如何在pandas DataFrame中基于现有列生成衍生列以适配Lasso回归特征构造
Lasso 非线性特征构造可运行实现
你原代码无法运行的核心问题有三点:
df.iteritems()遍历返回的是(列名, 列值Series)格式的元组,直接拿遍历返回的元组当列索引取值会触发类型错误,根本无法完成赋值- 全量无序双重循环会重复生成「特征i特征j」和「特征j特征i」的完全相同的列,既冗余又容易触发列名重名冲突
- 没有按照统一规则生成唯一列名,后续传入Sklearn训练时很容易因为列名重复触发索引错误
方式1:Sklearn内置特征生成器(最适配Lasso建模流程)
完全不需要手写循环,自动完成特征组合、列名生成,零冗余:
from sklearn.preprocessing import PolynomialFeatures import pandas as pd # 初始化特征生成器:关闭常数偏置,degree=2覆盖所有二次组合 poly = PolynomialFeatures(degree=2, include_bias=False) # 传入原始19列预测变量数据 feature_array = poly.fit_transform(df2) # 自动生成全局唯一的规范列名 feature_columns = poly.get_feature_names_out(df2.columns) # 转成标准DataFrame可直接传入Lasso模型训练 df3 = pd.DataFrame(feature_array, columns=feature_columns, index=df2.index)
列数核对:J=19时,这套设置生成的内容包含19个原始线性项、19个单变量平方项、171个无重复的两两交叉交互项,总列数209。如果你只需要171个纯交叉交互项、不需要原始项和平方项,可将参数调整为
interaction_only=True后再筛选掉原始特征列即可,和你最初的列数目标完全匹配。
小提示:生成完所有特征后,接入Lasso前记得做标准化处理,否则不同量纲的特征会直接影响Lasso的惩罚项计算结果,导致系数估计偏差。
方式2:手写循环实现(适配自定义列名规则需求)
如果需要自定义列名格式,修正遍历逻辑后的循环代码完全可达到预期效果:
df3 = pd.DataFrame(index=df2.index) col_list = list(df2.columns) # 仅遍历无重复的特征对,避免重复计算 for i in range(len(col_list)): for j in range(i, len(col_list)): # 按自定义规则生成唯一列名,杜绝重名问题 new_col = f"{col_list[i]}__mul__{col_list[j]}" df3[new_col] = df2[col_list[i]] * df2[col_list[j]]
这套逻辑下,19个特征生成的i<j交叉项刚好为171列,列名自动按规则生成,不需要手动维护命名逻辑。
内容的提问来源于stack exchange,提问作者Nish
相关产品推荐
相关产品推荐

