9

我正在尝试在非常不平衡的数据集上使用 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]

我运行 CV 以获得最佳模型和最佳回合。我在 CV 上得到了 0.994 AUC,在验证集中得到了相似的分数。

但是当我在测试集上进行预测时,我得到了非常糟糕的结果。我确信火车组是完美采样的。

需要调整哪些参数?问题的原因是什么。?我应该重新采样数据集以减少最高级别吗?

4

1 回答 1

11

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

preds = [1 if x >= 0.5 else 0 for x in preds]

这里应该是这种情况。

这是一个相当大的话题,我强烈建议您进行自己的研究(尝试谷歌搜索阈值切断概率不平衡数据),但这里有一些提示可以帮助您入门......

交叉验证的相关答案(强调添加):

不要忘记您应该智能地设定阈值以进行预测。当模型概率大于 0.5 时,预测 1 并不总是最好的。另一个阈值可能会更好。为此,您应该查看分类器的接收器操作特征 (ROC) 曲线,而不仅仅是使用默认概率阈值预测成功。

来自相关学术论文,Finding the Best Classification Threshold in Imbalanced Classification

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

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

(强烈推荐)应用预测建模博客中的优化类不平衡的概率阈值一文也很相关

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


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

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

于 2018-07-05T13:33:14.293 回答