有一个矩阵,我想将其与向量执行点积。以下是 Scala 代码:
val matrix = sc.parallelize(List(
(("v1","v1"),2),(("v1","v2"),4),(("v1","v3"),1),(("v2","v2"),5),
(("v2","v3"),1),(("v3","v3"),2)))
val vector = sc.parallelize(List(("v1",4),("v2",1),("v3",5)))
val dotproduct = matrix.flatMap{x => {
vector.flatMap { y => {
if(x._1._2 == y._1) Tuple2(x._1._1, x._2 * y._2)
}}
}}.reduceByKey((_,_) => _+_)
但出现以下错误:
<console>:25: error: type mismatch;
found : (String, Int)
required: TraversableOnce[?]
val dotproduct = matrix.flatMap{ x => { vector.flatMap { y => { if(x._1._2 == y._1) (x._1._1, x._2 * y._2) }}}}.reduceByKey((_,_) => _+_)
^
不知道RDD中的嵌套操作是否可以。 Spark MLlib是否提供任何API来执行矩阵和向量之间的点积?
最佳答案
I don't know if the nesting operation in RDD is OK.
这不行。 Spark 不支持嵌套操作、转换或分布式数据结构。
Does Spark MLlib provide any API to perform the dot product between matrix and vector?
RowMatrix
提供接受局部矩阵的multiply
方法。它应该在你的情况下工作得很好。
import org.apache.spark.mllib.linalg.distributed.{CoordinateMatrix, MatrixEntry}
val idx = "^v([0-9]+)$".r
val rdd = sc.parallelize(List(
(("v1", "v1"), 2), (("v1", "v2"), 4),
(("v1", "v3"), 1), (("v2", "v2"), 5),
(("v2", "v3"), 1), (("v3", "v3"), 2)
))
val mat = new CoordinateMatrix(rdd.map { case ((idx(i), idx(j)), v) =>
MatrixEntry(i.toLong - 1, j.toLong - 1, v.toDouble)
}).toIndexedRowMatrix
val vector = Matrices.dense(3, 1, Array(4.0, 1.0, 5.0))
mat.multiply(vector).rows
如果向量太大而无法在内存中处理,则可以使用 block 矩阵。请参阅Matrix Multiplication in Apache Spark
关于您的代码,您可以执行以下操作:
matrix
.map{case ((i, j), v) => (j, (i, v))}
.join(vector)
.values
.map{case ((i, v1), v2) => (i, v1 * v2)}
.reduceByKey(_ + _)
或使用本地“向量”(可选广播):
val vector = Map(("v1" -> 4), ("v2" -> 1), ("v3" -> 5)).withDefault(_ => 0)
matrix.map{case ((i, j), v) => (i, v * vector(j))}.reduceByKey(_ + _)
关于matrix - 如何使用 Spark 的 RDD 与向量执行矩阵点积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34542656/