복붙노트

[SCALA] 어떻게 아파치 스파크에서 RowMatrix의 역을 계산하기?

SCALA

어떻게 아파치 스파크에서 RowMatrix의 역을 계산하기?

나는 RowMatrix 형태의 X, 분산 행렬을 보유하고 있습니다. 나는 스파크 1.3.0를 사용하고 있습니다. 나는 X의 역을 계산 할 수 있어야합니다.

해결법

  1. ==============================

    1.

    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)
      }
    
  2. ==============================

    2.나는 옵션에이 기능을 사용하여 문제가 있었다

    나는 옵션에이 기능을 사용하여 문제가 있었다

    conf.set("spark.sql.shuffle.partitions", "12")
    

    RowMatrix의 행이 단행되었다.

    여기에 나를 위해 일한 업데이 트입니다

    import org.apache.spark.mllib.linalg.{DenseMatrix,DenseVector}
    import org.apache.spark.mllib.linalg.distributed.IndexedRowMatrix
    
    def computeInverse(X: IndexedRowMatrix)
    : DenseMatrix = 
    {
      val nCoef = X.numCols.toInt
      val svd = X.computeSVD(nCoef, computeU = true)
      if (svd.s.size < nCoef) {
        sys.error(s"IndexedRowMatrix.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 = svd.U.toBlockMatrix().toLocalMatrix().multiply(DenseMatrix.eye(svd.U.numRows().toInt)).transpose
    
      val V = svd.V
      (V.multiply(invS)).multiply(U)
    }
    
  3. ==============================

    3.행렬 U는 X.computeSVD는 그것을 수집 권장되지 않도록 치수, m은 m은 (K보다 가능성이 큰) 큰 것으로 기대 일본어 (분산) RowMatrix X. 하나의 행의 수이다 mxk 갖는다 의해 반환 드라이버 우리는 m의 정말 큰 값으로 규모 우리의 코드를 원하는 경우.

    행렬 U는 X.computeSVD는 그것을 수집 권장되지 않도록 치수, m은 m은 (K보다 가능성이 큰) 큰 것으로 기대 일본어 (분산) RowMatrix X. 하나의 행의 수이다 mxk 갖는다 의해 반환 드라이버 우리는 m의 정말 큰 값으로 규모 우리의 코드를 원하는 경우.

    나는 솔루션을 모두 아래이 결함으로 고통 말할 것입니다. @Alexander 카를라 모프 의해 주어진 대답 브로 svd.U.toBlockMatrix U = () 호출한다. toLocalMatrix ()을 드라이버의 매트릭스를 수집한다. 동일은 svd.U.rows.collect.flatMap (X => x.toArray)를 호출 @Climbs_lika_Spyder (BTW 당신의 별명은 바위!)에 의해 주어진 대답으로 발생합니다. 차라리 스칼라 코드가 여기에 게시와 같은 분산 행렬 곱셈에 의존하는 것이 좋습니다 것입니다.

  4. from https://stackoverflow.com/questions/29969521/how-to-compute-the-inverse-of-a-rowmatrix-in-apache-spark by cc-by-sa and MIT license