是否可以在Spark中正确计算IndexedRowMatrix上的SVD?

时间:2015-06-26 11:18:25

标签: scala apache-spark

我有一个IndexedRowMatrix [m x n],它只包含X个非零行。我正在设置 k = 3。

当我尝试在computeU设置为true的情况下计算此对象的SVD时, U 矩阵的尺寸为[m x n],当正确尺寸为[m x k]时。

为什么会这样?

我已尝试将IndexedRowMatrix转换为RowMatrix,然后计算SVD。结果维度为[X x k],因此它只计算非零行的结果(矩阵正在丢弃索引,如文档中所示)。

是否可以转换此矩阵,但保留行索引?

    val csv = sc.textFile("hdfs://spark/nlp/merged_sparse.csv").cache()  // original file

    val data = csv.mapPartitions(lines => {
        val parser = new CSVParser(' ')
        lines.map(line => {
          parser.parseLine(line)
        })
      }).map(line => {
        MatrixEntry(line(0).toLong - 1, line(1).toLong - 1 , line(2).toInt) 
      }
    )

    val coordinateMatrix: CoordinateMatrix = new CoordinateMatrix(data)
    val indexedRowMatrix: IndexedRowMatrix = coordinateMatrix.toIndexedRowMatrix()
    val rowMatrix: RowMatrix = indexedRowMatrix.toRowMatrix()


    val svd: SingularValueDecomposition[RowMatrix, Matrix] = rowMatrix.computeSVD(3, computeU = true, 1e-9)

    val U: RowMatrix = svd.U // The U factor is a RowMatrix.
    val S: Vector = svd.s // The singular values are stored in a local dense vector.
    val V: Matrix = svd.V // The V factor is a local dense matrix.

    val indexedSvd: SingularValueDecomposition[IndexedRowMatrix, Matrix] = indexedRowMatrix.computeSVD(3, computeU = true, 1e-9)

    val indexedU: IndexedRowMatrix = indexedSvd.U // The U factor is a RowMatrix.
    val indexedS: Vector = indexedSvd.s // The singular values are stored in a local dense vector.
    val indexedV: Matrix = indexedSvd.V // The V factor is a local dense matrix.

1 个答案:

答案 0 :(得分:1)

看起来这是Spark MLlib中的一个错误。如果您在索引矩阵中获得行向量的大小,它将正确返回3列:

indexedU.rows.first().vector.size

我查看了源代码,看起来他们错误地从indexed matrix复制了当前列数:

val U = if (computeU) {
  val indexedRows = indices.zip(svd.U.rows).map { case (i, v) =>
    IndexedRow(i, v)
  }
  new IndexedRowMatrix(indexedRows, nRows, nCols) //nCols is incorrect here
} else {
  null
}

看起来像是错误修正/拉取请求的主要候选人。