Moltiplicazione della matrice in Apache Spark

Sto cercando di eseguire la moltiplicazione della matrice usando Apache Spark e Java.

Ho 2 domande principali:

  1. Come creare RDD che può rappresentare la matrice in Apache Spark?
  2. Come moltiplicare due di questi RDD?

Tutto dipende dai dati di input e dalle dimensioni, ma in generale ciò che si desidera non è un RDD ma una delle strutture di dati distribuite da org.apache.spark.mllib.linalg.distributed . Al momento fornisce quattro diverse implementazioni di DistributedMatrix

  • IndexedRowMatrix – può essere creato direttamente da un RDD[IndexedRow] dove IndexedRow costituito da indice di riga e 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 – simile a IndexedRowMatrix ma senza indici di riga significativi. Può essere creato direttamente da RDD[org.apache.spark.mllib.linalg.Vector]

     import org.apache.spark.mllib.linalg.distributed.RowMatrix val rowMatrix = new RowMatrix(rows.map(_.vector)) 
  • BlockMatrix – può essere creato da RDD[((Int, Int), Matrix)] dove il primo elemento della tupla contiene le coordinate del blocco e il secondo è un org.apache.spark.mllib.linalg.Matrix locale

     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 – può essere creato da RDD[MatrixEntry] dove MatrixEntry consiste di riga, colonna e valore.

     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) 

Le prime due implementazioni supportano la moltiplicazione di una Matrix locale:

 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])) 

e il terzo può essere moltiplicato per un altro BlockMatrix fintanto che il numero di colonne per blocco in questa matrice corrisponde al numero di righe per blocco dell’altro matrici. CoordinateMatrix non supporta le moltiplicazioni ma è piuttosto facile da creare e trasformare in altri tipi di matrici distribuite:

 blockMatrix.multiply(coordinateMatrix.toBlockMatrix(3, 3)) 

Ogni tipo ha i suoi lati forti e deboli e ci sono alcuni fattori aggiuntivi da considerare quando si usano elementi sparsi o densi ( Vectors o blocchi di Matrices ). La moltiplicazione di una matrice locale è solitamente preferibile in quanto non richiede un mischiare costoso.

È ansible trovare ulteriori dettagli su ciascun tipo nella guida dei tipi di dati MLlib .