4. 特征工程入门:特征构造、特征选择、特征缩放
特征工程,说白了就是「喂给模型什么数据」以及「怎么喂」。
我见过太多人,模型调参调得飞起,结果特征一塌糊涂。嗯,这就像你给赛车加再好的机油,轮子却是方的——跑不快的。今天咱们就把特征工程的三个核心环节捋一遍:构造、选择、缩放。
核心观点:特征决定了模型效果的上限,算法只是逼近这个上限。所以,花时间做特征工程,永远值得。
4.1 特征构造:从原始数据中「挖」出新特征
特征构造,就是利用你对业务的理解,从现有字段里组合出新的、更有预测力的特征。说白了,就是「变着法子给模型找新角度」。
我在做信贷风控时遇到过这么个事:原始数据里只有「月收入」和「月支出」两个字段,单独看都不太能区分好坏客户。后来我把它们一除,构造了一个「收入支出比」,这个单特征的IV值直接飙到了0.3以上。你看,有时候就是一层窗户纸。
常见的构造方法
- 组合特征:把两个或多个字段做加减乘除。比如「负债收入比 = 总负债 / 月收入」。
- 聚合特征:对某个维度做统计。比如按用户ID聚合,计算「近3个月平均消费金额」。
- 时间特征:从时间戳里提取「星期几」「是否节假日」「距离上次还款的天数」。
- 文本特征:从备注、描述里提取关键词,或者计算文本长度。
我的小技巧:构造特征时,先列一个「业务假设清单」。比如「我觉得收入高的人还款意愿更强」,那就构造收入相关的特征。别盲目堆砌,否则后面选择阶段会很痛苦。
4.2 特征选择:去粗取精,只留「好」特征
特征构造完了,你可能手里有上百个特征。但别急着全扔进模型——很多特征是冗余的、噪声的,甚至是有害的。
特征选择,就是帮你做减法。我见过一个项目,原始特征200多个,做完选择只剩30个,模型AUC反而从0.72涨到了0.81。为什么?因为冗余特征会引入共线性,干扰模型判断。
三种主流选择方法
| 方法类别 | 代表算法 | 一句话说明 |
|---|---|---|
| 过滤法 | 方差阈值、卡方检验、互信息 | 先算特征与目标的相关性,再排序筛选。速度快,但忽略特征间交互。 |
| 包裹法 | 递归特征消除(RFE)、前向选择 | 把模型当黑盒,反复训练看效果。准确但慢,适合特征数不多的情况。 |
| 嵌入法 | Lasso回归、树模型特征重要性 | 训练过程中自动选择。效率与效果兼顾,我比较常用。 |
⚠️ 我曾经踩过的坑:有一次我用过滤法选了前20个特征,结果模型效果很差。后来发现,有两个特征单独看跟目标相关性很低,但组合起来预测力极强。过滤法会漏掉这种「组合效应」。所以,我建议先用过滤法粗筛,再用嵌入法或包裹法精筛。
4.3 特征缩放:让所有特征「站在同一起跑线」
特征缩放,就是把不同量纲的特征映射到同一个尺度上。你想想看,年龄是0-100,收入是0-100万,如果直接丢进模型,收入会主导距离计算,年龄几乎没贡献。这不合理。
我习惯把特征缩放分成两类:标准化和归一化。很多人搞混,其实区别很简单。
标准化(Standardization)
公式:z = (x - μ) / σ
结果:均值为0,标准差为1。不改变数据分布形状,只是平移缩放。
适用场景:数据近似正态分布,或者模型假设特征服从正态分布(如线性回归、逻辑回归、SVM)。
归一化(Normalization)
公式:x' = (x - min) / (max - min)
结果:缩放到[0, 1]区间。会改变分布形状,把数据压扁。
适用场景:数据分布未知,或者模型对尺度敏感(如KNN、神经网络)。
我的经验法则:
- 树模型(随机森林、XGBoost)—— 不需要缩放,因为树只关心分裂点,不关心尺度。
- 线性模型、SVM、KNN、神经网络 —— 必须缩放,否则模型会「偏科」。
- 如果拿不准,先标准化试试。标准化比归一化更「温和」,保留的信息更多。
代码示例:Python实现
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import pandas as pd
# 假设 df 是你的数据,features 是特征列名列表
features = ['age', 'income', 'credit_score']
# 标准化
scaler_std = StandardScaler()
df[features] = scaler_std.fit_transform(df[features])
# 归一化
scaler_mm = MinMaxScaler()
df[features] = scaler_mm.fit_transform(df[features])
print("标准化后均值:", df[features].mean().round(2))
print("归一化后范围:", df[features].min().values, "~", df[features].max().values)
💡 注意:缩放时,一定要先拆分训练集和测试集,然后在训练集上fit,再transform测试集。千万别对整个数据集一起fit_transform,否则会造成数据泄露,模型效果会被高估。
我刚开始做风控时犯过这个错,上线后模型效果直接腰斩。嗯,从那以后我再也不敢偷懒了。
4.4 三个环节的配合顺序
最后,我总结一下这三个环节的配合顺序:
- 先构造:基于业务理解,生成尽可能多的候选特征。别怕多,后面会选。
- 再选择:用过滤法粗筛,再用嵌入法/包裹法精筛。去掉冗余和噪声。
- 最后缩放:对选出来的特征做标准化或归一化。注意分训练集和测试集。
这个顺序我用了很多年,基本没出过问题。你想想看,如果先缩放再选择,那缩放后的特征分布会被选择过程破坏,等于白做了。
特征工程入门,说白了就是这三板斧。构造是「加法」,选择是「减法」,缩放是「归一法」。把这三步走扎实了,你的模型就已经赢在起跑线上了。
公众号:蓝海资料掘金营,微信deep3321