sklearn中的PCA主成分与numpy计算的协方差特征向量不匹配

机器算法验证 主成分分析 Python scikit-学习 麻木的
2022-03-28 01:01:13

我试图在 sklearn 的 PCA API 中使用 numpy在 numpy 中使用 PCA 来复制 PCA,而 sklearn 会产生不同的结果我注意到:

  • 特征值与 PCA 对象的 explain_variance_ 属性以及顺序相同
  • 特征向量不相同。这是我的代码:
import numpy as np
from sklearn.decomposition import PCA
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
X = datasets.load_iris()['data']
X_scaled = StandardScaler().fit_transform(X)

pca = PCA(n_components=4)
pca.fit(X_scaled)

print('Explained Variance = ', pca.explained_variance_)
print('Principal Components = ', pca.components_)

这给了我:

Explained Variance =  [2.93808505 0.9201649  0.14774182 0.02085386]
Principal Components =  [[ 0.52106591 -0.26934744  0.5804131   0.56485654]
 [ 0.37741762  0.92329566  0.02449161  0.06694199]
 [-0.71956635  0.24438178  0.14212637  0.63427274]
 [-0.26128628  0.12350962  0.80144925 -0.52359713]]

使用 Numpy:

cov = np.cov(X_scaled.T)
eig_val, eig_vec = np.linalg.eig(cov)
print('Eigenvalues = ', eig_val)
print('Eigenvectors = ', eig_vec)

这给了我:

Eigenvalues =  [2.93808505 0.9201649  0.14774182 0.02085386]
Eigenvectors =  [[ 0.52106591 -0.37741762 -0.71956635  0.26128628]
 [-0.26934744 -0.92329566  0.24438178 -0.12350962]
 [ 0.5804131  -0.02449161  0.14212637 -0.80144925]
 [ 0.56485654 -0.06694199  0.63427274  0.52359713]]

pca.explained_variance_请注意,特征值与ie完全相同,不像numpy 中的后 PCA 和 sklearn 产生不同的结果表明,我们确实通过 numpy 中的降序获得特征值(至少在本示例中),但特征向量与pca.components_. 为什么会这样以及如何手动复制 Sklearn 的 PCA API 的确切结果。

1个回答

虽然这是一个纯 python 相关的问题,不适合 CrossValidated,但无论如何让我来帮助你。这两个过程都找到了正确的特征向量。不同之处在于它的表示。虽然PCA()按行列出特征向量np.linalg.eig()的条目,但按列列出特征向量的条目。请记住,特征向量只有一个符号是唯一的。事实上,一个简单的检查产生:

print(abs(eig_vec.T.round(10))==abs(pca.components_.round(10)))
[[ True,  True,  True,  True],
   [ True,  True,  True,  True],
   [ True,  True,  True,  True],
   [ True,  True,  True,  True]])