Matrix 如何使用Spark';s RDD

Matrix 如何使用Spark';s RDD,matrix,vector,apache-spark,Matrix,Vector,Apache Spark,有一个矩阵,我想用一个向量做它的点积。以下是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 = m

有一个矩阵,我想用一个向量做它的点积。以下是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((_,_) => _+_)
                                                                                         ^
:25:错误:类型不匹配;
找到:(字符串,Int)
必需:可遍历一次[?]
val dotproduct=matrix.flatMap{x=>{vector.flatMap{y=>{if(x._1._2==y._1)(x._1._1._1,x._2*y._2)}}}。reduceByKey((_,_)=>_+})
^
我不知道RDD中的嵌套操作是否正常。Spark MLlib是否提供任何API来执行矩阵和向量之间的点积?

假设点积只是指普通的矩阵向量乘法,您可以使用
MLlib.linalg
包中的
乘法方法

val mlMat=Matrices.dense(3,2,matrix.collect().map(_._2.toDouble)).transpose
val mlVect=Vectors.dense(vector.collect().map(_._2.toDouble))
mlMat.multiply(mlVect)
//org.apache.spark.mllib.linalg.DenseVector = [17.0,31.0]
我不知道RDD中的嵌套操作是否正常

这不好。Spark不支持嵌套操作、转换或分布式数据结构

Spark MLlib是否提供任何API来执行矩阵和向量之间的点积

行矩阵
提供接受局部矩阵的
乘法
方法。对你来说应该没问题

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
若要在内存中处理的向量太大,可以使用块矩阵。看

例如,关于您的代码,您可以执行以下操作:

matrix
  .map{case ((i, j), v) => (j, (i, v))}
  .join(vector)
  .values
  .map{case ((i, v1), v2) => (i, v1 * v2)}
  .reduceByKey(_ + _)
或使用本地“矢量”(可选广播):


矩阵是对称的,所以我只使用了对角线上方的元素。谢谢你的澄清,zero323!
val vector = Map(("v1" -> 4), ("v2" -> 1), ("v3" -> 5)).withDefault(_ => 0)

matrix.map{case ((i, j), v) => (i, v * vector(j))}.reduceByKey(_ + _)