误识率、拒识率和ROC曲线

转载自:yanzi1225627

平时在做语音、人脸识别时,需要用到一些评价算法性能的评价指标。其中常见的当属以下几种:

误识率(FAR,false acceptance rate) 拒识率(FRR,false rejection rate) ROC曲线(Receiver Operator characteristic Curve)

其中误识率与拒识率的就算公式如下:

ROC1

说白一些,假定在指纹匹配识别过程中:

误识率(FAR)是指在标准指纹数据库上测试指纹识别算法时,不同指纹的匹配分数大于给定阈值,从而被认为是相同指纹的比例,简单地说就是“把不应该匹配的指纹当成匹配的指纹”的比例。

拒识率(FRR)是指在标准指纹数据库上测试指纹识别算法时,相同指纹的匹配分数低于给定阈值,从而被认为是不同指纹的比例,简单地说就是 “把应该相互匹配成功的指纹当成不能匹配的指纹”的比例。

举个例子:

假定有110个人,每人的大拇指的8幅指纹图片共110*8=880幅的指纹数据库,即110类,每类8幅图片。

当然,我们希望类内的任意两幅图片匹配成功,类间的任意图片匹配失败。现在我们让库中的每一幅图片除开它自身之外与其他的所有图片进行匹配,分别计算误识率与拒识率。

误识率(FAR):假定由于指纹识别算法性能的原因,把本应该匹配失败的判为匹配成功,若假定这种错误次数为1000次。理论情况下,来自同一个指纹的图像都成功匹配,次数为7*8*110=6160次,匹配的总次数,即880×(880-1)=773520次。匹配失败次数应为773520-6160=767360次。则误识率FAR1000/767360*100%=0.13%

拒识率(FRR):假定由于指纹识别算法性能的原因,把本应该匹配成功的判为匹配失败,若这种错误次数为160次。则拒识率为160/6160=2.6%。 在有些文献中将误识率表达为FMR(False match rate),以及将拒识率表达为FNMR(False non-match rate),这和本文中所讲到的误识率与拒识率是同一个意思,即:

误识率:FAR=FMR 拒识率:FRR=FNMR

可以用以下这图加深理解:

ROC2

ROC曲线(Receiver Operator characteristic Curve)是一种已经被广泛接受的系统匹配算法测试指标,它是匹配分数阈值误识率以及拒识率之间的一种关系。它反映了识别算法在不同阈值上,拒识率和误识率的平衡关系。

下图给出了ROC曲线,其中横坐标是拒识率,纵坐标是误识率,等错误率(EER Equal-Error Rate)是拒识率和误识率的一个平衡点,等错误率能够取到的值越低,表示算法的性能越好。

ROC3

在另外的一些二分类模式识别,如人脸验证中,ROC 关注常关注两个指标:

ROC4

其中:

True Positive(真正, TP):将正类预测为正类数。

True Negative(真负 , TN):将负类预测为负类数。

False Positive(假正, FP):将负类预测为正类数 → 误报 (Type I error)。

False Negative(假负 , FN):将正类预测为负类数 →漏报 (Type II error)。

直观上,TPR 代表能将正例分对的概率,FPR 代表将负例错分为正例的概率。在 ROC 空间中,每个点的横坐标是 FPR,纵坐标是 TPR,这也就描绘了分类器在 TP(真正率)和 FP(假正率)间的 trade-off2

ROC5

图像处理中经常有误拒率和误识率两个概念,今天简介下。

误拒率,就是错误拒绝的意思,指的类内匹配。如果有10个志愿者的样本,每个志愿者20幅样本。那么相对于类内测试,比如对1号志愿者,同一类的这20幅图片之间,互相匹配,假设1:1的匹配,互相不重复能够进行(20*19)/2次。如果10个志愿者都进行这么测试,就是10*(20*19)/2次。这是总的类内匹配次数。预设定阈值为TH,如果匹配值th>TH就会错误拒绝。

误识率,指错误接受的概率,相对于类间匹配而言。不同的类之间进行的匹配,如果阈值th小于预设阈值TH,就会认为属于同一类,这种情况就是错误接受。

计算公式如下:

ROC1

也可以参照这篇论文里的57页和20页的介绍。

因为FRRFAR互相矛盾,所以当两者相等时的概率就是等错误率。当阈值为TH时,此时对应的FRR有个数值、FAR有个数值。这样得到一组对应的FRRFAR,以FAR为横坐标,FRR为纵坐标画曲线,就是ROC曲线。再画y=x的曲线,两个曲线相交时对应的横坐标或纵坐标就是等错误率,这个时候对应的阈值就是最优的。

典型的ROC曲线示意图:

ROC6

网上至今没有计算等错误率和画ROC的Matlab源码,我写了一个,仅供大家参考,核心代码如下:

function out = YanEER(leinei, leijian)

NGRA = length(leinei);   %类内测试的次数 对应误据率 FRR
NIRA = length(leijian);  %类间测试的次数  对应误识率, FAR

FRR = [];
FAR = [];
th = 0.1:0.02:0.55;  %阈值,一共xxx个
for i=1:length(th)
    frr = sum(leinei>th(i))/NGRA;  %大于预设阈值的 就错误的拒绝了
    FRR=[FRR frr];

    far = sum(leijian<th(i))/NGRA; %小于阈值的  就错误的接受了
    FAR = [FAR far];

end

这里面的th是用来控制预设定阈值的,可以根据自己的需要设置。一般它跟你输入的参数的最小值和最大值有关系,也可以和这两个最值关联起来。另外,计算frr的时候也可以乘上100,这时坐标系就是(%)。大家灵活修改吧。

Table of Contents