web-dev-qa-db-fra.com

Obtenez la matrice U, Sigma, V * de SVD tronqué dans scikit-learn

J'utilise SVD tronqué à partir du package scikit-learn.

Dans la définition de la SVD, une matrice originale A est approximativement un produit AUΣV *U et V ont des colonnes orthonormales et Σ est une diagonale non négative.

Je dois obtenir les matrices U, et V *

En regardant le code source ici / j'ai découvert que V * est stocké dans le champ self.components_ après avoir appelé fit_transform.

Est-il possible d’obtenir les matrices U _ et ?

Mon code: 

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_
19
Vektor88

Si vous examinez la source via le lien que vous avez fourni, TruncatedSVD est essentiellement une enveloppe autour de sklearn.utils.extmath.randomized_svd; vous pouvez appeler ceci vous-même manuellement comme ceci:

from sklearn.utils.extmath import randomized_svd

U, Sigma, VT = randomized_svd(X, 
                              n_components=15,
                              n_iter=5,
                              random_state=None)
33
maxymoo

On peut utiliser scipy.sparse.svds (pour les matrices denses, vous pouvez utiliser 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

Si vous travaillez avec de très grosses matrices éparses (peut-être votre travail avec du texte naturel), même scipy.sparse.svds pourrait faire exploser la RAM de votre ordinateur. Dans ce cas, considérez le paquet sparsesvd qui utilise SVDLIBC , et ce que gensim utilise sous le capot .

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
9
Vektor88

Juste comme une note:

svd.transform(X)

et

svd.fit_transform(X)

générer U * Sigma .

svd.singular_values_

génère Sigma en forme vectorielle.

svd.components_

génèreVT. Peut-être pouvons-nous utiliser

svd.transform(X).dot(np.linalg.inv(np.diag(svd.singular_values_)))

obtenirUparce que U * Sigma * Sigma ^ -1 = U * I = U .

0
Yin