J'utilise SVD tronqué à partir du package scikit-learn
.
Dans la définition de la SVD, une matrice originale A est approximativement un produit A ≈ UΣV * où 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_
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)
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
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 .