乘以2个稀疏矩阵

时间:2017-10-24 03:31:58

标签: scala apache-spark sparse-matrix rdd matrix-multiplication

我想将两个源自文本文件的稀疏矩阵相乘。我目前有这个代码:

import org.apache.spark.SparkContext
import org.apache.spark.SparkConf


@SerialVersionUID(123L)
case class M_Matrix ( i: Long, j: Long, v: Double )
extends Serializable {}

@SerialVersionUID(123L)
case class N_Matrix ( j: Long, k: Long, w: Double )
extends Serializable {}

object Multiply {
def main(args: Array[ String ]){
val conf = new SparkConf().setAppName("Multiply")
val sc = new SparkContext(conf)

val M_ = sc.textFile(args(0)).map( line => { val a = line.split(",")
  M_Matrix(a(0).toLong,a(1).toLong,a(2).toDouble) } )

val N_ = sc.textFile(args(1)).map( line => { val a = line.split(",")
  N_Matrix(a(0).toLong, a(1).toLong, a(2).toDouble) } )
val res = M_.map( M_ => (M_.j,M_) )
  .join(N_.map( N_ => (N_.j, N_)))
  .map({case (j, ((i,v),(k,w))) => ((i,k), v * w)})
  .reduceByKey(_ + _)
  .map({ case ((i,k), sum) => (i, k, sum)} )
res.saveAsTextFile(args(2))
sc.stop()
}
}

它给了我一个错误* *在v * w中不是有效的运算符。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

代码几乎是正确的,需要进行一些小的更改才能使其正常工作。具体而言,在map操作之前的矩阵join中完成:

M_.map( M_ => (M_.j, (M_.i, M_.v))).join(N_.map(N_ => (N_.j, (N_.k, N_.w))))

元组应该在这里用作值,因为在下一个语句中元组是预期的,

.map{ case(j, ((i,v),(k,w))) => ((i,k), v * w)}

我建议尝试使用Spark中的内置功能,因为它应该更高效。可以从RDD[MatrixEntry]创建矩阵。首先创建两个矩阵:

import org.apache.spark.mllib.linalg.distributed.{BlockMatrix, CoordinateMatrix, MatrixEntry}

val M_ = sc.textFile(args(0)).map{ line => 
  val a = line.split(",")
  MatrixEntry(a(0).toLong, a(1).toLong, a(2).toDouble)
}

val N_ = sc.textFile(args(1)).map{ line => 
  val a = line.split(",")
  MatrixEntry(a(0).toLong, a(1).toLong, a(2).toDouble)
}

然后将它们转换为BlockMatrix

val matrix_M = new CoordinateMatrix(M_).toBlockMatrix()
val matrix_N = new CoordinateMatrix(N_).toBlockMatrix()

之后,您可以使用函数multiply简单地将它们相乘:

val res = matrix_M.multiply(matrix_N)