Получите матрицу U, Sigma, V * из усеченного SVD в scikit-learn
Я использую усеченный SVD из scikit-learn
.
В определении SVD исходная матрица A аппроксимируется как произведение A ≈ UΣV *, где U и 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_
Ответы
Ответ 1
Заглядывая в источник по предоставленной вами ссылке, 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)
Ответ 2
Можно использовать 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
Если вы работаете с очень большими разреженными матрицами (возможно, вы работаете с естественным текстом), даже scipy.sparse.svds
может взорвать ОЗУ вашего компьютера. В таких случаях рассмотрите пакет sparsesvd, который использует SVDLIBC, и то, что 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
Ответ 3
Просто как примечание:
svd.transform(X)
а также
svd.fit_transform(X)
генерировать U * Sigma.
svd.singular_values_
генерирует сигму в векторной форме.
svd.components_
генерирует VT. Может быть, мы можем использовать
svd.transform(X).dot(np.linalg.inv(np.diag(svd.singular_values_)))
чтобы получить U, потому что U * Сигма * Сигма ^ -1 = U * я = U.
Ответ 4
Из исходного кода мы видим, что X_transformed
который является U * Sigma
(здесь Sigma
- вектор), возвращается из метода fit_transform
. Таким образом, мы можем получить
svd = TruncatedSVD(k)
X_transformed = svd.fit_transform(X)
U = X_transformed / svd.singular_values_
Sigma_matrix = np.diag(svd.singular_values_)
VT = svd.components_
замечание
Усеченный СВД является приблизительным. X ≈ X '= UΣV *. У нас есть X'V = UΣ. Но как насчет XV? Интересный факт - XV = X'V. Это можно доказать, сравнив полную форму SVD X и усеченную форму SVD X '. Примечание XV - это просто transform(X)
, поэтому мы также можем получить U
U = svd.transform(X) / svd.singular_values_
Ответ 5
Я знаю, что это старый вопрос, но правильная версия is-
U = svd.fit_transform(X)
Sigma = svd.singular_values_
VT = svd.components_
Однако следует иметь в виду, что U и VT усекаются, поэтому без остальных значений невозможно воссоздать X.
Ответ 6
Предположим, что X - наша входная матрица, на которой мы хотим выполнить Truncated SVD.
Ниже команды помогают узнать U, Sigma и VT:
from sklearn.decomposition import TruncatedSVD
SVD = TruncatedSVD(n_components=r)
U = SVD.fit_transform(X)
Sigma = SVD.explained_variance_ratio_
VT = SVD.components_
#r corresponds to the rank of the matrix
Чтобы понять приведенные выше термины, обратитесь к http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.TruncatedSVD.html