特征工程:数值特征标准化、类别特征编码、特征选择与降维(PCA)
特征工程这步,说白了就是把原始数据变成模型爱吃的东西。我早年做风控模型时,吃过不少亏:直接拿原始数值灌进模型,结果某个字段因为量级太大,把其他字段全压死了。后来我老老实实走一遍标准化,效果立马不一样。
这一章咱们把四个核心环节撸一遍:数值特征标准化、类别特征编码、特征选择、PCA降维。注意,这不是流水线必须全走——具体用哪个,得看数据长啥样、模型是什么。
数值特征标准化
异常评分模型对特征量级特别敏感。如果年龄(0~100)和交易金额(0~10万)一起喂给模型,模型几乎只看到金额。我习惯先做Z-score标准化,公式很简单:
z = (x - μ) / σ
μ是均值,σ是标准差。标准化后数据均值为0,方差为1。这种方法假设数据大致正态,如果数据有极端异常值,记得加裁剪或者用RobustScaler(基于分位数)。
另一种是MinMax归一化:
scaled = (x - min) / (max - min)
把数据压缩到[0,1]区间。适合分布边界明确的特征,比如比例、评分。不过注意,如果有新数据超出训练集范围,会越界。
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Z-score | 分布大致正态,无极端离群 | 不受量纲影响 | 对离群点敏感 |
| MinMax | 边界已知,无离群 | 压缩到固定区间 | 新数据可能越界 |
| Robust | 存在离群点 | 鲁棒性好 | 对分位数选择敏感 |
类别特征编码
类别字段比如“城市”、“用户等级”,没法直接进模型。我建议按这类方式处理:
- 独热编码(One-Hot):每个取值变成一列0/1。类别少(比如不到20个)时首选。但注意:如果类别太多(比如邮编),独热编码会把维度撑爆。
- 标签编码(Label Encoding):给每个类别赋一个整数。对树模型没问题,但对线性模型和基于距离的模型会造成“有序假象”——比如“高=2,中=1,低=0”可能被模型误认为线性关系。
- 目标编码(Target Encoding):用类别对应的目标均值来替代。在异常评分中,可以用该类别样本的异常率来编码。效果好,但容易过拟合,建议配合交叉验证做平滑。
我记得有一次做电商反作弊,类别特征“设备型号”有上千种,独热编码根本行不通。后来用目标编码,配合5折交叉验证,效果出奇好。
# 目标编码示例(Python伪代码)
from sklearn.model_selection import KFold
import numpy as np
def target_encode(train, col, target, k=5):
kf = KFold(n_splits=k, shuffle=True)
encoded = np.zeros(len(train))
for train_idx, val_idx in kf.split(train):
train_fold = train.iloc[train_idx]
val_fold = train.iloc[val_idx]
mean_map = train_fold.groupby(col)[target].mean()
encoded[val_idx] = val_fold[col].map(mean_map).values
return encoded
特征选择
特征不是越多越好。冗余特征会增加噪声、降低泛化能力、拖慢训练。我常用的方法有三种:
- 方差选择法:去掉方差接近于0的特征——比如几乎全一样的字段,对模型毫无贡献。
- 卡方检验 / 互信息:计算每个特征与目标变量的相关性,保留得分高的。异常评分中,互信息比卡方更通用(不限于分类)。
- 基于模型的选择(SelectFromModel):用随机森林或L1惩罚的逻辑回归训练一次,看特征权重。权重接近0的直接丢掉。
我个人习惯先做一波“粗筛”去掉明显无用的特征,再用模型权重做“精筛”。做粗筛时,我会检查缺失率超过90%的字段——直接删掉,不犹豫。
PCA降维
当特征维度很高(比如图像像素、文本词袋),或者特征之间高度线性相关,PCA就派上用场了。它通过正交变换,把数据映射到几个“主成分”上,每个主成分都是原始特征的线性组合。
PCA的目标是保留最大的方差。第一个主成分捕获最大方差方向,第二个在正交方向捕获次大方差……你可以指定保留多少方差比例,比如95%,然后自动选择主成分个数。
from sklearn.decomposition import PCA
# 假设 X 已标准化
pca = PCA(n_components=0.95) # 保留95%方差
X_pca = pca.fit_transform(X)
print(f"原始维度: {X.shape[1]}, 降维后: {X_pca.shape[1]}")
注意,PCA对特征量级非常敏感,必须先做标准化。我有一回把标准的顺序搞反了——先PCA再标准化,结果主成分完全不对,折腾了一天才发现是顺序问题。
好了,这四个环节讲完了。实际项目中,我一般这样组合:数值特征标准化(Robust如果区间稳定就Z-score)+ 类别特征目标编码(避免独热爆维)+ 方差+模型特征选择(暴力剔除零贡献特征)+ 如果维度仍高(>100),再补一个PCA。调优时盯着交叉验证的AUC看,别光看特征数减少了就开心。