特征工程

特征工程是把原始数据转换为模型可学习信号的过程。目标不是盲目增加字段,而是用稳定、可解释且可复现的方式表达与任务相关的信息,同时避免数据泄漏。

标准流程

1
2
3
4
5
6
7
8
9
flowchart LR
A[原始数据] --> B[数据剖析]
B --> C[清洗与缺失处理]
C --> D[特征构造]
D --> E[编码与缩放]
E --> F[特征选择]
F --> G[训练与交叉验证]
G --> H[线上特征服务]
H --> I[漂移监控]

常用处理方法

数值特征

  • 缺失值可使用中位数、分组统计量或模型方法填补,并增加缺失指示字段。
  • 偏态分布可使用对数变换或分位数变换。
  • 对距离敏感的模型可执行标准化或归一化,树模型通常不依赖缩放。
  • 极端值应结合业务规则截断,不宜仅凭统计阈值删除。

类别特征

低基数类别适合独热编码。高基数类别可使用频次编码、哈希编码或带交叉验证的目标编码。未知类别必须有稳定的兜底值,避免线上推理失败。

时间与文本特征

时间字段可拆分为小时、星期、月份和节假日,也可计算距上次事件的间隔。文本可使用词频、TF-IDF、预训练向量或领域模型表示。所有统计特征都必须只使用预测时刻之前可获得的数据。

防止数据泄漏

数据泄漏指训练阶段使用了真实预测时刻无法获得的信息。常见来源包括先对全量数据缩放再划分训练集、使用未来窗口聚合、把结果字段的衍生值作为输入,以及对全量标签执行目标编码。正确做法是先划分数据,再仅在训练集上拟合转换器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

numeric = Pipeline([
("imputer", SimpleImputer(strategy="median")),
("scaler", StandardScaler()),
])
categorical = Pipeline([
("imputer", SimpleImputer(strategy="most_frequent")),
("encoder", OneHotEncoder(handle_unknown="ignore")),
])
preprocessor = ColumnTransformer([
("numeric", numeric, ["age", "amount"]),
("categorical", categorical, ["region", "channel"]),
])

特征选择与上线检查

过滤法使用相关性、互信息或统计检验快速筛选。包装法以模型效果为依据迭代选择,计算成本较高。嵌入法利用线性模型正则化或树模型重要性完成选择。上线前应确认训练与推理使用同一份转换逻辑,检查缺失率和未知类别策略,并记录特征版本、数据版本与模型版本。