计算二元分类的 roc_curve 阈值

Posted

技术标签:

【中文标题】计算二元分类的 roc_curve 阈值【英文标题】:Calculate threshold for roc_curve for binary classification 【发布时间】:2020-06-23 02:27:24 【问题描述】:

问题与以下链接中提到的类似,请阅读以供参考。

How does sklearn calculate the area under the roc curve for two binary inputs?

我了解sklearn.metrics._binary_clf_curve 中正在发生的一切。

但是对于二元分类,如何在所述函数中计算/确定多个阈值。该函数返回y_score[threshold_idxs] 作为绘制roc_curve 的阈值,我无法理解y_score[threshold_idxs] 的计算以及为什么这是阈值。

【问题讨论】:

【参考方案1】:

让我们以scikit-learn 0.22.2 documentation为指南针来了解函数的每个组成部分以及最终的结果。

功能
sklearn.metrics.roc_curve(y_true, y_score, pos_label=None, sample_weight=None, drop_intermediate=True)

"active" 参数如果使用默认调用:

y_true:数组,形状 = [n_samples],真正的二进制标签。 y_score:数组,形状 = [n_samples]。目标分数可以是正类的概率估计、置信度值或决策的非阈值度量 drop_intermediate: boolean, optional (default=True), 是否删除一些不会出现在绘制的 ROC 曲线上的次优阈值。

输出

fpr: 数组,形状 = [>2],增加误报率,使得元素 i 是分数 >= 阈值 [i] 的预测的误报率。 tpr:数组,形状 = [>2],增加真阳性率,使元素 i 是分数 >= 阈值 [i] 的预测的真阳性率。 thresholds: 数组,形状 = [n_thresholds],降低用于计算 fpr 和 tpr 的决策函数的阈值

现在,考虑到roc_curve() 的代码,它调用函数_binary_clf_curve(),在经过适当的操作和排序后,它会计算:

distinct_value_indices = np.where(np.diff(y_score))[0]
threshold_idxs = np.r_[distinct_value_indices, y_true.size - 1]

这几行的解释在评论里:

y_score 通常有许多绑定值。在这里,我们提取与不同值相关的索引。我们还连接了曲线末端的值。

以上两行大致回答了您的问题多个阈值是如何计算/确定的

然后,它计算:

tps = stable_cumsum(y_true * weight)[threshold_idxs]
fps = 1 + threshold_idxs - tps

然后返回:

return fps, tps, y_score[threshold_idxs]

然后在主函数上返回roc_curve(),如果是if drop_intermediate and len(fps) > 2:,则

尝试降低与两者之间的点相对应的阈值 与其他点共线。

optimal_idxs = np.where(np.r_[True,
                              np.logical_or(np.diff(fps, 2),
                                            np.diff(tps, 2)),
                              True])[0]

“新”值是:

fps = fps[optimal_idxs]
tps = tps[optimal_idxs]
thresholds = thresholds[optimal_idxs]

之后你可以看到其他操作,但核心是我上面强调的。

【讨论】:

那么如果有阈值对应的点不在中间并且与其他点共线,它们不会被丢弃吗?也没有。 y_score 中唯一的值将继续成为否。在被丢弃之前的阈值? 请注意,默认设置为drop_intermediate=True。您可以将其更改为 drop_intermediate=False 以保留次优阈值。

以上是关于计算二元分类的 roc_curve 阈值的主要内容,如果未能解决你的问题,请参考以下文章

如何更改二元分类的阈值

SVM二元分类器不应该理解训练集中的阈值吗?

scikit learn中roc_curve中的阈值

sklearn 如何计算二元分类器的 roc 曲线下面积?

如何解释决策树的 ROC AUC 曲线的阈值?

Sci-kit 分类阈值