Próbuję wykonać mnożenie macierzy za pomocą Apache Spark i Java.Mnożenie macierzy w Apache Spark
Mam 2 główne pytania:
- Jak stworzyć RDD, które mogą reprezentować matrycy w Apache Spark?
- Jak pomnożyć dwa takie RDD?
Próbuję wykonać mnożenie macierzy za pomocą Apache Spark i Java.Mnożenie macierzy w Apache Spark
Mam 2 główne pytania:
Wszystko zależy od danych wejściowych i wymiarach, ale ogólnie rzecz biorąc to, co chcesz nie jest RDD
ale jednym z rozproszonych struktur danych z org.apache.spark.mllib.linalg.distributed
. W tym momencie dostarcza cztery różne implementacje DistributedMatrix
IndexedRowMatrix
- może być utworzony bezpośrednio w RDD[IndexedRow]
gdzie IndexedRow
składa się z indeksem wiersza a org.apache.spark.mllib.linalg.Vector
import org.apache.spark.mllib.linalg.{Vectors, Matrices}
import org.apache.spark.mllib.linalg.distributed.{IndexedRowMatrix,
IndexedRow}
val rows = sc.parallelize(Seq(
(0L, Array(1.0, 0.0, 0.0)),
(0L, Array(0.0, 1.0, 0.0)),
(0L, Array(0.0, 0.0, 1.0)))
).map{case (i, xs) => IndexedRow(i, Vectors.dense(xs))}
val indexedRowMatrix = new IndexedRowMatrix(rows)
RowMatrix
- podobnie IndexedRowMatrix
bez znaczące indeksy wierszy. Mogą być tworzone bezpośrednio z RDD[org.apache.spark.mllib.linalg.Vector]
import org.apache.spark.mllib.linalg.distributed.RowMatrix
val rowMatrix = new RowMatrix(rows.map(_.vector))
BlockMatrix
- mogą być tworzone z RDD[((Int, Int), Matrix)]
gdzie pierwszym elementem krotki zawierający współrzędne bloku, a drugi jest lokalnym org.apache.spark.mllib.linalg.Matrix
val eye = Matrices.sparse(
3, 3, Array(0, 1, 2, 3), Array(0, 1, 2), Array(1, 1, 1))
val blocks = sc.parallelize(Seq(
((0, 0), eye), ((1, 1), eye), ((2, 2), eye)))
val blockMatrix = new BlockMatrix(blocks, 3, 3, 9, 9)
CoordinateMatrix
- można utworzyć z RDD[MatrixEntry]
, gdzie MatrixEntry
składa się z wiersza, kolumny i wartości.
import org.apache.spark.mllib.linalg.distributed.{CoordinateMatrix,
MatrixEntry}
val entries = sc.parallelize(Seq(
(0, 0, 3.0), (2, 0, -5.0), (3, 2, 1.0),
(4, 1, 6.0), (6, 2, 2.0), (8, 1, 4.0))
).map{case (i, j, v) => MatrixEntry(i, j, v)}
val coordinateMatrix = new CoordinateMatrix(entries, 9, 3)
Pierwsze dwie implementacje wspierać mnożenie przez miejscowego Matrix
:
val localMatrix = Matrices.dense(3, 2, Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))
indexedRowMatrix.multiply(localMatrix).rows.collect
// Array(IndexedRow(0,[1.0,4.0]), IndexedRow(0,[2.0,5.0]),
// IndexedRow(0,[3.0,6.0]))
a trzeci może być pomnożona przez innego BlockMatrix
tak długo, jak liczba kolumn na blok w tym meczów macierzy liczba wierszy na blok innej macierzy. CoordinateMatrix
nie obsługuje mnożenia, ale jest dość łatwo tworzyć i przekształcać się w inne rodzaje matryc rozproszonych:
blockMatrix.multiply(coordinateMatrix.toBlockMatrix(3, 3))
Każdy typ ma swoje mocne i słabe strony i istnieje kilka dodatkowych czynników do rozważenia podczas korzystania skąpe lub gęste elementy (Vectors
lub blok Matrices
). Mnożenie przez lokalną matrycę jest zwykle lepsze, ponieważ nie wymaga kosztownego tasowania.
Więcej szczegółowych informacji o każdym typie można uzyskać pod numerem the MLlib Data Types guide.
To jest świetne podsumowanie tego, jak utworzyć różne typy macierzy - myślę, że zamierzam to dodać do zakładek! –