J'ai une matrice X, distribuée, dans la forme RowMatrix. J'utilise Spark 1.3.0. Je dois être capable de calculer x inverse. p>
3 Réponses :
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) }
J'ai eu des problèmes à l'aide de cette fonction avec l'option Les rangées de Rowmatrix ont été mélangées. P> Voici une mise à jour qui a fonctionné pour moi p> 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)
}
matrice u retourné par Je dirais que les deux solutions ci-dessous souffrent de cette faille. La réponse donnée par @ x.computesvd code> a des dimensions mxk où m em> est le nombre de lignes de l'orthographe d'origine (distribué) RowMatrix X. On pourrait attendre m em> être grand (éventuellement plus grand que k em>), il n'est donc pas conseillé de le recueillir dans le pilote si nous voulons que notre code augmente de très grandes valeurs de m em>. p>
alexander kharlamov code> appels
val u = svd.u.toblockmatrix (). Tolocalmatrix () code> qui recueille la matrice du pilote. Il en va de même avec la réponse donnée par @
climbs_lika_spyder code> (BTW Vos Nick Rocks !!), qui appelle
svd.u.rows.collect.flatmap (x => x.totarray) code>. Je préférerais suggérer de s'appuyer sur une multiplication de matrice distribuée telle que le code Scala posté ici . p>
Je ne vois aucun calcul inverse sur le lien que vous avez ajouté.
@Climbs_lika_spyder Le lien est à propos de la multiplication de matrice distribuée pour remplacer la multiplication de matrice locale (v.multiphe (INVS)). Multipliez (u) code> dans la dernière ligne de votre solution, de sorte que vous n'avez pas besoin de Recueillir
u code> dans le pilote. Je pense que
v code> et
invas code> ne sont pas assez gros pour causer des problèmes.
Un algorithme est décrit dans arxiv.org/pdf/1801.04723.pdf