用MLAlgorithms做降维:PCA主成分分析的代码实现与几何直觉完全指南
【免费下载链接】MLAlgorithmsMinimal and clean examples of machine learning algorithms implementations项目地址: https://gitcode.com/gh_mirrors/ml/MLAlgorithms
MLAlgorithms是一个用最小、最干净的代码实现机器学习算法的开源项目,其中 mla/pca.py 仅用 60 多行 Python 就完整实现了PCA 主成分分析——一种最常用的数据降维算法。对于初学者来说,读这份源码比啃优化过的 sklearn 内部实现要轻松得多,是理解「PCA 到底在做什么」的最佳切入点。
一、为什么需要降维?
高维数据有三个经典痛点:
- 计算贵:100 个特征的分类问题,比 2 个特征慢几十倍;
- 噪声多:很多特征对结果毫无贡献,反而干扰模型(维度灾难);
- 看不清:人眼只能看 2D/3D,想把数据画出来就必须降维。
PCA 的思路一句话概括:把一堆可能相关的特征,旋转成几个互不相关的"主成分",并按方差从大到小排序。前几个主成分就保留了数据中绝大部分的"变化信息"。
几何直觉:找数据"伸展"的方向
想象 1000 个点在二维平面上排成一条斜着的椭圆:
- 中心化:先把数据平移到原点(减均值);
- 旋转:找到椭圆长轴方向——这是数据"变化最大"的方向,即第一主成分;
- 正交约束:第二主成分必须与第一主成分垂直,取剩余变化最大的方向;
- 丢弃:如果短轴方向的波动只有长轴的 1%,丢掉它几乎不损失信息。
PCA 的输出components就是这组旋转方向向量(行向量),把数据乘上它的转置,就完成了"换坐标轴"。
二、项目里的 PCA 长什么样
整个核心实现集中在 mla/pca.py,类定义在第 12 行:
class PCA(BaseEstimator): y_required = False # 无监督任务,不需要标签 y它继承自 mla/base/base.py 的BaseEstimator(该文件第 5 行),统一了fit / transform / predict的接口风格,与 scikit-learn 的用法几乎一致——这点对新手很友好。
三个关键方法
| 方法 | 代码位置 | 作用 |
|---|---|---|
fit | mla/pca.py#L35-L37 | 计算均值 + 分解 |
_decompose | mla/pca.py#L39-L55 | 中心化、SVD/特征分解、求方差解释比 |
transform | mla/pca.py#L57-L60 | 投影到主成分空间 |
核心逻辑逐行看
_decompose是灵魂(mla/pca.py#L39-L55):
def _decompose(self, X): X = X.copy() X -= self.mean # ① 均值中心化 if self.solver == "svd": _, s, Vh = svd(X, full_matrices=True) # ② SVD 分解 elif self.solver == "eigen": s, Vh = np.linalg.eig(np.cov(X.T)) # ② 协方差矩阵特征分解 Vh = Vh.T s_squared = s**2 variance_ratio = s_squared / s_squared.sum() # ③ 方差解释比 self.components = Vh[0 : self.n_components] # ④ 取前 k 个方向对应上面四步几何直觉:① 中心化 → ② 求方向 → ③ 看每个方向保留了多少方差 → ④ 只留下前 k 个方向。
transform则只是一次矩阵乘法(mla/pca.py#L57-L60):先减均值,再X @ components.T,把每个样本"读"成新坐标。
💡两个求解器怎么选?
solver="svd"(默认,基于scipy.linalg.svd)数值更稳定、更推荐;solver="eigen"走协方差矩阵特征分解,是教科书式写法,便于对照公式理解。两者数学上等价。
三、快速上手:从安装到运行示例
安装项目
git clone https://gitcode.com/gh_mirrors/ml/MLAlgorithms cd MLAlgorithms pip install -r requirements.txt python setup.py develop依赖很轻:只需 requirements.txt 里的 numpy、scipy 等科学计算库。
运行 PCA 官方示例
不安装也能直接跑(项目自带示例模块 examples/pca.py):
python -m examples.pca这个示例做了一个完整的降维 + 分类流水线,步骤拆解:
- 用 sklearn 造一个1000 样本 × 100 特征的二分类问题(examples/pca.py#L14-L21);
- 划分训练/测试集;
- 分别用
svd和eigen两种求解器做 PCA,把 100 维压到15 维(examples/pca.py#L28-L34); - 在降维后的数据上训练 mla/linear_models.py 里的
LogisticRegression,打印分类准确率。
for s in ["svd", "eigen"]: p = PCA(15, solver=s) p.fit(X_train) # 只在训练集上 fit! X_train_reduced = p.transform(X_train) X_test_reduced = p.transform(X_test) # 接着训练逻辑回归,对比两种 solver 的准确率跑完你会看到类似输出:
Classification accuracy for svd PCA: 0.87xx Classification accuracy for eigen PCA: 0.87xx100 维直接降到 15 维,准确率几乎不掉——这就是 PCA 的威力。
一个容易踩的坑
注意示例里刻意只fit(X_train),再transform测试集(examples/pca.py#L31-L34)。PCA 会"记住"训练集的均值和方向,测试集不能参与 fit,否则会造成数据泄漏,让准确率虚高。
四、如何选择主成分个数 k?
PCA 没有告诉你 k 该选多少,但_decompose里已经算好了答案——方差解释比(mla/pca.py#L50-L54):
variance_ratio = s_squared / s_squared.sum() logging.info("Explained variance ratio: %s" % (variance_ratio[:self.n_components]))打开日志即可看到前 k 个主成分各自解释了多大比例的方差。经验法则:让累计解释比达到 95% 左右,对应的 k 就是甜点。
import logging logging.basicConfig(level=logging.INFO) # 加上这行就能看到解释比 from mla.pca import PCA p = PCA(n_components=15, solver="svd") p.fit(X_train)五、配套测试与延伸学习
- 降维的测试用例在 mla/tests/test_reduction.py,它验证「PCA 降到 50 维 + 随机森林」的 ROC-AUC 不低于 0.75(当前标记为 skip,可作参考);
- 想用非线性降维?同目录的 mla/tsne.py 实现了 t-SNE,适合做数据可视化;
- 想继续深挖线性模型,可看 mla/linear_models.py 的梯度下降实现;
- 更多算法清单见 README.md。
六、常见问题 FAQ
Q1:PCA 是监督学习吗?不是。y_required = False表明它只看特征 X,不需要标签,属于无监督特征提取。
Q2:PCA 对特征尺度敏感吗?非常敏感。方差大的特征会主导主成分,实际使用前建议先做标准化(本项目示例数据本身尺度一致,所以未处理)。
Q3:60 行代码,和 sklearn 的 PCA 差在哪?功能上,这里实现的是核心数学流程;sklearn 额外处理了增量拟合、稀疏矩阵、多种 solver 加速等工程细节。学原理读这里,生产用 sklearn。
Q4:fit之后哪些属性能拿来用?
p.mean:训练集均值(mla/pca.py#L36)p.components:前 k 个主成分方向(mla/pca.py#L55)
小结
MLAlgorithms 的 PCA 实现(mla/pca.py)用「中心化 → 分解 → 取前 k 个方向」三步把主成分分析讲透了:
- ✅几何直觉:找数据变化最大的正交方向,丢弃次要方向;
- ✅双求解器:
svd(默认、稳)与eigen(教科书式)可切换对照; - ✅实战闭环:examples/pca.py 演示 100 维 → 15 维 + 逻辑回归的完整流程;
- ✅接口对齐 sklearn:
fit / transform用法一致,学习成本平滑迁移。
先跑一遍python -m examples.pca,再对照 mla/pca.py 逐行读,PCA 的数学与工程你就都通了。
【免费下载链接】MLAlgorithmsMinimal and clean examples of machine learning algorithms implementations项目地址: https://gitcode.com/gh_mirrors/ml/MLAlgorithms
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考