我正在尝试使用Apache Spark和Java进行矩阵乘法。
我的两个主要问题是:
- 如何创建能够在Apache Spark中表示矩阵的RDD?
- 如何对这样的两个RDD进行乘法运算?
我正在尝试使用Apache Spark和Java进行矩阵乘法。
我的两个主要问题是:
一切取决于输入数据和维度,但总的来说,您需要的不是 RDD
,而是来自 org.apache.spark.mllib.linalg.distributed
的分布式数据结构之一。目前,它提供了四种不同的实现方式,即 DistributedMatrix
。
IndexedRowMatrix
- can be created directly from a RDD[IndexedRow]
where IndexedRow
consist of row index and 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
- similar to IndexedRowMatrix
but without meaningful row indices. Can be created directly from RDD[org.apache.spark.mllib.linalg.Vector]
import org.apache.spark.mllib.linalg.distributed.RowMatrix
val rowMatrix = new RowMatrix(rows.map(_.vector))
BlockMatrix
- can be created from RDD[((Int, Int), Matrix)]
where first element of the tuple contains coordinates of the block and the second one is a local 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
- can be created from RDD[MatrixEntry]
where MatrixEntry
consist of row, column and value.
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)
前两个实现支持使用本地矩阵
进行乘法:
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]))
第三个矩阵可以与另一个BlockMatrix
相乘,前提是该矩阵每个块的列数与另一个矩阵每个块的行数相匹配。虽然CoordinateMatrix
不支持乘法,但很容易创建并转换为其他类型的分布式矩阵:
blockMatrix.multiply(coordinateMatrix.toBlockMatrix(3, 3))
Vectors
或块Matrices
)时,还需考虑一些额外因素。通常情况下,通过本地矩阵进行乘法计算更为可取,因为它不需要昂贵的洗牌操作。
BlockMatrix
参数有什么用?我看到乘法可以带一个整数参数?我正在尝试计算250k x 30k X 30k x 30k的乘积,但遇到了麻烦。 - Dan Ciborowski - MSFT