机器学习建模中的样本加权

写在最前:样本加权与过采样/欠采样的本质目的基本一致,都是为了有侧重的学习样本,以期提升模型效果

一、为什么加权?

1. 业务需求

(1) 业务有侧重产品

业务角度可以将样本分类,业务未来发展方向更关注某种类别的样本,则加重该类别样本权重

(2) 样本由多个不同分布来源组成

比如样本包含多个分布不同的客群

2. 数据角度

(1) 训练集y分布不均衡

一般加重样本量较少的y类别的样本学习

(2) 训练集与验证集/测试集分布不一致

此时交叉验证无法改善过拟合情况。需要加重与验证集相似部分样本的学习

3. 模型角度

为提升模型训练效果,对某些样本加权。例如adaboost侧重某些错分样本权重

二、加权方案确定

从以下几个出发点考虑:

1. 业务角度考虑:

(1) 时间因素

例如风控背景的评分卡模型注重模型的时间外效果,要求模型的风控能力不能随时间偏移过多。显然近期样本与未来样本的相似度较高,则此时可根据时间的远近对样本加权,加重近期样本的学习

(2) 业务需求

例如,基于3个场景的样本构造一个通用模型时,如果业务发展偏重于某个场景,则可以适当加重该场景的样本权重

(3) 样本本身分布差异

实际应用中,建模训练样本可能包含多个客群。例如,基于3家商户的样本建模时,如果某家商户与其他商户样本分布不一致(体现在样本量分月统计、好坏分布、标签指标测试结果等),可根据具体分布差异情况加权。

2. 数据角度考虑:

(1) 训练样本y不均衡

根据样本的y值对样本加权,效果与各种过采样、欠采样方法等同。

(2) 另建模型学习最适权重

可参考对抗验证(Adversarial Validation),加重与验证集/测试集相似样本的学习

''' 对抗验证实现样本加权 '''

# step1. 设置新y,train中样本的y值为0,test中样本的y值为1
df_train['Is_Test'] = 0
df_test['Is_Test'] = 1

# step2. 将train、test两个数据集合并
df_adv = pd.concat([df_train, df_test])

# step3. 通过分类模型拟合新y。注意这里的分类模型AUC越高,说明train/val的分布差异越大
model_adv.fit(df_adv.drop('Is_Test', axis=1), df_adv.loc[:, 'Is_Test'])

# step4. 分类模型对train样本作预测,得到train中各样本与test样本的相似概率
preds_adv = model_adv.predict_proba(df_adv.drop('Is_Test', axis=1))[:, 1]

# step5. 用概率值对train中样本加权,这里以lightGBM为例
train_set = lgb.Dataset(
            df_train.drop('target', axis=1),
            label=df_train.loc[:, 'target'], weight=preds_adv[:len(df_train)])

2. 模型角度考虑

(1) 代价敏感学习

损失函数步骤上加权
比如损失函数中设置坏样本权重高,则坏样本命中少时,代价高;
比如类似于adaboost思路,所有训练样本中,设置错分样本权重高,则错分时,代价高。则模型后期迭代会更偏向于错分样本的学习

最终的加权方案可综合上述因素确定

注意:

  1. 加权的本质都是为了有侧重的学习样本,以期提升模型效果
  2. 加权会改变训练集原有分布,是否应该加权存在争议
  3. 业务角度确定加权方案的可解释性强,但不一定取得较好的模型结果。实际应用时还是偏向于多尝试权重方案;
  4. 加权样本训练模型完毕后,是否需要模型校准?即,评估模型指标时是否需要还原原始样本权重再计算,以期还原真实数据上模型的指标?该问题存在争议

三、加权实现

  1. python的imblearn包作采样
  2. 一般的机器学习算法包中都带有权重参数
    sklearn的fit中sample_weight

具体有时间再补充

参考1:样本权重对逻辑回归评分卡的影响探讨
参考2:对抗验证
参考3:不平衡处理:xgboost 中scale_pos_weight、给样本设置权重weight、 自定义损失函数 和 简单复制正样本的区别

你可能感兴趣的:(机器学习)