【问题标题】:Thresholds, False Positive Rate, True Positive Rate阈值、假阳性率、真阳性率
【发布时间】:2022-01-17 06:49:27
【问题描述】:

我试图清楚地了解标题中术语的计算内容。 https://scikit-learn.org/stable/modules/model_evaluation.html#roc-metrics 的文档说

“接收器操作特征 (ROC),或简称 ROC 曲线,是一个图形图,它说明了二元分类器系统在其区分阈值变化时的性能。它是通过绘制真阳性的分数而创建的在不同的阈值设置下,阳性(TPR = 真阳性率)与阴性中假阳性的比例(FPR = 假阳性率)。”

这是我根据我使用 keras 所做的一些预测创建的一些简单代码。

from sklearn import metrics
test1 = '0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0'        
pred1 = '0.04172871 0.01611879 0.01073375 0.03344169 0.04172871 0.04172871\
 0.00430162 0.04172871 0.04172871 0.04172871 0.07977659 0.905772\
 0.9396076  0.03344169 0.04172871 0.09125287 0.02964183 0.0641269\
 0.04172871 0.04172871 0.04172871 0.0641269  0.04172871 0.04172871\
 0.9919831  0.04172871 0.01611879 0.04172871 0.37865442 0.00240888'

test = np.array([int(i) for i in test1.split()])
pred =np.array([float(i) for i in pred1.split()])

print(type(test))

print(type(pred))

fpr, tpr, thresholds = metrics.roc_curve(test, pred)
print('false pos rate')
print(fpr)
print()
print('true pos rate')
print(tpr)
print()
print('thresholds')
print(thresholds)

我可以看到它是如何选择阈值的(在本例中为 10 个值 - 最低 pred,最高 pred+1),但为什么在本例中为 10 个阈值 - 为什么不是其他数字? 我还希望能够遵循代数如何使用阈值获取 fpr 和 tpr 值。答案可能在我上面给出的文档句子中,但我还没有弄清楚费率计算的工作原理。

这里分别是阈值、fp 率和 tp 率

[1.9919831 0.9919831 0.37865442 0.07977659 0.0641269 0.04172871 0.03344169 0.02964183 0.01611879 0.00240888]

[0. 0. 0. 0.07692308 0.15384615 0.69230769 0.76923077 0.80769231 0.88461538 1.]

[0. 0.25 1. 1. 1. 1. 1. 1. 1. 1. ]

【问题讨论】:

  • 请使用问题编辑器上方的代码格式化按钮 ({}) 将您的代码格式化为代码,并从中删除所有多余的空行。通常,在 Python 中,包含 two; separate; statements 的行是不好的风格(它们甚至在 Matlab 中,老实说!)。您发布的代码对于理解毫无用处,因为缩进在 Python 语法中很重要,并且被默认文本格式吃掉了。请修复您的代码!

标签: scikit-learn


【解决方案1】:

正如您可能看到的herethreshold 向量作为 distinct 分数的向量获得(在您的情况下,它由 pred 数组中的不同值给出)。

也就是说,您应该考虑roc_curve 有一个进一步的参数(drop_intermediate - 默认为 True),用于降低次优阈值。在您的情况下,通过将其传递给 False 从而避免降低特定阈值fpr, tpr, thresholds = metrics.roc_curve(test, pred, drop_intermediate=False), 你会看到你会得到一个threshold 向量,其长度等于你的分数向量中不同值的数量加一。

确实,正如您可能看到的here,阈值向量进一步扩展了一个元素thresholds[0] + 1,以确保ROC 曲线从(0,0) 开始。

关于tpr (tp / (tp + fn)) 的计算,请考虑文档中的内容:

tpr: ndarray 形状 (>2,) 提高真阳性率,使元素 i 是分数 >= thresholds[i] 的预测的真阳性率。

要对此进行解码,最好坚持一个更简单的例子:

import numpy as np
from sklearn import metrics
y = np.array([0, 0, 1, 1])
scores = np.array([0.1, 0.4, 0.35, 0.8])
fpr, tpr, thresholds = metrics.roc_curve(y, scores, drop_intermediate=False)   
# thresholds = array([1.8, 0.8, 0.4, 0.35, 0.1])

按升序对scores 进行排序并相应地考虑ythresholds,您将拥有:

y = np.array([0, 1, 0, 1])
scores = np.array([0.1, 0.35, 0.4, 0.8])
thresholds = array([0.1, 0.35, 0.4, 0.8, 1.8])

# score = threshold = 0.1, y = 0  --> tp = 0, tp+fn = total number positives = 2 --> tpr = 0
# score = threshold = 0.35, y = 1 --> tp = 1, tp+fn = 2 --> tpr = 0.5
# score = threshold = 0.4, y = 0  --> tp = 1, tp+fn = 2 --> tpr = 0.5
# score = threshold = 0.8, y = 1  --> tp = 2, tp+fn = 2 --> tpr = 1
# score = threshold = 1.8         --> tp = 2, tp+fn = 2 --> tpr = 1

tp 是真阳性的累计数。

因此,您将拥有tpr = np.array([0, 0.5, 0.5, 1, 1])fpr 的计算应该按照其定义直接进行。

【讨论】:

  • 谢谢 - 我在昨天发布后完成了 fpr、tpr 计算。我像你一样使用了 sci-kit 学习示例,并使用一个小的 5 x 4 电子表格来计算它 - 基本上就是你在这里所做的。我想我理解次优阈值的概念 - 在 sci-kit 'source' 链接中解释过 - 丢弃不会影响 AUC,而且他们说“保持太多阈值没有害处”。
猜你喜欢
  • 1970-01-01
  • 2018-08-21
  • 1970-01-01
  • 2022-12-29
  • 2018-11-12
  • 2017-01-25
  • 2016-02-03
  • 1970-01-01
  • 2020-10-13
相关资源
最近更新 更多