机器学习:移动阈值

Posted

技术标签:

【中文标题】机器学习:移动阈值【英文标题】:Machine Learning: Move Treshhold 【发布时间】:2018-01-10 00:19:59 【问题描述】:

我正在尝试解决一个二进制分类问题,其中 80% 的数据属于 x 类,20% 的数据属于 y 类。我所有的模型(AdaBoost、神经网络和 SVC)都只是预测所有数据都属于 x 类,因为这是它们可以达到的最高准确度。

我的目标是对 x 类的所有条目实现更高的精度,我不在乎有多少条目被错误分类为 y 类的一部分。

我的想法是,当模型对它们非常确定时将条目放入类 x 中,否则将它们放入类 y 中。

我将如何实现这一目标?有没有办法移动阈值,以便只有非常明显的条目被归类为 x 类?

我正在使用 python 和 sklearn

示例代码:

adaboost = AdaBoostClassifier(random_state=1)
adaboost.fit(X_train, y_train)
adaboost_prediction = adaboost.predict(X_test)

confusion_matrix(adaboost_prediction,y_test) outputs:

array([[  0,   0],
       [10845, 51591]])

【问题讨论】:

【参考方案1】:

使用AdaBoostClassifier,您可以输出类别概率,然后使用predict_proba 代替predict 对它们进行阈值化:

adaboost = AdaBoostClassifier(random_state=1)
adaboost.fit(X_train, y_train)
adaboost_probs = adaboost.predict_proba(X_test)

threshold = 0.8 # for example    
thresholded_adaboost_prediction = adaboost_probs > threshold

使用这种方法,您还可以检查(仅调试打印,或者在图表上排序和绘制)您的最终模型在测试数据上的置信度如何变化,以帮助确定是否值得进一步研究。

不过,有不止一种方法可以解决您的问题。例如,请参阅Miriam Farber's answer,它着眼于重新加权分类器以在训练期间调整您的 80/20 类不平衡。您可能会发现您还有其他问题,包括您使用的分类器可能无法根据您当前的数据实际分离 x 和 y 类。研究像这样的数据问题的所有可能性可能需要几种不同的方法。

如果您对 数据问题(而不是代码)有更多疑问,Stack Exchange 站点和 Stack Overflow 可以为您提供帮助(请在发布前阅读站点指南) :Data Science 和 Cross Validated。

【讨论】:

【参考方案2】:

在 SVM 中,移动阈值的一种方法是选择 class_weight,这样您就可以更加重视来自类 y 的数据点。考虑以下示例,取自SVM: Separating hyperplane for unbalanced classes:

直线是您使用 SVC 和默认类权重(每个类的权重相同)时得到的决策边界。虚线是您在使用class_weight=1: 10 时得到的决策边界(也就是说,相对于 0 类,将更多权重放在第 1 类上)。

类权重基本调整SVM中的惩罚参数:

class_weight : dict, ‘balanced’, 可选

对于 SVC,将第 i 类的参数 C 设置为 class_weight[i]*C。如果不 给定,所有类都应该有权重一。 “平衡” mode 使用 y 的值自动反向调整权重 与输入数据中的类频率成正比为 n_samples / (n_classes * np.bincount(y))

【讨论】:

以上是关于机器学习:移动阈值的主要内容,如果未能解决你的问题,请参考以下文章

机器学习:处理非平衡数据集的办法

机器学习实战-决策树

Andrew Ng机器学习:逻辑回归

机器学习-ROC曲线

机器学习

机器学习系列模型评价ROC曲线约登指数最佳阈值一个函数中实现约登指数计算并集成到ROC图中,给出默认阈值及最佳阈值下的混淆矩阵