使用Scala在Apache Spark中将矩阵转换为行矩阵

5

我很想将我的org.apache.spark.mllib.linalg.Matrix转换为org.apache.spark.mllib.linalg.distributed.RowMatrix。

我可以这样做:

val xx = X.computeGramianMatrix()  //xx is type org.apache.spark.mllib.linalg.Matrix
val xxs = xx.toString()
val xxr = xxs.split("\n").map(row => row.replace("   "," ").replace("  "," ").replace("  "," ").replace("  "," ").replace(" ",",").split(","))
val xxp = sc.parallelize(xxr)
val xxd = xxp.map(ar => Vectors.dense(ar.map(elm => elm.toDouble)))
val xxrm: RowMatrix = new RowMatrix(xxd)

然而,这真的很粗糙,也是一种完全的黑客行为。有人能展示给我更好的方法吗?

请注意,我正在使用Spark版本1.3.0。

2个回答

11

我建议您将Matrix转换为RDD [Vector],然后可以自动转换为RowMatrix

因此,让我们考虑以下示例:

import org.apache.spark.rdd._
import org.apache.spark.mllib.linalg._


val denseData = Seq(
  Vectors.dense(0.0, 1.0, 2.0),
  Vectors.dense(3.0, 4.0, 5.0),
  Vectors.dense(6.0, 7.0, 8.0),
  Vectors.dense(9.0, 0.0, 1.0)
)

val dm: Matrix = Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))
我们需要定义一种方法将该 Matrix 转换为一个 RDD[Vector]
def matrixToRDD(m: Matrix): RDD[Vector] = {
   val columns = m.toArray.grouped(m.numRows)
   val rows = columns.toSeq.transpose // Skip this if you want a column-major RDD.
   val vectors = rows.map(row => new DenseVector(row.toArray))
   sc.parallelize(vectors)
}

现在我们可以将该转换应用于主要的Matrix

 import org.apache.spark.mllib.linalg.distributed.RowMatrix
 val rows = matrixToRDD(dm)
 val mat = new RowMatrix(rows)

-1

以上代码需要进行小改正: 我们需要使用Vectors.dense而不是new DenseVector

val vectors = rows.map(row =>  Vectors.dense(row.toArray))

使用这个而不是 new DenseVector 有特定的原因吗? - dennlinger
我不确定这是关于什么的。这个有什么理由吗?你为什么需要那个? - eliasah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接