lightgbm和xgb如何处理不平衡数据的
ctr,cvr这类2分类问题的样本不平衡性行可想而知的。
而lightgbm和xgb这些分类大杀器在ctr,cvr这类2分类问题中也是常用的,那问题就是这lightgbm和xgb是如何越过样本不平衡问题的?
答案,lightgbm和xgb模型都有is_unbalance=True/False 、scale_pos_weight这两个参数,这两个参数二选一即可解决,
具体来说,is_unbalance和scale_pos_weight都是从改变模型的目标函数,即增大正样本权重,从而间接降低了负样本权重的方式来解决样本不平衡问题的。
具体来说就是is_unbalance=true时,自动将正样本权重设置为
正 样 本 权 重 = 负 样 本 数 量 正 样 本 数 量 正样本权重=\dfrac{负样本数量}{正样本数量} 正样本权重=正样本数量负样本数量
而设置scale_pos_weight值时,
正
样
本
权
重
=
自
定
义
的
s
c
a
l
e
_
p
o
s
_
w
e
i
g
h
t
值
正样本权重=自定义的scale\_pos\_weight值
正样本权重=自定义的scale_pos_weight值。
不信我们就来看源码,
Lightgbm
// weight for label
label_weights_[0] = 1.0f;
label_weights_[1] = 1.0f;
// if using unbalance, change the labels weight
if (is_unbalance_ && cnt_positive > 0 && cnt_negative > 0) {
if (cnt_positive > cnt_negative) {
label_weights_[1] = 1.0f;
label_weights_[0] = static_cast<double>(cnt_positive) / cnt_negative;
} else {
label_weights_[1] = static_cast<double>(cnt_negative) / cnt_positive;
label_weights_[0] = 1.0f;
}
}
label_weights_[1] *= scale_pos_weight_;
可以看到lightGBM通过增加正样本标签的权重,即label_weights_[1] *= scale_pos_weight_;
通过对正样本的权重label_weights_[1] 乘以scale_pos_weight_来增大正样本权重,而不对负样本权重label_weights_[0] 来乘以值,
来处理样本不平衡的问题。
XGBoost
for (omp_ulong i = 0; i < n - remainder; i += 8) {
avx::Float8 y(&info.labels_[i]);
avx::Float8 p = Loss::PredTransform(avx::Float8(&preds_h[i]));
avx::Float8 w = info.weights_.empty() ? avx::Float8(1.0f)
: avx::Float8(&info.weights_[i]);
// Adjust weight
w += y * (scale * w - w);
avx::Float8 grad = Loss::FirstOrderGradient(p, y);
avx::Float8 hess = Loss::SecondOrderGradient(p, y);
avx::StoreGpair(gpair_ptr + i, grad * w, hess * w);
}
xgb中,可以看到源码中的公式:
w += y * (scale * w - w);
也就是说,当y=1,正样本时,w+=(scale * w - w);,其实就是
w=scale * w 。
而当y=0,负样本时,w仍然是原值,w+=0,即w仍然是w.