Sklearn TruncatedSVD 没有按降序显示解释的方差比,或者第一个数字有其他含义?
Sklearn TruncatedSVD not showing explained variance ration in descending order, or first number means something else?
from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.decomposition import TruncatedSVD
digits = datasets.load_digits()
X = digits.data
X = X - X.mean() # centering the data
#### svd
svd = TruncatedSVD(n_components=5)
svd.fit(X)
print(svd.explained_variance_ration)
#### PCA
pca = PCA(n_components=5)
pca.fit(X)
print(pca.explained_variance_ratio_)
svd 输出为:
array([0.02049911, 0.1489056 , 0.13534811, 0.11738598, 0.08382797])
pca 输出为:
array([0.14890594, 0.13618771, 0.11794594, 0.08409979, 0.05782415])
TruncatedSVD 实现中是否存在错误?或者为什么第一个解释的方差 (0.02...) 表现得像这样?或者是什么意思
总结:
那是因为TruncatedSVD
和PCA
使用了不同的SVD
函数!
注意:您的案例是由于下面的原因 2,但我为未来的读者提供了另一个原因。
详情:
原因1:用户在每个算法中设置的求解器不同:
PCA
内部使用 scipy.linalg.svd 对奇异值进行排序,因此 explained_variance_ratio_
被排序。
PCA
的部分 Scikit 实现:
# Center data
U, S, Vt = linalg.svd(X, full_matrices=False)
# flip eigenvectors' sign to enforce deterministic output
U, Vt = svd_flip(U, Vt)
components_ = Vt
# Get variance explained by singular values
explained_variance_ = (S ** 2) / (n_samples - 1)
total_var = explained_variance_.sum()
explained_variance_ratio_ = explained_variance_ / total_var
上面的截图scipy.linalg.svd
link:
另一方面,TruncatedSVD
使用 scipy.sparse.linalg.svds,它依赖于 ARPACK
解算器进行分解。
上面的截图scipy.sparse.linalg.svds
link:
原因 2:TruncatedSVD
的运行方式与 PCA
不同:
在您的情况下,您在两种算法中都选择了 randomized
作为求解器(默认设置),但您在方差阶数方面获得了不同的结果。
那是因为在PCA
中,方差是从已经排序的实际奇异值(在Scikit-Learn实现中称为Sigma
或S
)中获得的:
另一方面,TruncatedSVD
中的方差是从 X_transformed
中获得的,它是数据矩阵乘以分量的结果。后者不一定保留顺序,因为数据不居中,也不是 TruncatedSVD
的目的,它首先用于稀疏矩阵:
现在,如果您将数据居中,就会对它们进行排序(请注意,您没有正确居中数据,因为居中需要除以标准差):
from sklearn import datasets
from sklearn.decomposition import TruncatedSVD
from sklearn.preprocessing import StandardScaler
digits = datasets.load_digits()
X = digits.data
sc = StandardScaler()
X = sc.fit_transform(X)
### SVD
svd = TruncatedSVD(n_components=5, algorithm='randomized', random_state=2021)
svd.fit(X)
print(svd.explained_variance_ratio_)
输出
[0.12033916 0.09561054 0.08444415 0.06498406 0.04860093]
from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.decomposition import TruncatedSVD
digits = datasets.load_digits()
X = digits.data
X = X - X.mean() # centering the data
#### svd
svd = TruncatedSVD(n_components=5)
svd.fit(X)
print(svd.explained_variance_ration)
#### PCA
pca = PCA(n_components=5)
pca.fit(X)
print(pca.explained_variance_ratio_)
svd 输出为:
array([0.02049911, 0.1489056 , 0.13534811, 0.11738598, 0.08382797])
pca 输出为:
array([0.14890594, 0.13618771, 0.11794594, 0.08409979, 0.05782415])
TruncatedSVD 实现中是否存在错误?或者为什么第一个解释的方差 (0.02...) 表现得像这样?或者是什么意思
总结:
那是因为TruncatedSVD
和PCA
使用了不同的SVD
函数!
注意:您的案例是由于下面的原因 2,但我为未来的读者提供了另一个原因。
详情:
原因1:用户在每个算法中设置的求解器不同:
PCA
内部使用 scipy.linalg.svd 对奇异值进行排序,因此 explained_variance_ratio_
被排序。
PCA
的部分 Scikit 实现:
# Center data
U, S, Vt = linalg.svd(X, full_matrices=False)
# flip eigenvectors' sign to enforce deterministic output
U, Vt = svd_flip(U, Vt)
components_ = Vt
# Get variance explained by singular values
explained_variance_ = (S ** 2) / (n_samples - 1)
total_var = explained_variance_.sum()
explained_variance_ratio_ = explained_variance_ / total_var
上面的截图scipy.linalg.svd
link:
另一方面,TruncatedSVD
使用 scipy.sparse.linalg.svds,它依赖于 ARPACK
解算器进行分解。
上面的截图scipy.sparse.linalg.svds
link:
原因 2:TruncatedSVD
的运行方式与 PCA
不同:
在您的情况下,您在两种算法中都选择了 randomized
作为求解器(默认设置),但您在方差阶数方面获得了不同的结果。
那是因为在PCA
中,方差是从已经排序的实际奇异值(在Scikit-Learn实现中称为Sigma
或S
)中获得的:
另一方面,TruncatedSVD
中的方差是从 X_transformed
中获得的,它是数据矩阵乘以分量的结果。后者不一定保留顺序,因为数据不居中,也不是 TruncatedSVD
的目的,它首先用于稀疏矩阵:
现在,如果您将数据居中,就会对它们进行排序(请注意,您没有正确居中数据,因为居中需要除以标准差):
from sklearn import datasets
from sklearn.decomposition import TruncatedSVD
from sklearn.preprocessing import StandardScaler
digits = datasets.load_digits()
X = digits.data
sc = StandardScaler()
X = sc.fit_transform(X)
### SVD
svd = TruncatedSVD(n_components=5, algorithm='randomized', random_state=2021)
svd.fit(X)
print(svd.explained_variance_ratio_)
输出
[0.12033916 0.09561054 0.08444415 0.06498406 0.04860093]