使用Pyspark从SVD组件重建矩阵

时间:2019-03-02 08:36:54

标签: apache-spark pyspark apache-spark-mllib svd

我正在使用pyspark开发SVD。但是在documentation以及其他任何地方,我都没有找到如何使用分段向量来重建矩阵的方法。例如,使用pyspark的svd,我得到了U,{{1 }}和s矩阵,如下所示。

V

现在,我想通过乘以原始矩阵来重建原始矩阵。等式是:

from pyspark.mllib.linalg import Vectors from pyspark.mllib.linalg.distributed import RowMatrix rows = sc.parallelize([ Vectors.sparse(5, {1: 1.0, 3: 7.0}), Vectors.dense(2.0, 0.0, 3.0, 4.0, 5.0), Vectors.dense(4.0, 0.0, 0.0, 6.0, 7.0) ]) mat = RowMatrix(rows) # Compute the top 5 singular values and corresponding singular vectors. svd = mat.computeSVD(5, computeU=True) U = svd.U # The U factor is a RowMatrix. s = svd.s # The singular values are stored in a local dense vector. V = svd.V # The V factor is a local dense matrix.

在python中,我们可以轻松地做到这一点。但是在pyspark中我没有得到结果。 我找到了this链接。但是它在scala中,我不知道如何在pyspark中进行转换。如果有人可以指导我,那将非常有帮助。

谢谢!

1 个答案:

答案 0 :(得分:1)

转换u to diagonal matrix Σ

import numpy as np
from pyspark.mllib.linalg import DenseMatrix

Σ = DenseMatrix(len(s), len(s), np.diag(s).ravel("F"))

转置Vconvert to column major,然后转换回DenseMatrix

V_ = DenseMatrix(V.numCols, V.numRows, V.toArray().transpose().ravel("F"))

Multiply

mat_ = U.multiply(Σ).multiply(V_) 

检查结果:

for row in mat_.rows.take(3): 
    print(row.round(12)) 
[0. 1. 0. 7. 0.]
[2. 0. 3. 4. 5.]
[4. 0. 0. 6. 7.]

选中the norm

np.linalg.norm(np.array(rows.collect()) - np.array(mat_.rows.collect())
1.2222842061189339e-14

当然,最后两个步骤仅用于测试,在现实生活中的数据上不可行。