机器学习:移动Treshhold

时间:2017-08-02 16:40:52

标签: python machine-learning scikit-learn data-science

我正在尝试解决二进制分类问题,其中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]])

2 个答案:

答案 0 :(得分:4)

使用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 ScienceCross Validated

答案 1 :(得分:2)

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

enter image description here

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

类权重在SVM

中修改惩罚参数
  

class_weight:{dict,'balanced'},可选

     

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