PCA必须先标准化,否则量纲差异会导致高数值特征主导主成分方向;StandardScaler使各特征均值为0、标准差为1,保障协方差计算中特征“平等”贡献。

PCA 不能跳过标准化直接用,否则量纲大的特征会主导主成分方向——这是最常踩的坑。
为什么必须先用 StandardScaler?
原始数据中,比如“年收入(万元)”和“年龄(岁)”数值范围差两个数量级,协方差矩阵会被收入项严重拉偏。StandardScaler 把每个特征变成均值为 0、标准差为 1 的分布,让它们在计算协方差时真正“平等”。
常见错误现象:pca.components_ 显示第一主成分几乎只由某个高量纲变量构成,explained_variance_ratio_ 分布极不均匀,甚至前 5 个成分累计不到 60%。
- 标准化必须在
fit_transform时对训练集做,测试集用transform复用同一 scaler - 别用
MinMaxScaler替代——PCA 依赖的是方差结构,不是缩放到 [0,1] - 如果数据含大量稀疏特征(如 one-hot 编码),标准化后可能破坏稀疏性,需谨慎评估
PCA(n_components=...) 怎么选值?
硬设 n_components=2 或 3 只适合可视化;真实建模要按信息保留率来定。
立即学习“Python免费学习笔记(深入)”;
推荐做法是先拟合全维度 PCA,再看累计解释方差曲线:
from sklearn.decomposition import PCA pca_full = PCA().fit(X_scaled) plt.plot(np.cumsum(pca_full.explained_variance_ratio_)) plt.axhline(y=0.85, linestyle='--', color='r') # 标出 85% 线
- 横轴数值即建议的
n_components值,例如曲线在第 7 个点首次越过 0.85,就设n_components=7 -
n_components=0.85(传浮点数)也能让 sklearn 自动截断,但不易调试中间过程 - 若原始特征数 200,85% 往往已足够,避免过拟合噪声
降维后怎么还原回原始空间?
调用 pca.inverse_transform() 可以近似还原,但它只还原到主成分张成的子空间,无法恢复被丢弃的方向信息。
这在图像重建、异常检测中很关键:
- 还原前必须确保输入是 PCA 输出的低维表示(shape 匹配
pca.n_components_) - 还原结果仍需反向标准化:用同一个
scaler.inverse_transform()才能得到原始量纲 - 还原误差可用
np.mean((X_original - X_recon) ** 2)评估,误差大说明保留成分太少
用 np.linalg.eig 手动实现 PCA 有什么实际价值?
绝大多数场景下没必要——sklearn.PCA 经过高度优化,支持 svd_solver 参数适配不同规模数据,且自动处理中心化。
手动实现仅在两类情况有用:
- 教学调试:想逐行验证协方差矩阵是否对称、特征向量是否正交、投影是否满足
X_pca = X_centered @ V[:, :k] - 嵌入式或极简环境:无法安装 scikit-learn,只能靠 numpy + scipy
- 注意:手算时
np.cov(X_scaled.T)必须转置,而sklearn内部默认按样本行处理,别混淆维度顺序
实际项目里,最容易被忽略的是:标准化和 PCA 必须作为 pipeline 固定步骤封装起来。单独保存 pca 对象却忘了保存配套的 scaler,上线后 predict 就会因未标准化直接崩掉。


















