PCA 主成分分析详解
一、什么是 PCA
PCA(Principal Component Analysis)是一种无监督线性降维方法,通过正交变换将高维数据投影到新的坐标系中,使得:
- 第一主成分方向上的数据方差最大(信息量最大)
- 后续主成分依次取与前面正交的方向中方差最大者
- 各主成分之间互不相关(正交)
直观理解:找一组新的轴,让数据在这些轴上的投影尽可能"散开",用少数几个轴就能捕捉大部分信息。
二、数学原理
步骤
1. 数据标准化 X_std = (X - μ) / σ 2. 计算协方差矩阵 C = (1/n) · X_stdᵀ · X_std 3. 对协方差矩阵做特征值分解 C · v = λ · v λ₁ ≥ λ₂ ≥ ... ≥ λₖ (特征值,即各主成分的方差) v₁, v₂, ..., vₖ (特征向量,即各主成分的方向) 4. 选择前 m 个主成分 W = [v₁, v₂, ..., vₘ] (投影矩阵) 5. 投影到低维空间 X_pca = X_std · W
核心关系
特征值 λᵢ = 第 i 个主成分的方差 方差贡献率 = λᵢ / Σλⱼ 累计方差贡献率 = Σ(λ₁~λₘ) / Σλⱼ
三、PCA 在数据分析中的作用
| 作用 | 说明 |
|---|
| 降维 | 用少数主成分替代大量原始特征,减少计算开销 |
| 去相关 | 主成分之间正交,消除多重共线性 |
| 去噪 | 舍弃方差小的主成分(通常对应噪声),保留信号 |
| 可视化 | 降到 2-3 维后绘制散点图,观察数据分布和聚类 |
| 特征压缩 | 为后续建模提供低维输入,降低过拟合风险 |
| 数据压缩 | 存储和传输时只需保留主成分系数和投影矩阵 |
四、如何确定保留多少主成分
| 方法 | 规则 | 特点 |
|---|
| 累计方差贡献率法 | 保留累计贡献率 ≥ 85%(或 90%/95%)的成分 | 最常用,阈值可按需调整 |
| 碎石图(Scree Plot) | 画特征值随主成分序号的折线图,取拐点 | 直观,但拐点有时不明显 |
| Kaiser 准则 | 保留特征值 > 1 的主成分 | 适用于标准化数据,偏保守 |
| 交叉验证 | 比较不同主成分数下下游模型的性能 | 最可靠,但计算成本高 |
碎石图示意:
特征值 │ │ * │ * │ * │ * │ * * * * * * * ← 拐点之后趋于平缓 │ └──────────────────→ 主成分序号 ↑ 拐点处截断
五、PCA 的假设与局限
| 假设/局限 | 说明 |
|---|
| 线性假设 | PCA 只能捕捉线性关系,非线性结构需用 Kernel PCA / UMAP |
| 大方差 = 重要信息 | 方差小的成分被丢弃,但有时小方差特征恰好是关键区分信号 |
| 主成分不可解释 | 主成分是原始特征的线性组合,通常没有明确的业务含义 |
| 对异常值敏感 | 少数极端值会显著影响协方差矩阵和主成分方向 |
| 需标准化 | 量纲不同时,大方差特征会主导主成分,必须先 Z-score 标准化 |
六、PCA vs 其他降维方法
| 对比维度 | PCA | LDA | t-SNE | UMAP | Autoencoder |
|---|
| 类型 | 无监督 | 有监督 | 无监督 | 无监督 | 无监督 |
| 线性/非线性 | 线性 | 线性 | 非线性 | 非线性 | 非线性 |
| 主要用途 | 通用降维 | 分类降维 | 可视化 | 可视化+降维 | 复杂数据降维 |
| 可解释性 | 低 | 中 | 低 | 低 | 低 |
| 计算效率 | 高 | 高 | 低 | 中 | 低(需训练) |
| 保持全局结构 | 好 | 好 | 差 | 较好 | 取决于架构 |
七、Python 实践示例
fromsklearn.preprocessingimportStandardScalerfromsklearn.decompositionimportPCAimportmatplotlib.pyplotasplt# 1. 标准化(必须)scaler=StandardScaler()X_std=scaler.fit_transform(X)# 2. 拟合 PCApca=PCA(n_components=0.90)# 保留 90% 方差X_pca=pca.fit_transform(X_std)print(f"原始维度:{X.shape[1]}")print(f"降维后维度:{X_pca.shape[1]}")print(f"各主成分方差贡献率:{pca.explained_variance_ratio_}")print(f"累计方差贡献率:{pca.explained_variance_ratio_.cumsum()}")# 3. 碎石图plt.plot(range(1,len(pca.explained_variance_ratio_)+1),pca.explained_variance_ratio_,'bo-')plt.xlabel('主成分序号')plt.ylabel('方差贡献率')plt.title('Scree Plot')plt.show()# 4. 2D 可视化pca_2d=PCA(n_components=2)X_2d=pca_2d.fit_transform(X_std)plt.scatter(X_2d[:,0],X_2d[:,1],c=y,cmap='viridis',alpha=0.6)plt.xlabel('PC1')plt.ylabel('PC2')plt.title('PCA 2D Projection')plt.show()
八、实践要点总结
- 标准化是前提— 不标准化,PCA 结果由量纲决定而非数据结构
- PCA 是无监督的— 不使用标签信息,降维结果不一定有利于分类
- 避免信息泄露—
fit只在训练集上做,再用transform处理测试集 - 降维不是目的— 保留多少维度应结合下游任务验证,而非仅看方差贡献率
- 先检查线性可分性— 若数据有强非线性结构,PCA 可能效果不佳,考虑 Kernel PCA 或流形学习