ADJ*_*ADJ 62 python classification machine-learning scikit-learn
我正在研究不平衡类(5%1)的分类问题.我想预测班级,而不是概率.
在二进制分类问题中,scikit 默认classifier.predict()
使用0.5
?如果没有,那么默认方法是什么?如果是,我该如何更改?
在scikit中,一些分类器可以class_weight='auto'
选择,但并非所有分类器都可以.有class_weight='auto'
,会.predict()
用实际人口比例作为门槛吗?
在像MultinomialNB
这样的分类器中不支持的方法是class_weight
什么?除了使用predict_proba()
然后自己计算类.
Fre*_*Foo 38
是scikit
classifier.predict()
默认使用0.5?
在概率分类器中,是的.正如其他人所解释的那样,这是数学观点上唯一明智的门槛.
在像MultinomialNB这样不支持的分类器中,这样做的方法是什么
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])
Run Code Online (Sandbox Code Playgroud)
den*_*son 30
对于二元分类,scikit学习中的阈值为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
Run Code Online (Sandbox Code Playgroud)
Yuc*_*ang 29
可以使用设置阈值 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
Run Code Online (Sandbox Code Playgroud)
你似乎在这里混淆概念.阈值不是"通用分类器"的概念 - 最基本的方法基于一些可调阈值,但是大多数现有方法创建了复杂的分类规则,这些规则不能(或至少不应该)被视为阈值.
所以首先 - 一个人无法回答你的问题scikit的分类器默认阈值,因为没有这样的事情.
第二类加权不是关于阈值,关于分类器处理不平衡类的能力,它是依赖于特定分类器的东西.例如 - 在SVM情况下,它是在优化问题中加权松弛变量的方法,或者如果您愿意,则是与特定类相关联的拉格朗日乘数值的上限.将其设置为"auto"意味着使用一些默认启发式,但再一次 - 它不能简单地转换为某些阈值.
另一方面,朴素贝叶斯直接估计训练集中的类概率.它被称为"类优先",您可以使用"class_prior"变量在构造函数中设置它.
从文档:
类的先验概率.如果指定,则不根据数据调整先验.
小智 6
如果有人访问此线程希望获得现成可用的函数(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
Run Code Online (Sandbox Code Playgroud)
欢迎批评/修改。希望它在极少数情况下有所帮助,即类别平衡无法实现并且数据集本身高度不平衡。
归档时间: |
|
查看次数: |
52086 次 |
最近记录: |