高AUC但数据不平衡的预测结果不佳

Sre*_* TP 9 python classification machine-learning auc lightgbm

我正在尝试在非常不平衡的数据集上使用LightGBM构建分类器.不平衡是比例97:3,即:

Class

0    0.970691
1    0.029309
Run Code Online (Sandbox Code Playgroud)

我使用的参数和培训代码如下所示.

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]
Run Code Online (Sandbox Code Playgroud)

我运行简历以获得最佳模型和最佳轮次.我在CV上获得了0.994 AUC,在验证集中获得了类似的分数.

但是当我在测试集上预测时,我的结果非常糟糕.我确信火车组的样品完美无缺.

需要调整哪些参数.问题的原因是什么?我应该重新采样数据集,以便降低最高级别.

des*_*aut 9

问题在于,尽管数据集中的类极不平衡,但在决定最终的硬分类时,您仍然使用0.5的"默认"阈值

preds = [1 if x >= 0.5 else 0 for x in preds]
Run Code Online (Sandbox Code Playgroud)

这应该不是这里的情况.

这是一个相当大的话题,我强烈建议你做自己的研究(尝试谷歌搜索阈值切断概率不平衡数据),但这里有一些指导,让你开始......

来自Cross Validated的相关答案(重点补充):

不要忘记你应该智能地进行阈值处理以进行预测.当模型概率大于0.5时,预测1并不总是最好的.另一个门槛可能更好.为此,您应该查看分类器的接收器操作特性(ROC)曲线,而不仅仅是其具有默认概率阈值的预测成功.

从相关的学术论文中,找出不平衡分类中的最佳分类阈值:

2.2.如何设置测试集的分类阈值

预测结果最终根据预测概率确定.阈值通常设置为0.5.如果预测概率超过0.5,则预测样本为正; 否则,否定.但是,对于某些情况,0.5并不理想,特别是对于不平衡的数据集.

该职位的类别不平衡优化概率阈值从(强烈推荐)应用预测建模博客也有关.

从以上所有内容中吸取教训:AUC很少,但ROC 曲线本身往往是你最好的朋友......


关于阈值本身在分类过程中的作用(根据我的经验,至少许多从业者出错),在更一般的层面上,还要检查Cross Validated中的分类概率阈值线程(和提供的链接); 关键点:

当您为新样本的每个类输出概率时,练习的统计部分结束.选择一个阈值,超过该阈值,您将新观察分类为1对0不再是统计数据的一部分.它是决策部分的一部分.