为什么 sklearn.decomposition.PCA.fit_transform(X) 不乘以 X?
Why does sklearn.decomposition.PCA.fit_transform(X) no multiplication by X?
据我了解PCA一般有以下步骤:
- 计算协方差矩阵 Σ = (1/m) * (X*X')
- 对 Σ 应用奇异值分解:U,S,V = SVD(Σ)
- 取 U 的前 k 列减少到 k 维:U_reduced = U[:,k]
- 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?
据我了解PCA一般有以下步骤:
- 计算协方差矩阵 Σ = (1/m) * (X*X')
- 对 Σ 应用奇异值分解:U,S,V = SVD(Σ)
- 取 U 的前 k 列减少到 k 维:U_reduced = U[:,k]
- 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?