阅读鱼佬《机器学习算法竞赛实战》4.3节记录,主要记录如何对类别相关统计特征进行 目标编码
机器学习难以识别复杂模式,尤其是不同特征间交互信息,因此需要根据直觉或业务理解构建特征。
针对类别相关统计特征,可考虑:
- 目标编码
- 考虑 类别特征 和 目标变量
- count, nunique, ratio
- 经常使用的类别特征构造方式
- 类别特征交叉组合
- 类别特征间的组合
目标编码
目标编码是用目标变量(通常是Label)统计量对类别特征进行编码。对不同问题:
- 分类:正、负样本个数,正负样本比例
- 回归:统计目标变量的均值、中位数、最值
直观的理解:对类别特征进行分组,每组利用目标变量的统计量替换(map)该类别分组。
pandas 表示: df.group('类别特征')['目标变量'].聚合操作
书中给出的示例代码如下:
folds = KFold(n_splits=5, shuffle=True, random_state=2020)
for col in columns:
colname = col+'_kfold'
# 5折交叉验证
for fold_, (trn_idx, val_idx) in enumerate(folds.split(train)):
tmp = train.iloc[trn_idx]
order_label = tmp.groupby([col])['label'].mean()
train[colname] = train[col].map(order_label)
......
# 处理 test 中类别特征数据
order_label = train.groupby([col])['label'].mean()
test[colname] = test[col].map(order_label)
分析:
- 在5折交叉验证中,用另外四分样本计算目标变量(label)的统计量,防止信息泄露。即
order_label = tmp.groupby([col])['label'].mean()
,注意此时是tmp
。之后对进行类别特征替换时,val
也要做相应处理,即train[colname] = train[col].map(order_label)
。 - 处理
test
数据时,对整个train
分组聚合。 - 示例是针对回归问题统计目标变量的均值。针对分类问题,如统计正负样本比例可写为
order_label = tmp.groupby([col])['label'].agg(lambda x: x.sum() / (1-x).sum())
。
其他
关于 count, nunique, ratio
三个统计指标,书中给出较好的例子理解:count(计数特征)用于统计类别特征的出现频次。nunique和ratio 的构造相对复杂一些,经常会涉及多个类别特征的联合构造,例如在广告点击率预测问题中,对于用户 ID 和广告 ID,使用 nunique可以反映用户对广告的兴趣宽度,也就是统计用户 ID 看过几种广告 ID;使用 ratio 可以反映用户对某类广告的偏好程度,也就是统计用户 ID 点击某类广告 ID 的频次占用户点击所有广告ID 频次的比例。
类别特征交叉组合:注意类别基数即可,不做赘述