在scikit-learn中从截断的SVD获取U,Sigma,V*矩阵

Vek*_*r88 23 python scipy sparse-matrix svd scikit-learn

我在scikit-learn 封装中使用截断的SVD .

在SVD的定义中,原始矩阵被approxmated作为产品UΣV*其中ùV具有正交列,并且Σ是非负对角线.

我需要得到U,ΣV*矩阵.

看一下这里的源代码,我发现调用后V*存储在self.components_字段中fit_transform.

是否有可能得到U  和Σ矩阵?

我的代码:

import sklearn.decomposition as skd
import numpy as np

matrix = np.random.random((20,20))
trsvd = skd.TruncatedSVD(n_components=15)
transformed = trsvd.fit_transform(matrix)
VT = trsvd.components_
Run Code Online (Sandbox Code Playgroud)

max*_*moo 37

通过您提供的链接查看源代码,TruncatedSVD基本上是sklearn.utils.extmath.randomized_svd的包装器; 您可以像这样自己手动调用:

from sklearn.utils.extmath import randomized_svd

U, Sigma, VT = randomized_svd(X, 
                              n_components=15,
                              n_iter=5,
                              random_state=None)
Run Code Online (Sandbox Code Playgroud)


Vek*_*r88 10

可以使用scipy.sparse.svds(对于密集矩阵,您可以使用svd).

import numpy as np
from scipy.sparse.linalg import svds

matrix = np.random.random((20, 20))
num_components = 2
u, s, v = svds(matrix, k=num_components)
X = u.dot(np.diag(s))  # output of TruncatedSVD
Run Code Online (Sandbox Code Playgroud)

如果你正在使用非常大的稀疏矩阵(也许你使用自然文本),甚至scipy.sparse.svds可能会炸毁计算机的RAM.在这种情况下,请考虑使用SVDLIBCsparsesvd包,以及使用引擎盖下的内容.gensim

import numpy as np
from sparsesvd import sparsesvd


X = np.random.random((30, 30))
ut, s, vt = sparsesvd(X.tocsc(), k)
projected = (X * ut.T)/s
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的,但对于常规的numpy.linalg.svd方法,您无法将组件数作为参数传递,因此您必须自己提取顶部K. 轻微的不便. (2认同)

Cos*_*syn 8

从源代码中,我们可以看到该方法返回的X_transformedU * Sigma(这里是一个向量) 。所以我们可以得到Sigmafit_transform

\n\n
svd = TruncatedSVD(k)\nX_transformed = svd.fit_transform(X)\n\nU = X_transformed / svd.singular_values_\nSigma_matrix = np.diag(svd.singular_values_)\nVT = svd.components_\n
Run Code Online (Sandbox Code Playgroud)\n\n

评论

\n\n

截断 SVD 是一种近似值。X \xe2\x89\x88 X' = U\xce\xa3V*。我们有 X'V = U\xce\xa3。但是XV呢?一个有趣的事实是 XV = X'V。这可以通过比较 X 的完整 SVD 形式和 X' 的截断 SVD 形式来证明。Note XV 只是transform(X),所以我们也可以U通过

\n\n
U = svd.transform(X) / svd.singular_values_\n
Run Code Online (Sandbox Code Playgroud)\n


小智 6

就像一个注释:

svd.transform(X)
Run Code Online (Sandbox Code Playgroud)

svd.fit_transform(X)
Run Code Online (Sandbox Code Playgroud)

生成U * Sigma

svd.singular_values_
Run Code Online (Sandbox Code Playgroud)

以向量形式生成Sigma

svd.components_
Run Code Online (Sandbox Code Playgroud)

产生VT。也许我们可以使用

svd.transform(X).dot(np.linalg.inv(np.diag(svd.singular_values_)))
Run Code Online (Sandbox Code Playgroud)

得到U因为U * Sigma * Sigma ^ -1 = U * I = U