为什么sklearn和numpy在计算PCA的成分乘法时结果不同?

3
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个回答

1

sklearn.decomposition中的PCA使用奇异值分解(SVD)来获取主成分。这仅在列首先通过其平均值居中时才有效。如果您检查源代码,它们会在进行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]])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接