交互项通过构造乘积特征使线性模型捕获变量协同效应,需先标准化再生成,PolynomialFeatures实现升维投影而非非线性拟合,应嵌入Pipeline保证训练预测一致性,避免手动构造导致维度不匹配。

交互项让线性模型“看见”变量间的协同效应
线性回归本身只能建模各特征对目标的独立加性影响,比如 price = β₀ + β₁×area + β₂×rooms。但现实中,area 和 rooms 往往不是各自起作用——100㎡配2个房间和100㎡配4个房间,价值完全不同。交互项 area × rooms 就是把这种“组合价值”显式变成一个新特征,让模型能学出:当房间数多时,每平米的溢价更高(或更低)。
常见错误现象:LinearRegression 在含交互关系的数据上 R² 低于 0.4,残差图呈现明显 U 形或 S 形趋势;单独看 area 和 rooms 的系数显著,但业务解释不通(比如面积系数为负,违背常识)。
- 必须先做中心化或标准化再构造交互项,否则
β₁和β₂会严重受量纲干扰(例如面积单位是㎡还是km²,会直接改变交互项数值大小) -
PolynomialFeatures(interaction_only=True)只生成乘积项,不带平方项,适合你明确只想捕捉协同、不希望引入单变量非线性的情况 - 分类变量参与交互时,要确保其类型是
category或已做 one-hot 编码,否则PolynomialFeatures会把类别标签(如 0/1)当作数值相乘,失去语义
PolynomialFeatures 实际做了什么?不是“拟合曲线”,而是“升维投影”
它不修改模型结构,只改输入数据形状。原始特征矩阵 X 是 (n_samples, 1),PolynomialFeatures(degree=2) 后变成 (n_samples, 3):列分别是 [x, x², x×x](最后一项其实是冗余的,但 sklearn 默认保留)。对多特征如 [x₁, x₂],degree=2 会输出 [x₁, x₂, x₁², x₂², x₁×x₂] —— 所有不超过二阶的单项与交叉项。
关键点在于:这些新列仍被 LinearRegression 当作独立输入,用普通最小二乘求解。所以最终模型仍是线性的(对系数而言),但输入空间已从 ℝ¹ 映射到 ℝ⁵,曲面在高维中变“直”了。
立即学习“Python免费学习笔记(深入)”;
- degree=3 时,两个特征会产生 10 列(含常数项),三特征则达 20 列;维度爆炸很快,别盲目设 high degree
-
include_bias=False可去掉全 1 列(即截距项),如果你后续会用fit_intercept=True的LinearRegression,这个参数建议设为True避免重复 - 用
poly.get_feature_names_out()查看每列对应什么表达式,避免调试时搞混x0和x1的顺序
为什么不用 statsmodels 公式接口而选 sklearn 流水线?
因为 statsmodels.formula.api.ols('y ~ x1 + x2 + x1:x2', data=df) 虽然写法直观,但它不支持 transform 接口,无法嵌入 Pipeline 做训练/预测一致性处理。一旦上线,你得手动复现同样的交互逻辑,极易出错。
而 PolynomialFeatures + LinearRegression 组成的 pipeline,调用一次 fit() 就固化了全部变换规则,predict() 时自动完成相同映射。这对部署和 A/B 测试至关重要。
- 不要在训练前手写
df['x1_x2'] = df['x1'] * df['x2'],这会导致测试集缺失该列,predict()报ValueError: X has 2 features, but LinearRegression is expecting 3 features - 如果要用
StandardScaler,务必放在PolynomialFeatures之后——因为标准化的是多项式后的特征,不是原始特征 - 交叉验证必须在整个 pipeline 上做,不能只 cross-validate
LinearRegression,否则会泄漏PolynomialFeatures的数据分布信息
过拟合信号比你想的更早出现
当你看到训练集 R² > 0.95 但测试集 R²
真正容易被忽略的是:交互项和高次项会急剧扩大特征的方差范围。比如 x 在 [0, 1],x² 就压缩到 [0, 1],但 x³ 更扁平;而 x₁×x₂ 若两变量都未缩放,可能产生远超原始量级的新值,导致 LinearRegression 的数值不稳定(np.linalg.lstsq 内部条件数飙升)。
- 永远检查
np.linalg.cond(X_poly.T @ X_poly),> 1e12 就说明矩阵接近奇异,需要缩放或降维 - 用
RFE或 Lasso(LassoCV)配合多项式特征做自动筛选,比硬设 degree 更鲁棒 - degree=2 的交互项已经能覆盖绝大多数业务场景;degree=3 及以上几乎总是过拟合,除非你有强先验且样本量极大(>10⁵)


















