Spark分布式矩阵乘法和伪逆计算

Spark distributed matrix multiply and pseudo-inverse calculating

我是 Apache Spark Scala 的新手。你能帮我做一些手术吗?

我在 Spark Scala 中有两个分布式矩阵 H 和 Y。

我想计算 H 的伪逆,然后将 H 和 Y 相乘。

我该怎么做?

矩阵乘法是比较简单的:org.apache.spark.mllib.linalg和[=14包中有几个Matrix实现了multiply方法=].选择最适合您的需求。

我在 Spark API 的任何地方都没有看到 (伪)逆。但是 RowMatrix 能够计算 奇异值分解 ,可用于计算矩阵的逆。这是一个非常天真的实现,灵感来自 How can we compute Pseudoinverse for any Matrix(警告:2x2 矩阵的维度是硬编码的):

val m = new RowMatrix(sc.parallelize(Seq(Vectors.dense(4, 3), Vectors.dense(3, 2))))
val svd = m.computeSVD(2, true)
val v = svd.V
val sInvArray = svd.s.toArray.toList.map(x => 1.0 / x).toArray
val sInverse = new DenseMatrix(2, 2, Matrices.diag(Vectors.dense(sInvArray)).toArray)
val uArray = svd.U.rows.collect.toList.map(_.toArray.toList).flatten.toArray
val uTranspose = new DenseMatrix(2, 2, uArray) // already transposed because DenseMatrix is column-major
val inverse = v.multiply(sInverse).multiply(uTranspose)
  // -1.9999999999998297  2.999999999999767    
  // 2.9999999999997637   -3.9999999999996767    

不幸的是,需要进行大量从矩阵到数组的转换等等。如果您需要完全分布式的实现,请尝试使用 DistributedMatrix 而不是 DenseMatrix。如果没有,也许在这里使用 Breeze 更可取。

这里是逆向的实现。

import org.apache.spark.mllib.linalg.{Vectors,Vector,Matrix,SingularValueDecomposition,DenseMatrix,DenseVector}
import org.apache.spark.mllib.linalg.distributed.RowMatrix

def computeInverse(X: RowMatrix): DenseMatrix = {
  val nCoef = X.numCols.toInt
  val svd = X.computeSVD(nCoef, computeU = true)
  if (svd.s.size < nCoef) {
    sys.error(s"RowMatrix.computeInverse called on singular matrix.")
  }

  // Create the inv diagonal matrix from S 
  val invS = DenseMatrix.diag(new DenseVector(svd.s.toArray.map(x => math.pow(x,-1))))

  // U cannot be a RowMatrix
  val U = new DenseMatrix(svd.U.numRows().toInt,svd.U.numCols().toInt,svd.U.rows.collect.flatMap(x => x.toArray))

  // If you could make V distributed, then this may be better. However its alreadly local...so maybe this is fine.
  val V = svd.V
  // inv(X) = V*inv(S)*transpose(U)  --- the U is already transposed.
  (V.multiply(invS)).multiply(U)
  }

要计算非方矩阵的伪逆,您需要能够计算转置(简单)和矩阵逆(其他人已经提供了该功能)。有两种不同的计算,具体取决于 M 是否具有完整的列排名或完整的行排名。

满列秩是指矩阵的列是线性无关的,要求列数小于或等于行数。 (在病态情况下,m>=n 的 mxn 矩阵可能仍然没有完整的列秩,但我们将忽略统计上的不可能性。如果在您的情况下有可能,下面的矩阵求逆步骤将失败。)对于完整列秩,伪逆是

M^+ = (M^T M)^{-1} M^T

其中 M^TM 的转置。矩阵乘 M^T 乘以 M,然后取逆,然后矩阵再次乘以 M^T。 (我假设 M 有实数条目;如果条目是复数,你还必须采用复共轭。)

确保正确计算伪逆的快速检查是检查 M^+ M。它应该是单位矩阵(直到浮点误差)。

另一方面,如果 M 具有完整的行秩,换句话说 M 是 mxn,其中 m<=n,伪逆是

M^+ = M^T (M M^T)^{-1}

要检查在这种情况下是否有正确的伪逆,请与原始矩阵右乘:M M^+。那应该等于单位矩阵,直到浮点误差。