Получите матрицу U, Sigma, V * из усеченного SVD в scikit-learn

Я использую усеченный SVD из scikit-learn.

В определении SVD исходная матрица A аппроксимируется как произведение AUΣ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