为啥 sklearn 和 numpy 不同意 PCA 的乘法分量?

Posted

技术标签:

【中文标题】为啥 sklearn 和 numpy 不同意 PCA 的乘法分量?【英文标题】:Why does sklearn and numpy disagree about multiplying component of PCA?为什么 sklearn 和 numpy 不同意 PCA 的乘法分量? 【发布时间】:2021-03-28 11:14:03 【问题描述】:
from sklearn.datasets import make_blobs
from sklearn.decomposition import PCA

SEED = 123
X, y = make_blobs(n_samples=1000, n_features=5000, cluster_std=90., random_state=SEED)
pca = PCA(2)
pca.fit(X)
pca1, pca2 = pca.components_

pcaX = pca.transform(X)
pcaXnp = np.array([X @ pca1, X @ pca2]).T

如果您打印出 pcaX 和 pcaXnp,您会发现它们很相似,但彼此不一致。为什么这些应该不同?似乎“.components_”应该返回 sklearn 将矩阵乘以的内容,是否有理由说明它只是乘法的近似值?

【问题讨论】:

【参考方案1】:

来自 sklearn.decomposition 的 PCA 使用奇异值分解或 SVD 来获取您的主成分。这仅在列首先是 centered by their means 时才有效。如果您检查source code,他们会在 SVD 之前进行居中:

def _fit_full(self, X, n_components):
[...]
        # Center data
        self.mean_ = np.mean(X, axis=0)
        X -= self.mean_

因此,要获得 PCA 分数,您需要先将矩阵居中:

pcaX = pca.transform(X)
Xc = X - X.mean(axis=0)
pcaXnp = np.array([Xc @ pca1, Xc @ pca2]).T

pcaX[:3]
array([[-101.45177987,  212.45583745],
       [ 520.84541298,   87.32254399],
       [-273.26407231, -318.78493994]])

pcaXnp[:3]
array([[-101.45177987,  212.45583745],
       [ 520.84541298,   87.32254399],
       [-273.26407231, -318.78493994]])

【讨论】:

以上是关于为啥 sklearn 和 numpy 不同意 PCA 的乘法分量?的主要内容,如果未能解决你的问题,请参考以下文章

带有sklearn的numpy多项式线性回归

为啥 SKlearn 和 WEKA 结果不匹配?

Sklearn库

带有 SKLEARN、PANDAS 和 NUMPY 问题的 Python 部署包?

python常用库 - NumPy 和 sklearn入门

Numpy、Pandas 和 Sklearn 中的多维缩放拟合(ValueError)