直接用LinearRegression会失效是因为特征强相关导致设计矩阵X.T@X接近奇异,逆运算不稳定;PCA需中心化且须保存均值和成分,推荐用Pipeline封装并选累计方差比≥0.95的主成分。

为什么直接用 LinearRegression 会失效?
当特征之间存在强相关性(比如 X[:, 0] 和 X[:, 1] 相关系数 > 0.95),LinearRegression 的系数估计会剧烈震荡,coef_ 可能正负交替、数值极大,甚至出现 LinAlgError: Singular matrix。这不是模型“学不会”,而是设计矩阵 X.T @ X 接近奇异,逆运算不稳定。
用 PCA + LinearRegression 手动组合的坑
常见错误是先对原始 X 做 PCA.fit_transform(X),再用结果训练回归模型,却忘了:PCA 默认不中心化新样本,预测时若未对新 X_test 手动减去训练集均值并投影,预测结果完全错误。
- 必须保存
pca.mean_和pca.components_,不能只存变换后数据 -
PCA(n_components=0.95)比固定数量更稳妥,避免保留过多噪声主成分 - 别在 PCA 前做标准化——
StandardScaler已隐含在PCA中(除非你手动设copy=False, whiten=False)
推荐用 Pipeline 封装,避免数据泄漏和预处理错位
主成分回归本质是两步:中心化 → PCA 投影 → 线性拟合。用 Pipeline 能确保 fit 和 predict 流程一致,且 cross_val_score 也能正确评估。
from sklearn.pipeline import Pipeline
from sklearn.decomposition import PCA
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
<h1>注意:StandardScaler 不是必须的,因为 PCA 内部已中心化;但显式加上更清晰</h1><p>pipe = Pipeline([
('scaler', StandardScaler()),
('pca', PCA(n_components=0.85)),
('lr', LinearRegression())
])
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)
如果特征量级差异极大(如有的列是年龄,有的是收入),StandardScaler 仍建议保留;否则 PCA 会受量纲主导。
立即学习“Python免费学习笔记(深入)”;
PCA 维度选多少才够?看累计方差比,不是拍脑袋
选太少(如 n_components=2)可能丢掉关键信息;选太多(如 n_components=50)又没解决共线性。真正该盯的是 pca.explained_variance_ratio_.cumsum():
pca = PCA().fit(X_train) print(pca.explained_variance_ratio_.cumsum()[:10]) # 输出类似:[0.42 0.67 0.79 0.86 0.91 0.94 0.96 0.97 0.98 0.99]
从输出可见,取前 6 个主成分就能解释 94% 方差,足够平衡降维与信息保留。硬设 n_components=0.95 是更省心的选择。
实际中,高度相关特征常导致前几个主成分承载绝大多数方差——这也是 PCA 有效的根本原因。但别忽略:主成分回归牺牲了可解释性,coef_ 对应的是主成分而非原始变量,想归因得回溯 pca.components_ 和原始特征权重。


















