如何基于ROC结果为sklearn分类器设置阈值?

19
我使用scikit-learn训练了一个ExtraTreesClassifier(基尼指数),并且它基本符合我的需求。准确度不是很高,但使用10倍交叉验证,AUC为0.95。我想在我的工作中使用这个分类器。我对机器学习还比较新,如果我问错了什么,请原谅我。
我绘制了一些ROC曲线,通过它,似乎我有一个特定的阈值,我的分类器开始表现良好。我想将这个值设置在拟合的分类器上,这样每次我调用预测时,分类器都会使用该阈值,我可以相信FP和TP率。
我还看到了这篇文章(scikit .predict() default threshold),其中指出阈值不是分类器的通用概念。但由于ExtraTreesClassifier具有predict_proba方法,并且ROC曲线也与阈值定义相关,因此我应该可以指定它。
我没有找到任何参数或任何可用于此目的的类/接口。我如何为已训练的ExtraTreesClassifier(或任何其他分类器)在scikit-learn中设置阈值?
非常感谢, Colis
2个回答

20

这是我所完成的:

model = SomeSklearnModel()
model.fit(X_train, y_train)
predict = model.predict(X_test)
predict_probabilities = model.predict_proba(X_test)
fpr, tpr, _ = roc_curve(y_test, predict_probabilities)

然而,我很不爽predict选择一个对应于真正例0.4%的阈值(伪正例为零)。ROC曲线显示我更喜欢的阈值适用于我的问题,其中真正例约为20%(伪正例约为4%)。然后我扫描predict_probabilities以查找与我喜欢的ROC点对应的概率值。在我的情况下,这个概率是0.21。然后我创建自己的predict数组:

predict_mine = np.where(rf_predict_probabilities > 0.21, 1, 0)

就是这样:

confusion_matrix(y_test, predict_mine)

返回我想要的内容:

array([[6927,  309],
       [ 621,  121]])

2
请注意,由于阈值是基于测试数据选择的,导致了数据泄露,因此产生的混淆矩阵不是适用于样本外性能的正确指标。正确的方法是将数据分成训练/验证/测试集。使用训练数据训练分类器,使用验证数据选择阈值,然后使用测试集评估最终模型(包括阈值)。 - Philipp
是的,你说得对,我过于简化了答案。 - famargar
我接着扫描预测概率,以找到与我最喜欢的ROC点相对应的概率值。您能详细说明一下这个步骤吗?您如何知道哪个概率值对应于ROC点? - stateMachine

0

没有具体的代码示例,很难提供确切的答案。如果您已经在进行交叉验证,可以考虑将AUC指定为要优化的参数:

shuffle = cross_validation.KFold(len(X_train), n_folds=10, shuffle=True)
scores = cross_val_score(classifier, X_train, y_train, cv=shuffle, scoring='roc_auc')

1
嗨White,感谢您的回复。我通过选择roc_auc和其他我当时感兴趣的指标进行了优化(我还创建了一个自定义评分器来优化LR+)。我的主要疑问是如何选择ROC曲线上显示的阈值点之一作为我调用predict()的阈值?我的问题与(https://github.com/scikit-learn/scikit-learn/issues/4813)有关。 我不确定这是否适用于树,因为它们通常不使用probas。但是如何为其他方法设置它呢? - Colis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接