Matrix 火花分布矩阵乘法与伪逆计算

Matrix 火花分布矩阵乘法与伪逆计算,matrix,apache-spark,distributed-computing,Matrix,Apache Spark,Distributed Computing,我是Apache Spark Scala的新手。你能帮我做些手术吗 在Spark Scala中有两个分布矩阵H和Y 我想计算H的伪逆,然后乘以H和Y 我该怎么做 矩阵乘法是比较容易的一种:在包org.apache.spark.mllib.linalg和org.apache.spark.mllib.linalg.distributed中有几个Matrix实现方法。挑选最适合你需要的东西 我在Spark API中的任何地方都没有看到(伪)反转。但是RowMatrix能够计算奇异值分解,该分解可用于计

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

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

我想计算H的伪逆,然后乘以H和Y


我该怎么做

矩阵乘法是比较容易的一种:在包
org.apache.spark.mllib.linalg
org.apache.spark.mllib.linalg.distributed
中有几个
Matrix
实现方法。挑选最适合你需要的东西

我在Spark API中的任何地方都没有看到(伪)反转。但是
RowMatrix
能够计算奇异值分解,该分解可用于计算矩阵的逆。这是一个非常简单的实现,灵感来自(警告:2x2矩阵的维度是硬编码的):

val m=新的行矩阵(sc.parallelize(Seq(Vectors.dense(4,3),Vectors.dense(3,2)))
val svd=m.computeSVD(2,真)
val v=svd.v
val sInvArray=svd.s.toArray.toList.map(x=>1.0/x).toArray
val sInverse=新密度矩阵(2,2,矩阵.diag(向量.密集(sInvArray)).toArray)
val uArray=svd.U.rows.collect.toList.map(U.toArray.toList).flatte.toArray
val uTranspose=new DenseMatrix(2,2,uArray)//已经转置,因为DenseMatrix是主列
val逆=v.乘(正反)。乘(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)
  }
import org.apache.spark.mllib.linalg.{向量,向量,矩阵,奇异值分解,DenseMatrix,DenseVector}
导入org.apache.spark.mllib.linalg.distributed.RowMatrix
def计算反转(X:RowMatrix):密度矩阵={
val nCoef=X.numCols.toInt
val svd=X.computeSVD(nCoef,computeU=true)
if(svd.s.尺寸math.pow(x,-1)))
//U不能是行矩阵
val U=新密度矩阵(svd.U.numRows().toInt,svd.U.numCols().toInt,svd.U.rows.collect.flatMap(x=>x.toArray))
//如果你能使V分布,那么这可能会更好。但是它已经是本地的了…所以也许这是好的。
val V=svd.V
//inv(X)=V*inv(S)*转置(U)--U已被转置。
(V)乘(invS)乘(U)
}

要计算非方矩阵的伪逆,您需要能够计算转置(简单)和矩阵逆(其他人提供了该功能)。根据
M
是否具有全列秩或全行秩,有两种不同的计算

全列秩表示矩阵的列是线性独立的,这要求列数小于或等于行数。(在病理病例中,m>=n的mxn矩阵可能仍然没有满列秩,但我们将忽略统计上的不可能性。如果在您的病例中存在这种可能性,下面的矩阵求逆步骤将失败。)对于满列秩,伪逆是

M^+ = (M^T M)^{-1} M^T
M^+ = M^T (M M^T)^{-1}
其中
M^T
M
的转置。矩阵相乘
M^T
乘以
M
,然后求逆,然后再次矩阵相乘
M^T
。(我假设
m
有实数条目;如果条目是复数,则还必须采用复数共轭。)

要快速检查以确保已正确计算psuedo逆,请检查
M^+M
。它应该是单位矩阵(最多为浮点错误)


另一方面,如果
M
具有全行秩,换句话说
M
是mxn,非常感谢。我熟悉了矩阵乘法。它起作用了。你的代码帮我找到平方矩阵的psevdo逆。你们能建议这对非方矩阵应该如何工作吗?我还有一个关于沿矩阵行的最大值指数的问题。我能用Spark Scala做这个吗?对不起,我自己对这个话题还不够熟悉。我认为我的答案是一个概念的证明,它将引导你走向正确的方向,但现在我建议你使用像Breeze这样的专业库。-你的另一个问题应该是有更多细节的额外帖子。我尝试过这个,我得到了一个乘法的结果,但对于逆运算,我没有任何想法。