为什么 sklearn.decomposition.PCA.fit_transform(X) 不乘以 X?

Why does sklearn.decomposition.PCA.fit_transform(X) no multiplication by X?

据我了解PCA一般有以下步骤:

  1. 计算协方差矩阵 Σ = (1/m) * (X*X')
  2. 对 Σ 应用奇异值分解:U,S,V = SVD(Σ)
  3. 取 U 的前 k 列减少到 k 维:U_reduced = U[:,k]
  4. X_reduced = U_reduced' * X

X_reduced 是 X 减少到 k 维。

但是当我查看 implementation of SKLearn 时,我发现了这行代码:

U *= S[:self.n_components_]

并且这个 U 作为转换后的 X 返回。 为什么使用 S 而不是 X 仍然有效?

你对1-2的理解有误。通过将 SVD 应用于居中数据矩阵,可以通过找到协方差矩阵 的特征向量来实现 PCA 或者。您不会同时执行协方差和 SVD。在实践中,SVD 方法更可取,因为协方差矩阵的计算会放大与条件较差的矩阵相关的数值问题。 SKLearn 使用它;这是 the core of the method

self.mean_ = np.mean(X, axis=0)
X -= self.mean_
U, S, V = linalg.svd(X, full_matrices=False)

SVD 将 X 表示为 U @ S @ V.T(使用 @ 进行矩阵乘法,并假设实值数据)。这里V由协方差矩阵的特征向量组成,满足正交关系V.T @ V = I

根据特征向量V,转换后的数据为X @ V。但由于 X 等于 U @ S @ V.T,两边都乘以 V 会导致 X @ V 等于 U @ S。因此,U @ S 是转换后的数据。

乘以 S(对角线)比乘以 X(任意稠密矩阵)更容易。

有关更多信息,请参阅 Relationship between SVD and PCA. How to use SVD to perform PCA?