我正在尝试解决二进制分类问题,其中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]])
答案 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 Science和Cross Validated。
答案 1 :(得分:2)
在SVM中,移动阈值的一种方法是选择class_weight
,以便更加重视来自类y
的数据点。请考虑以下示例,取自SVM: Separating hyperplane for unbalanced classes:
直线是您使用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))