我正在尝试在非常不平衡的数据集上使用LightGBM构建分类器。不平衡的比例为97:3
,即:
Class
0 0.970691
1 0.029309
我使用的参数和训练代码如下所示。
lgb_params = {
'boosting_type': 'gbdt',
'objective': 'binary',
'metric':'auc',
'learning_rate': 0.1,
'is_unbalance': 'true', #because training data is unbalance (replaced with scale_pos_weight)
'num_leaves': 31, # we should let it be smaller than 2^(max_depth)
'max_depth': 6, # -1 means no limit
'subsample' : 0.78
}
# Cross-validate
cv_results = lgb.cv(lgb_params, dtrain, num_boost_round=1500, nfold=10,
verbose_eval=10, early_stopping_rounds=40)
nround = cv_results['auc-mean'].index(np.max(cv_results['auc-mean']))
print(nround)
model = lgb.train(lgb_params, dtrain, num_boost_round=nround)
preds = model.predict(test_feats)
preds = [1 if x >= 0.5 else 0 for x in preds]
我运行简历来获得最好的模型和最好的回合。我在简历上获得了0.994的AUC,并且在验证集中获得了类似的分数。
但是当我根据测试集进行预测时,我得到的结果非常糟糕。我敢肯定火车的样本是完美的。
需要调整哪些参数?是什么原因造成的?我是否应该对数据集重新采样以减少最高等级??
答案 0 :(得分:8)
问题是,尽管数据集中的类存在极端的不平衡,但是在确定最终的硬分类时,您仍使用“默认”阈值0.5。
preds = [1 if x >= 0.5 else 0 for x in preds]
在这种情况下不是。
这是一个相当大的话题,我强烈建议您进行自己的研究(尝试搜索阈值或切断概率不平衡数据),但是这里有一些指导您入门的指针...
摘自Cross Validated的相关答案(已加强调):
别忘了您应该明智地阈值进行预测。当模型概率大于0.5时,并不总是最好预测1。另一个阈值可能更好。为此,您应该研究分类器的接收器工作特征(ROC)曲线,而不仅仅是具有默认概率阈值的预测成功。
从相关的学术论文Finding the Best Classification Threshold in Imbalanced Classification:
2.2。如何设置测试集的分类阈值
预测 结果 是 最终 决心 根据 至 预测 概率。 的 阈 是 通常 组 至 0.5。 如果 的 预测 可能性 超过 0.5, 的 样品 是 预料到的 至 是 正; 除此以外, 负。 然而, 0.5 是 不 理想 对于 一些 情况 尤其 对于 不平衡的 数据集。
(强烈推荐)“应用预测建模”博客中的帖子Optimizing Probability Thresholds for Class Imbalances也与此相关。
从以上所有内容中吸取教训:AUC很少,但是ROC曲线本身通常是您最好的朋友...
在更一般的层面上,关于阈值本身在分类过程中的作用(至少根据我的经验,很多从业者会出错),还请检查Classification probability threshold线程(以及提供的链接)在交叉验证时;重点:
当您为新样本的每个类别输出概率时,练习的统计部分结束。选择一个阈值以将新观察值分类为1 vs. 0不再是统计的一部分。它是决定组件的一部分。