web-dev-qa-db-ja.com

Apacheでの行列乗算Spark

Apache SparkおよびJavaを使用して行列乗算を実行しようとしています。

私は2つの主な質問があります:

  1. Apache Sparkでマトリックスを表すことができるRDDを作成する方法は?
  2. このような2つのRDDを乗算する方法は?
19
Jigar

すべては入力データとディメンションに依存しますが、一般的に言えば、必要なのはRDDではなく、 _org.Apache.spark.mllib.linalg.distributed_ からの分散データ構造の1つです。この時点で、それは DistributedMatrix の4つの異なる実装を提供します

  • IndexedRowMatrix -_RDD[IndexedRow]_から直接作成できます IndexedRow 行インデックスと_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 -IndexedRowMatrixに似ていますが、意味のある行インデックスはありません。 _RDD[org.Apache.spark.mllib.linalg.Vector]_から直接作成できます

    _import org.Apache.spark.mllib.linalg.distributed.RowMatrix
    
    val rowMatrix = new RowMatrix(rows.map(_.vector))      
    _
  • BlockMatrix -RDD[((Int, Int), Matrix)]から作成できます。タプルの最初の要素にはブロックの座標が含まれ、2番目の要素はローカル_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 -_RDD[MatrixEntry]_から作成できます MatrixEntry 行、列、値で構成されます。

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

最初の2つの実装は、ローカル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]))
_

そして、この行列のブロックごとの列の数が他の行列のブロックごとの行の数と一致する限り、3番目のものは別のBlockMatrixで乗算できます。 CoordinateMatrixは乗算をサポートしていませんが、作成して他のタイプの分散行列に変換するのは非常に簡単です。

_blockMatrix.multiply(coordinateMatrix.toBlockMatrix(3, 3))
_

各タイプには独自の強みと弱みがあり、疎要素または密要素(VectorsまたはブロックMatrices)を使用する場合に考慮すべきいくつかの追加の要素があります。高価なシャッフルを必要としないため、通常はローカルマトリックスを乗算することをお勧めします。

各タイプの詳細については MLlibデータタイプガイド を参照してください。

42
zero323