Python scikit learn.predict()默认阈值

Python scikit learn.predict()默认阈值,python,machine-learning,classification,scikit-learn,Python,Machine Learning,Classification,Scikit Learn,我正在研究一个不平衡类的分类问题(5%1)。我想预测课程,而不是概率 在二进制分类问题中,scikit的分类器.predict()默认使用0.5? 如果没有,默认的方法是什么?如果是,我该如何更改它 在scikit中,一些分类器具有class\u weight='auto'选项,但并非所有分类器都具有该选项。使用class\u weight='auto',是否将.predict()使用实际人口比例作为阈值 在像多项式nb这样的不支持类权重的分类器中,该怎么做?除了使用predict_proba(

我正在研究一个不平衡类的分类问题(5%1)。我想预测课程,而不是概率

在二进制分类问题中,scikit的
分类器.predict()
默认使用
0.5
? 如果没有,默认的方法是什么?如果是,我该如何更改它

在scikit中,一些分类器具有
class\u weight='auto'
选项,但并非所有分类器都具有该选项。使用
class\u weight='auto'
,是否将
.predict()
使用实际人口比例作为阈值


在像
多项式nb
这样的不支持
类权重的分类器中,该怎么做?除了使用
predict_proba()
然后自己计算类之外。

您似乎在这里混淆了概念。阈值不是“通用分类器”的概念-最基本的方法基于一些可调阈值,但大多数现有方法创建复杂的分类规则,不能(或至少不应该)将其视为阈值

因此,首先,我们无法回答您关于scikit的分类器默认阈值的问题,因为没有这样的问题

第二类权重不是关于阈值,而是关于分类器处理不平衡类的能力,它取决于特定的分类器。例如,在支持向量机的情况下,这是一种在优化问题中加权松弛变量的方法,或者如果您愿意,也可以是与特定类相关的拉格朗日乘数值的上界。将其设置为“自动”意味着使用一些默认的启发式,但再一次-它不能简单地转换为一些阈值

另一方面,朴素贝叶斯直接从训练集中估计类概率。它被称为“class Previor”,您可以使用“class_Previor”变量在构造函数中设置它

从:

类的先验概率。如果指定,则不会根据数据调整优先级

scikit的分类器.predict()是否默认使用0.5


在概率分类器中,是的。正如其他人所解释的那样,从数学角度来看,这是唯一合理的阈值

在不支持
class\u-weight
的多项式nb这样的分类器中,该怎么做

您可以设置
class_prior
,它是每个class y的先验概率p(y)。这实际上改变了决策边界。例如

# minimal dataset
>>> X = [[1, 0], [1, 0], [0, 1]]
>>> y = [0, 0, 1]
# use empirical prior, learned from y
>>> MultinomialNB().fit(X,y).predict([1,1])
array([0])
# use custom prior to make 1 more likely
>>> MultinomialNB(class_prior=[.1, .9]).fit(X,y).predict([1,1])
array([1])

scikit学习中的阈值对于二元分类是0.5,对于多类分类,无论哪个类具有最大的概率。在许多问题中,通过调整阈值可以获得更好的结果。然而,这必须小心进行,而不是对坚持测试数据,而是对培训数据进行交叉验证。如果您对测试数据进行任何阈值调整,那么您只是过度拟合了测试数据

大多数调整阈值的方法都基于and,但也可以通过其他方法(如使用遗传算法进行搜索)进行调整

以下是一篇同行评议杂志文章,描述了在医学中的这一做法:

据我所知,目前还没有用Python进行搜索的软件包,但用Python进行蛮力搜索相对简单(但效率低下)

这是一个R代码

## load data
DD73OP <- read.table("/my_probabilites.txt", header=T, quote="\"")

library("pROC")
# No smoothing
roc_OP <- roc(DD73OP$tc, DD73OP$prob)
auc_OP <- auc(roc_OP)
auc_OP
Area under the curve: 0.8909
plot(roc_OP)

# Best threshold
# Method: Youden
#Youden's J statistic (Youden, 1950) is employed. The optimal cut-off is the threshold that maximizes the distance to the identity (diagonal) line. Can be shortened to "y".
#The optimality criterion is:
#max(sensitivities + specificities)
coords(roc_OP, "best", ret=c("threshold", "specificity", "sensitivity"), best.method="youden")
#threshold specificity sensitivity 
#0.7276835   0.9092466   0.7559022
##加载数据

DD73OP以防有人访问此线程,希望使用现成的函数(python 2.7)。在本例中,截断旨在反映原始数据集中事件与非事件的比率df,而y\u prob可能是.predict\u proba方法的结果(假设分层训练/测试分割)


请随意批评/修改。希望在很少情况下,当类平衡不存在问题且数据集本身高度不平衡时,它会有所帮助。

可以使用
clf.predict\u proba()

例如:

from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(random_state = 2)
clf.fit(X_train,y_train)
# y_pred = clf.predict(X_test)  # default threshold is 0.5
y_pred = (clf.predict_proba(X_test)[:,1] >= 0.3).astype(bool) # set threshold as 0.3

让我以不同的方式解释一下,然后可以自由地说,我仍然感到困惑:-)。假设我有两门课。大多数分类器都会预测概率。我可以使用概率来评估我的模型,比如使用ROC。但是如果我想预测一个类,我需要选择一个截止值,比如说0.5,然后说“每一个p0.5的观察结果都进入第1类。如果你的先验值是0.5-0.5,这通常是一个不错的选择。但是对于不平衡的问题,我需要一个不同的截止值。我的问题是,当使用.predict()时,scikit是如何处理这个截止值的。大多数分类器不是概率分类器。它们能够以某种方式“积”此概率(估计)并不意味着它们实际上“使用它”进行预测。这就是为什么我将此称为可能混淆。预测调用原始模型用于进行预测的例程,它可以是概率(NB)、几何(SVM),基于回归(NN)或基于规则(树),因此predict()中的概率值问题似乎是概念上的混乱。@lejlot,如果是这样的话,那么用predict_proba绘制的roc曲线的整个概念不是也变得无关紧要了吗?在不同阈值绘制的roc曲线的不同点不适用于predict_proba的结果吗?似乎没有RandomForestClassifier的类优先权。如何进行这?RandomForestClassifier没有class_Previor参数,但它有一个class_weight参数,可以使用。实际上,0.5默认值是任意的,不必是最优的,例如,谁是被切除的机构。”在概率分类器中,是的。正如其他人所解释的那样,从数学的角度来看,这是唯一合理的阈值。”-这似乎完全偏离了基准。例如,如果你想将回忆的权重置于精确度之上,该怎么办?很棒的帖子!最重要的一点是:“如果你对测试数据的阈值进行任何调整,那你就太过合适了。”
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(random_state = 2)
clf.fit(X_train,y_train)
# y_pred = clf.predict(X_test)  # default threshold is 0.5
y_pred = (clf.predict_proba(X_test)[:,1] >= 0.3).astype(bool) # set threshold as 0.3