ошибка памяти при вычислении инверсии большой матрицы в искре - PullRequest
0 голосов
/ 05 мая 2018

Я пытаюсь вычислить инверсию 25 ГБ матрицы в искре, я работаю в локальном режиме с машиной 6 ГБ в памяти. Я нашел этот код: https://stackoverflow.com/users/1290485/climbs-lika-spyder Его работа основана на вычислении SVD.

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) }

Моя проблема в том, что когда я пытался вычислить SVD матрицы строк, эта ошибка выскакивала, даже когда я увеличивал размер кучи.

scala> computeInverse(result)
18/05/04 23:50:18 WARN RowMatrix: computing svd with k=36704 and  n=36704, please check necessity
18/05/04 23:50:18 WARN RowMatrix: The input data is not directly cached, which may hurt performance if its parent RDDs are also uncached.
java.lang.IllegalArgumentException: requirement failed: k must be smaller than n in dist-eigs mode but got k=36704 and n=36704.
at scala.Predef$.require(Predef.scala:224)
at org.apache.spark.mllib.linalg.distributed.RowMatrix.computeSVD(RowMatrix.scala:267)
at org.apache.spark.mllib.linalg.distributed.RowMatrix.computeSVD(RowMatrix.scala:194)
at computeInverse(<console>:34)
... 50 elided

поэтому я уменьшил K до 20000, однако снова возникла ошибка, указывающая на проблему размера кучи

 scala> val svd = result.computeSVD(20000, computeU = true)
18/05/06 13:18:08 WARN RowMatrix: computing svd with k=20000 and n=36704, please check necessity
18/05/06 13:18:08 WARN RowMatrix: The input data is not directly cached, which may hurt performance if its parent RDDs are also uncached.
18/05/06 13:18:08 WARN ARPACK: Failed to load implementation from: com.github.fommil.netlib.NativeSystemARPACK
18/05/06 13:18:08 WARN ARPACK: Failed to load implementation from: com.github.fommil.netlib.NativeRefARPACK
java.lang.OutOfMemoryError: Java heap space
at org.apache.spark.mllib.linalg.EigenValueDecomposition$.symmetricEigs(EigenValueDecomposition.scala:84)
at org.apache.spark.mllib.linalg.distributed.RowMatrix.computeSVD(RowMatrix.scala:268)
at org.apache.spark.mllib.linalg.distributed.RowMatrix.computeSVD(RowMatrix.scala:194)
... 29 elided

У кого-нибудь есть идея или альтернативное решение? и могу ли я дать какое-то объяснение, как спарк выделяет оборудование для выполнения такой операции

...