scikit .predict()默认阈值
classification
machine-learning
python
scikit-learn
4
0

我正在处理不平衡类(5%1)的分类问题。我想预测班级,而不是概率。

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

在scikit中,某些分类器具有class_weight='auto'选项,但并非所有分类器都具有。使用class_weight='auto' ,. class_weight='auto' .predict()将实际人口比例用作阈值?

什么是像一个分类,以做到这一点的方式MultinomialNB不支持class_weight ?除了使用predict_proba()然后自己计算类之外。

参考资料:
Stack Overflow
收藏
评论
共 6 个回答
高赞 时间 活跃

0.5与人口比例没有任何关系。它是一个概率输出。没有“阈值”,如果一个类别的概率为0.51,则它似乎是最可能的类别。如果始终使用0.5,则应使用*,并且没有软件包使用其他“阈值”。如果您的概率分数是*准确且真正具有代表性的*,则您必须始终选择最可能的类别 。否则只会降低您的准确性。由于我们使用各种进行假设的算法,因此我们不知道概率为真-但您会违背模型所做的假设。

感到困惑的class_weight做什么。更改类权重会增加表示较少的类中数据点的权重(/对于表示过多的类则减小),以使每个类的“权重”相等-好像它们具有相同数量的正例和负例。这是尝试避免始终为最常见类别投票的分类器的常见技巧。因为这样,从学习算法的角度来看,这两个类都是相同的。

  • 注意:如果您担心误报/误报,则可以选择仅在某类的概率达到某个最小值时接受。但这并不会改变学习的方式,也不会改变概率背后的含义。
收藏
评论

如果有人访问此线程,希望可以使用现成的功能(python 2.7)。在此示例中,截止值设计为反映原始数据集df中事件与非事件的比率,而y_prob可能是.predict_proba方法的结果(假设分层训练/测试拆分)。

def predict_with_cutoff(colname, y_prob, df):
    n_events = df[colname].values
    event_rate = sum(n_events) / float(df.shape[0]) * 100
    threshold = np.percentile(y_prob[:, 1], 100 - event_rate)
    print "Cutoff/threshold at: " + str(threshold)
    y_pred = [1 if x >= threshold else 0 for x in y_prob[:, 1]]
    return y_pred

随时批评/修改。希望在少数情况下无法解决类平衡并且数据集本身高度不平衡的情况提供帮助。

收藏
评论

默认情况下,scikit的classifier.predict()使用0.5?

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

在不支持class_weight类的分类器中,如何做到这class_weight

您可以设置class_prior ,它是每个类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 learning的阈值为0.5,而对多分类进行分类的可能性最大的一个分类。在许多问题中,通过调整阈值可以获得更好的结果。但是,这必须谨慎进行,而不是对保留测试数据,而应对训练数据进行交叉验证。如果您对测试数据的阈值进行了任何调整,那么您只是在过度拟合测试数据。

调整阈值的大多数方法都是基于接收器工作特性(ROC)Youden的J统计量,但也可以通过其他方法来完成,例如使用遗传算法进行搜索。

这是一篇同行评议期刊文章,描述了在医学领域中的用法:

http://www.ncbi.nlm.nih.gov/pmc/articles/PMC2515362/

据我所知,没有在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
收藏
评论

可以使用clf.predict_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
收藏
评论

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

因此,首先-无法回答scikit的分类器默认阈值的问题,因为没有此类问题。

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

另一方面,朴素贝叶斯(Naive Bayes) 直接从训练集中估计班级概率。它称为“类优先”,您可以在构造函数中使用“ class_prior”变量进行设置。

文档中

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

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号