Python 中的等误差率

18

有人能告诉我如何在Python中从ROC曲线计算等误差率(EER)吗?在scikit-learn中有计算ROC曲线和AUC的方法,但找不到计算EER的方法。

from sklearn.metrics import roc_curve, auc

回答:

我认为我自己实现了。

ROC EER的想法是连接(1,0)和(0,1)的一条直线与ROC曲线相交的交点。它是唯一的交点。对于一个斜率为1且截距为1的直线,方程为x+y=1(x/a+y/b=1.0)。因此,交点的真正阳性率(TPR)和假阳性率(FPR)的值满足以下方程:

    x + y - 1.0 = 0.0

因此,将该方法实现为:

 def compute_roc_EER(fpr, tpr):
    roc_EER = []
    cords = zip(fpr, tpr)
    for item in cords:
        item_fpr, item_tpr = item
        if item_tpr + item_fpr == 1.0:
            roc_EER.append((item_fpr, item_tpr))
assert(len(roc_EER) == 1.0)
return np.array(roc_EER)

这里有一个错误率和一个准确率。

也许有人可以帮我验证一下。


2
你的理解是正确的 - 你正在寻找 TPR+FPR==1 的位置。然而,你的代码不够健壮,因为我们不能保证坐标列表实际上包含一个恰好位于 EER 线上的点。换句话说,有可能会出现 len(roc_EER)==0 的情况。你需要在两个点之间进行插值(EER 线的两侧各选一个点)以更加健壮地完成这项任务。或者,简单起见,如果你需要选择测试配置中的一种,则可以选择与 EER 线距离最小的设置。 - Dan Stowell
6个回答

28

如果有其他人通过谷歌搜索来到这里,Fran的答案是错误的,正如Gerhard指出的那样。正确的代码应该是:

import numpy as np
from sklearn.metrics import roc_curve

fpr, tpr, threshold = roc_curve(y, y_pred, pos_label=1)
fnr = 1 - tpr
eer_threshold = threshold[np.nanargmin(np.absolute((fnr - fpr)))]

请注意,此代码获取的是EER发生时的阈值,而不是EER本身。 EER定义为FPR = 1 - PTR = FNR。因此,要获取EER(实际错误率),您可以使用以下代码:

EER = fpr[np.nanargmin(np.absolute((fnr - fpr)))]

作为一种合理性检查,该值应该接近于

EER = fnr[np.nanargmin(np.absolute((fnr - fpr)))]

因为这只是一个近似值。


16
对于阅读此答案的任何人:应该使用fpr[np.nanargmin(np.absolute((fnr - fpr)))]而不是fpr(np.nanargmin(np.absolute((fnr - fpr)))),因为fpr是一个numpy数组。 - Colonder

10

参考 Changjiang 的 How to compute Equal Error Rate (EER) on ROC计算方法:

from scipy.optimize import brentq
from scipy.interpolate import interp1d
from sklearn.metrics import roc_curve

fpr, tpr, thresholds = roc_curve(y, y_score, pos_label=1)

eer = brentq(lambda x : 1. - x - interp1d(fpr, tpr)(x), 0., 1.)
thresh = interp1d(fpr, thresholds)(eer)

那给了我正确的EER值。还要记得在文档中写道,y值为{0, 1}或{-1, 1}的真二进制标签。如果标签不是二进制的,则应明确给出pos_label并且y_score目标分数,可以是正类的概率估计、置信度值或某些分类器上“decision_function”返回的非阈值决策度量。


1

在Github上,一篇相对较新的论文AutoSpeech的官方代码中有一个参考代码。我猜这是其中可靠的一个。

https://github.com/VITA-Group/AutoSpeech/blob/master/utils.py#L84

def compute_eer(distances, labels):
    # Calculate evaluation metrics
    fprs, tprs, _ = roc_curve(labels, distances)
    eer = fprs[np.nanargmin(np.absolute((1 - tprs) - fprs))]
    return eer

另一个选择是使用VoxCeleb1非官方基线,该基线链接在官方VoxCeleb1页面上:

https://github.com/clovaai/voxceleb_trainer/blob/master/tuneThreshold.py#L13

但是链接中的tuneThresholdfromScore函数并不简单,那么AutoSpeech可能更好。


1

等误差率(EER)是指您的假阳性率(fpr)==假阴性率(fnr)[越小越好]

使用从roc sklearn计算得到的fpr、tpr和阈值,您可以使用此函数获取EER:

def compute_eer(fpr,tpr,thresholds):
    """ Returns equal error rate (EER) and the corresponding threshold. """
    fnr = 1-tpr
    abs_diffs = np.abs(fpr - fnr)
    min_index = np.argmin(abs_diffs)
    eer = np.mean((fpr[min_index], fnr[min_index]))
    return eer, thresholds[min_index]

0
EER(等错误率)被定义为 FPR=1-PTR=FNR。这是错误的。由于 FPR=1-TNR(真负率),因此不等于 FNR。

-4

要估计等误差率 EER,您需要查找使 TPR 值等于 FPR 值的 ROC 中的点,即 TPR-FPR=0。换句话说,您需要查找 abs(TPR-FPR) 的最小点。

  1. 首先,您需要估计 ROC 曲线:

fpr, tpr, threshold = roc_curve(y, y_pred, pos_label=1)

  1. 要在 Python 中计算 EER,您只需要一行代码:

EER = threshold(np.argmin(abs(tpr-fpr)))


9
错误的。Equal error rate = 假正率 - 假负率。不是真正率 - 假正率! - Gerhard Hagerer

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