《sklearn机器学习——数据预处理》生成多项式特征
生成多项式特征
生成多项式特征的核心思想是通过构造原始特征的多项式组合(如平方项、交叉项等)来扩展特征空间,从而提升模型的非线性拟合能力。在线性模型中,若数据关系非线性,模型可能欠拟合。通过引入如 x12x_1^2x12、x22x_2^2x22、x1x2x_1x_2x1x2 等高阶项,可使线性模型在扩展后的特征空间中拟合更复杂的决策边界。例如,将二维特征 (x1,x2)(x_1, x_2)(x1,x2) 转换为 (1,x1,x2,x12,x1x2,x22)(1, x_1, x_2, x_1^2, x_1x_2, x_2^2)(1,x1,x2,x12,x1x2,x22),模型虽仍为“线性”,但能捕捉二次关系。sklearn 中的 PolynomialFeatures
类自动化此过程,支持指定最高阶数和是否包含交互项。但需注意,特征数量随阶数指数增长,易导致维度爆炸和过拟合,因此常配合正则化使用。
PolynomialFeatures
(生成多项式特征)
在 scikit-learn 中,PolynomialFeatures
类位于 sklearn.preprocessing
模块,用于生成多项式和交互特征。它通过将原始特征进行组合,构造出包含高阶项和交叉项的新特征矩阵,从而增强模型的表达能力。
主要参数:
degree
:整数,默认为 2。指定生成多项式的最高阶数。例如,degree=2 会生成平方项和一次交互项,degree=3 则包含立方项等。interaction_only
:布尔值,默认为 False。若为 True,则只生成交互项(如 x1x2x_1x_2x1x2),不生成高次幂项(如 x12x_1^2x12)。适用于希望避免特征膨胀且只关注特征间交互的场景。include_bias
:布尔值,默认为 True。若为 True,则在输出特征中添加一个常数项(即全为 1 的列),对应模型中的截距项。若后续使用带截距的线性模型,可设为 False 避免重复。order
:字符串,可选 ‘C’ 或 ‘F’,默认为 ‘C’。控制输出数组的内存布局顺序。‘C’ 为行优先,‘F’ 为列优先,一般保持默认即可。
返回值:
PolynomialFeatures
本身是一个转换器,调用 fit_transform(X)
方法后返回一个 NumPy 数组或稀疏矩阵(取决于输入),其形状为 (n_samples, n_output_features_)
,其中 n_output_features_
是生成后的特征总数。该数组包含原始特征的所有多项式组合,顺序由算法确定(通常按字典序排列)。
常用方法:
fit(X, y=None)
:计算输入数据X
的特征组合规则,确定输出特征的数量和结构。返回自身,用于链式调用。transform(X)
:将已学习的规则应用于数据X
,生成对应的多项式特征矩阵。要求X
的特征数与fit
时一致。fit_transform(X, y=None)
:先调用fit
,再调用transform
,一步完成训练和转换,常用于训练集。get_feature_names_out(input_features=None)
:返回输出特征的名称数组,便于理解每列对应的多项式项(如 [‘x0’, ‘x1’, ‘x0^2’, ‘x0 x1’, ‘x1^2’]),对特征解释和调试非常有用。
该类适用于线性模型前的特征增强,但需注意:当原始特征数较多或 degree
较大时,输出特征数会急剧增加(组合爆炸),可能导致过拟合和计算负担,因此常与特征选择或正则化方法(如 Lasso)结合使用。
PolynomialFeatures
类在python中的使用
本节中,python代码列出各种用法
from sklearn.preprocessing import PolynomialFeatures
import numpy as np
import pandas as pd# 创建示例数据
X = np.array([[2, 3],[4, 5],[6, 7]], dtype=float)print("原始数据 X:")
print(X)# 示例1:基本用法,degree=2
print("\n--- degree=2(默认)---")
poly = PolynomialFeatures(degree=2, include_bias=True)
X_poly = poly.fit_transform(X)
print("多项式特征:")
print(X_poly)
print("特征名称:", poly.get_feature_names_out())# 解释:输出为 [1, x0, x1, x0^2, x0*x1, x1^2]# 示例2:不包含偏置项(常数列)
print("\n--- 不包含偏置项 ---")
poly_no_bias = PolynomialFeatures(degree=2, include_bias=False)
X_poly_no_bias = poly_no_bias.fit_transform(X)
print("无常数列的多项式特征:")
print(X_poly_no_bias)
print("特征名称:", poly_no_bias.get_feature_names_out())# 示例3:仅交互项
print("\n--- 仅交互项(interaction_only=True)---")
poly_inter = PolynomialFeatures(degree=2, interaction_only=True, include_bias=True)
X_poly_inter = poly_inter.fit_transform(X)
print("仅交互项特征:")
print(X_poly_inter)
print("特征名称:", poly_inter.get_feature_names_out())# 示例4:更高阶多项式
print("\n--- degree=3 ---")
poly3 = PolynomialFeatures(degree=3, include_bias=True)
X_poly3 = poly3.fit_transform(X)
print("三次多项式特征:")
print(X_poly3)
print("特征名称:", poly3.get_feature_names_out())# 示例5:与线性模型结合使用
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline# 生成带噪声的二次关系数据
rng = np.random.RandomState(42)
X_simple = 3 * rng.rand(100, 1)
y = 0.5 * X_simple.ravel()**2 + X_simple.ravel() + 2 + rng.randn(100)*0.5# 构建管道:先生成多项式特征,再线性回归
model = Pipeline([('poly', PolynomialFeatures(degree=2)),('reg', LinearRegression())
])# 训练模型
model.fit(X_simple, y)# 预测
X_test = np.linspace(0, 3, 100).reshape(-1, 1)
y_pred = model.predict(X_test)print("\n--- 与Pipeline结合拟合非线性关系 ---")
print("模型在训练集上的R²:", model.score(X_simple, y))
print("多项式系数 (regressor.coef_):", model.named_steps['reg'].coef_)# 示例6:处理DataFrame
df = pd.DataFrame(X, columns=['feat1', 'feat2'])
poly_df = PolynomialFeatures(degree=2, include_bias=False)
X_df_poly = poly_df.fit_transform(df)
df_poly = pd.DataFrame(X_df_poly, columns=poly_df.get_feature_names_out(df.columns))
print("\n--- 处理Pandas DataFrame ---")
print(df_poly)# 示例7:高维特征的注意事项
X_high = np.random.rand(50, 5) # 5个特征
poly_high = PolynomialFeatures(degree=2)
X_high_poly = poly_high.fit_transform(X_high)
print(f"\n--- 高维特征示例 ---")
print(f"原始特征数: {X_high.shape[1]}")
print(f"二次多项式后特征数: {X_high_poly.shape[1]}")
# 组合数公式: C(n+d, d) 其中 n=5, d=2
# 实际包括所有单项和交互项# 示例8:degree=3 时的特征爆炸
poly_high3 = PolynomialFeatures(degree=3)
X_high_poly3 = poly_high3.fit_transform(X_high)
print(f"三次多项式后特征数: {X_high_poly3.shape[1]}")# 总结:PolynomialFeatures 是增强线性模型表达能力的有力工具,
# 但需注意维度爆炸问题,建议配合正则化(如Ridge、Lasso)使用。
上面代码的输出结果示例:
原始数据 X:
[[2. 3.][4. 5.][6. 7.]]--- degree=2(默认)---
多项式特征:
[[ 1. 2. 3. 4. 6. 9.][ 1. 4. 5. 16. 20. 25.][ 1. 6. 7. 36. 42. 49.]]
特征名称: ['1' 'x0' 'x1' 'x0^2' 'x0 x1' 'x1^2']--- 不包含偏置项 ---
无常数列的多项式特征:
[[ 2. 3. 4. 6. 9.][ 4. 5. 16. 20. 25.][ 6. 7. 36. 42. 49.]]
特征名称: ['x0' 'x1' 'x0^2' 'x0 x1' 'x1^2']--- 仅交互项(interaction_only=True)---
仅交互项特征:
[[ 1. 2. 3. 6.][ 1. 4. 5. 20.][ 1. 6. 7. 42.]]
特征名称: ['1' 'x0' 'x1' 'x0 x1']--- degree=3 ---
三次多项式特征:
[[ 1. 2. 3. 4. 6. 9. 8. 12. 18. 27.][ 1. 4. 5. 16. 20. 25. 64. 80. 100. 125.][ 1. 6. 7. 36. 42. 49. 216. 252. 294. 343.]]
特征名称: ['1' 'x0' 'x1' 'x0^2' 'x0 x1' 'x1^2' 'x0^3' 'x0^2 x1' 'x0 x1^2' 'x1^3']--- 与Pipeline结合拟合非线性关系 ---
模型在训练集上的R²: 0.9887540707970783
多项式系数 (regressor.coef_): [0. 1.05030334 0.49002772]--- 处理Pandas DataFrame ---feat1 feat2 feat1^2 feat1 feat2 feat2^2
0 2.000000 3.0 4.00 6.0 9.0
1 4.000000 5.0 16.00 20.0 25.0
2 6.964692 7.0 48.50 48.75 49.0--- 高维特征示例 ---
原始特征数: 5
二次多项式后特征数: 21
三次多项式后特征数: 56
生成多项式特征的使用注意事项
在使用 PolynomialFeatures
生成多项式特征时,虽然能够显著提升模型对非线性关系的拟合能力,但必须注意以下几个关键问题,以避免引入新的风险或降低模型性能。
首先,特征爆炸(维度灾难) 是最突出的问题。多项式特征的数量随原始特征数和阶数呈组合式增长。例如,对于 nnn 个原始特征,生成 ddd 阶多项式后,特征总数为 (n+dd)\binom{n+d}{d}(dn+d)。当 n=10,d=2n=10, d=2n=10,d=2 时,特征数为 66;若 d=3d=3d=3,则增至 286。这不仅大幅增加计算开销和内存占用,还可能导致模型训练缓慢,尤其在大规模数据集上。更严重的是,高维特征空间容易引发过拟合,模型可能过度拟合训练数据中的噪声,导致泛化能力下降。
其次,多重共线性问题显著。多项式特征之间存在高度相关性,例如 xxx 与 x2x^2x2、x1x_1x1 与 x1x2x_1x_2x1x2 等。这种共线性会降低线性模型参数估计的稳定性,使得系数解释变得困难,且模型对数据扰动更加敏感。因此,在使用多项式特征后,强烈建议结合正则化方法,如 Ridge 回归(L2 正则化)或 Lasso 回归(L1 正则化)。Ridge 可以有效缓解共线性问题,而 Lasso 还能实现特征选择,自动剔除不重要的高阶项。
第三,特征缩放的重要性不可忽视。由于多项式特征(如 x2x^2x2)的数值范围通常远大于原始特征,若不进行标准化,模型会过度依赖高阶项,导致优化过程不稳定。因此,在生成多项式特征后,应使用 StandardScaler
或 MinMaxScaler
对整个特征矩阵进行标准化处理,确保所有特征处于相似的数量级。
第四,交互项的解释性降低。虽然 x1x2x_1x_2x1x2 可以捕捉特征间的协同效应,但其物理意义不如原始特征直观。在需要模型可解释性的场景中,应谨慎使用高阶交互项,并通过可视化或特征重要性分析辅助理解。
最后,应根据实际数据和任务需求合理选择 degree
和 interaction_only
参数。并非越高阶越好,通常 degree=2
或 3
已足够。若仅关注特征间相互作用而避免幂运算,可设置 interaction_only=True
以控制特征数量。此外,可通过交叉验证评估不同配置对模型性能的影响,选择最优参数。
综上,生成多项式特征是一把“双刃剑”,应在理解其影响的基础上,结合正则化、标准化和模型验证等手段,谨慎使用。