有人能告诉我如何在python中从ROC曲线计算等误差率(EER)吗?在scikit学习中,有计算roc曲线和auc的方法,但找不到计算EER的方法。
from sklearn.metrics import roc_curve, auc
ANSRWER:
我想我实现了自己。
ROC EER的概念是直线连接之间的交点(1,0)和(0,1)以及roc曲线。这是它唯一相交的地方。对于a=1和b=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)
这里一个值是错误率,另一个值则是准确度。
可能有人可以帮我核实一下。
对于通过谷歌搜索到达这里的任何其他人。正如格哈德指出的那样,弗兰的回答是错误的。正确的代码是:
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)))]
因为这是近似值。
复制长江如何计算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}的True二进制标签。如果标签不是二进制的,则应明确给定pos_label,并且y_score
是目标分数,可以是正类的概率估计、置信值或决策的非阈值度量(由某些分类器上的"decision_function"返回)
等错误率(EER)是指错误pos率(fpr)==错误neg率(fnr)[越小越好]
使用从roc-sk-learn计算中获得的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]
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可能会更好。
EER定义为FPR=1-PTR=FNR。这是错误的。
由于FPR=1-TNR(真负率),因此不等于FNR。
要估计相等错误率EER
,请在ROC
中查找使TPR
值等于FPR
值的点,即TPR-FPR=0
。换句话说,你寻找abs(TPR-FPR
)的最小点
- 首先,您需要估计
ROC
曲线:
fpr, tpr, threshold = roc_curve(y, y_pred, pos_label=1)
- 要在python中计算
EER
,您只需要一行代码:
EER = threshold(np.argmin(abs(tpr-fpr)))