这是反向的实现。
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) }
的 矩阵乘法 强> 更容易:有几个 Matrix 用a实现 multiply 包中的方法 org.apache.spark.mllib.linalg 和 org.apache.spark.mllib.linalg.distributed 。挑选最符合您需求的产品。
Matrix
multiply
org.apache.spark.mllib.linalg
org.apache.spark.mllib.linalg.distributed
我没见过 的 (伪)逆 强> Spark API中的任何位置。但 RowMatrix 能够计算出来 奇异值分解 它可以用来计算矩阵的逆。这是一个非常天真的实现,受到启发 我们如何计算任何矩阵的伪逆 (警告:2x2矩阵的尺寸是硬编码的):
RowMatrix
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
不幸的是,从Matrix到Array等的大量转换是必要的。如果您需要完全分布式实现,请尝试使用 DistributedMatrix 代替 DenseMatrix 。如果没有,可以在这里使用Breeze。
DistributedMatrix
DenseMatrix
要计算非平方矩阵的伪逆,您需要能够计算转置(简单)和矩阵逆(其他已提供该功能)。根据是否,有两种不同的计算方法 M 具有完整的列级别或完整的行级别。
M
全列等级意味着矩阵的列是线性独立的,这要求列数小于或等于行数。 (在病态情况下,m> = n的mxn矩阵可能仍然没有完整的列级别,但我们将忽略统计不可能性。如果在您的情况下有可能,下面的矩阵求逆步骤将失败。)完整列等级,伪逆是
M^+ = (M^T M)^{-1} M^T
哪里 M^T 是的转置 M 。矩阵乘法 M^T 通过 M ,然后取逆,然后矩阵乘以 M^T 再次。 (我假设 M 有实数的条目;如果条目是复数,则还必须采用复数共轭。)
M^T
快速检查以确保您正确计算了psuedo-inverse是检查 M^+ M 。它应该是单位矩阵(最多浮点错误)。
M^+ M
另一方面,如果 M 换句话说,有完整的排名 M mx是m <= n,伪逆是
M^+ = M^T (M M^T)^{-1}
要检查在这种情况下是否有正确的伪逆,请与原始矩阵正确相乘: M M^+ 。这应该等于单位矩阵,直到浮点错误。
M M^+