机器学习:移动阈值
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))
【讨论】:
以上是关于机器学习:移动阈值的主要内容,如果未能解决你的问题,请参考以下文章
机器学习系列模型评价ROC曲线约登指数最佳阈值一个函数中实现约登指数计算并集成到ROC图中,给出默认阈值及最佳阈值下的混淆矩阵