机器学习/深度学习入门:准确率(查准率)、召回率(查全率)、F值和误识率(FAR)、拒识率(FRR)、ROC曲线

准确率(查准率)、召回率(查全率)、F值

正确率、召回率和F值是目标的重要评价指标。

  • 正确率 = 正确识别的个体总数 / 识别出的个体总数 
  • 召回率 = 正确识别的个体总数 / 测试集中存在的个体总数 
  • F值 = 正确率 * 召回率 * 2 / (正确率 + 召回率)

假设要识别照片中的狗的,在一些照片中,包含12只狗的照片和一些猫的照片。算法识别出有8只狗。在确定的8只狗中,5只实际上是狗(真阳性TP),而其余的是猫(假阳性FP)。该程序的精度为5/8,而其召回率为5/12。

不妨举这样一个例子:某池塘有1400条鲤鱼,300只虾,300只鳖。现在以捕鲤鱼为目的。Seaeagle撒一大网,逮着了700条鲤鱼,200只虾,100只鳖。那么,这些指标分别如下:
正确率 = 700 / (700 + 200 + 100) = 70% 
召回率 = 700 / 1400 = 50% 
F1值 = 70% * 50% * 2 / (70% + 50%) = 58.3%

不妨看看如果Seaeagle把池子里的所有的鲤鱼、虾和鳖都一网打尽,这些指标又有何变化: 
正确率 = 1400 / (1400 + 300 + 300) = 70% 
召回率 = 1400 / 1400 = 100% 
F1值 = 70% * 100% * 2 / (70% + 100%) = 82.35% 

由此可见,正确率是评估捕获的成果中目标成果所占得比例;召回率,顾名思义,就是从关注领域中,召回目标类别的比例;而F值,则是综合这二者指标的评估指标,用于综合反映整体的指标。

下面有关分类算法的准确率,召回率,F1 值的描述,错误的是? C

A.准确率是检索出相关文档数与检索出的文档总数的比率,衡量的是检索系统的查准率
B.召回率是指检索出的相关文档数和文档库中所有的相关文档数的比率,衡量的是检索系统的查全率
C.正确率、召回率和 F 值取值都在0和1之间,数值越接近0,查准率或查全率就越高
D.为了解决准确率和召回率冲突问题,引入了F1分数

 

误识率(FAR)、拒识率(FRR)、ROC曲线

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

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

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

è¿éåå¾çæè¿°

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

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

假定有110个人,每人的大拇指的8幅指纹图片共110*8=880幅的指纹数据库,即110类,每类8幅图片。当然,我们希望类内的任意两幅图片匹配成功,类间的任意图片匹配失败。现在我们让库中的每一幅图片除开它自身之外与其他的所有图片进行匹配,分别计算误识率,与拒识率。

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

拒识率(FRR):假定由于指纹识别算法性能的原因,把本应该匹配成功的判为匹配失败,若这种错误次数为160次。则拒识率为160/6160=2.6%.

在有些文献中将误识率表达为FMR(False match rate),以及将拒识率表达为FNMR(False non-match rate),这和本文中所讲到的误识率与拒识率是同一个意思,即:误识率:FAR=FMR、拒识率:FRR=FNMR

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

è¿éåå¾çæè¿°

ROC曲线(Receiver Operator characteristic Curve)是一种已经被广泛接受的系统匹配算法测试指标,它是匹配分数阈值、误识率以及拒识率之间的一种关系。它反映了识别算法在不同阈值上,拒识率和误识率的平衡关系。 下图给出了ROC曲线,其中横坐标是拒识率,纵坐标是误识率,等错误率(EER Equal-Error Rate)是拒识率和误识率的一个平衡点,等错误率能够取到的值越低,表示算法的性能越好。 

è¿éåå¾çæè¿°

二分类ROC和AUC

ROC

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

  • True Positive(真正, TP):将正类预测为正类数. 
  • True Negative(真负 , TN):将负类预测为负类数. 
  • False Positive(假正, FP):将负类预测为正类数 → 误报 (Type I error). 
  • False Negative(假负 , FN):将正类预测为负类数 →漏报 (Type II error).

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

TPR为纵轴,FPR为横轴希望FPR越小越好,TPR越大越好

点(0,1),所有的预测都正确了点(1,0),所有的预测都预测错了。点(0,0),所有的样本都预测为。点(1,1),所有的样本都预测为。如果一个点越接近左上角,那么说明模型的预测效果越好。通过更改分类阈值来得到ROC。

  • 阈值的范围是[0,1],当阈值从1到0慢慢移动时,FPR会越来越大。因为FP(假正例)会越来越多。
  • 事实上,ROC曲线不是光滑的,而是阶梯型的。为什么呢?因为样本的数量是有限的,而FPR和TPR的变化需要至少有一个样本变化了,在没有变化的间隙里,就不会有变化。也就是说,步进是1/样本数。

AUC

假设我们有一个分类器,输出是样本输入正例的概率,所有的样本都会有一个相应的概率,这样我们可以得到下面这个图: 
 这里写图片描述 
其中,横轴表示预测为正例的概率,纵轴表示样本数。 
所以,蓝色区域表示所有负例样本的概率分布,红色样本表示所有正例样本的概率分布。显然,如果我们希望分类效果最好的话,那么红色区域越接近1越好,蓝色区域越接近0越好。

为了验证你的分类器的效果。你需要选择一个阈值,比这个阈值大的预测为正例,比这个阈值小的预测为负例。如下图: 
 这里写图片描述 
在这个图中,阈值选择了0.5于是左边的样本都被认为是负例,右边的样本都被认为是正例。可以看到,红色区域与蓝色区域是有重叠的,所以当阈值为0.5的时候,我们可以计算出准确率为90%.

好,现在我们来引入ROC曲线。 

这里写图片描述
图中左上角就是ROC曲线,其中横轴就是前面说的FPR(False Positive Rate),纵轴就是TPR(True Positive Rate)。 
然后我们选择不同的阈值时,就可以对应坐标系中一个点。

 这里写图片描述 
当阈值为0.8时,对应上图箭头所指的点。

 这里写图片描述 
当阈值为0.5时,对应上图箭头所指的点。

这样,不同的阈值对应不同的点。最后所有的点就可以连在一起形成一条曲线,就是ROC曲线。

现在我们来看看,如果蓝色区域与红色的区域发生变化,那么ROC曲线会怎么变呢? 
 这里写图片描述 
上图中,蓝色区域与红色区域的重叠部分不多,所以可以看到ROC曲线距离左上角很近。

 这里写图片描述 
但是,当蓝色区域与红色区域基本重叠时,ROC曲线就和接近y=x这条线了。

综上两个图,如果我们想要用ROC来评估分类器的分类质量,我们就可以通过计算AUC(ROC曲线下的面积)来评估了,这就是AUC的目的。其实,AUC表示的是正例排在负例前面的概率。 
 这里写图片描述 
比如上图,第一个坐标系的AUC值表示,所有的正例都排在负例的前面。第二个AUC值,表示有百分之八十的正例排在负例的前面。

我们知道阈值可以取不同,也就是说,分类的结果会受到阈值的影响。如果使用AUC的话,因为阈值变动考虑到了,所以评估的效果更好。

另一个好处是,ROC曲线有一个很好的特性:当测试集中的正负样本分布发生变化了,ROC曲线可以保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。 

多分类下的ROC曲线和AUC

        由于ROC曲线是针对二分类的情况,对于多分类问题,ROC曲线的获取主要有两种方法:

        假设测试样本个数为m,类别个数为n(假设类别标签分别为:0,2,...,n-1)。在训练完成后,计算出每个测试样本的在各类别下的概率或置信度,得到一个[m, n]形状的矩阵P,每一行表示一个测试样本在各类别下概率值(按类别标签排序)。相应地,将每个测试样本的标签转换为类似二进制的形式,每个位置用来标记是否属于对应的类别(也按标签排序,这样才和前面对应),由此也可以获得一个[m, n]的标签矩阵L。

         比如n等于3,标签应转换为:

        方法1:每种类别下,都可以得到m个测试样本为该类别的概率(矩阵P中的列)。所以,根据概率矩阵P和标签矩阵L中对应的每一列,可以计算出各个阈值下的假正例率(FPR)和真正例率(TPR),从而绘制出一条ROC曲线。这样总共可以绘制出n条ROC曲线。最后对n条ROC曲线取平均,即可得到最终的ROC曲线。

        方法2:首先,对于一个测试样本:1)标签只由0和1组成,1的位置表明了它的类别(可对应二分类问题中的‘’正’’),0就表示其他类别(‘’负‘’);2)要是分类器对该测试样本分类正确,则该样本标签中1对应的位置在概率矩阵P中的值是大于0对应的位置的概率值的。基于这两点,将标签矩阵L和概率矩阵P分别按行展开,转置后形成两列,这就得到了一个二分类的结果。所以,此方法经过计算后可以直接得到最终的ROC曲线。

       上面的两个方法得到的ROC曲线是不同的,当然曲线下的面积AUC也是不一样的。 在python中,方法1和方法2分别对应sklearn.metrics.roc_auc_score函数中参数average值为'macro'和'micro'的情况。

      下面以方法2为例,直接上代码,概率矩阵P和标签矩阵L分别对应代码中的y_score和y_one_hot:

#!/usr/bin/python
# -*- coding:utf-8 -*-
 
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegressionCV
from sklearn import metrics
from sklearn.preprocessing import label_binarize
 
if __name__ == '__main__':
    np.random.seed(0)
    data = pd.read_csv('iris.data', header = None)  #读取数据
    iris_types = data[4].unique()
    n_class = iris_types.size
    x = data.iloc[:, :2]  #只取前面两个特征
    y = pd.Categorical(data[4]).codes  #将标签转换0,1,...
    x_train, x_test, y_train, y_test = train_test_split(x, y, train_size = 0.6, random_state = 0)
    y_one_hot = label_binarize(y_test, np.arange(n_class))  #装换成类似二进制的编码
    alpha = np.logspace(-2, 2, 20)  #设置超参数范围
    model = LogisticRegressionCV(Cs = alpha, cv = 3, penalty = 'l2')  #使用L2正则化
    model.fit(x_train, y_train)
    print '超参数:', model.C_
    # 计算属于各个类别的概率,返回值的shape = [n_samples, n_classes]
    y_score = model.predict_proba(x_test)
    # 1、调用函数计算micro类型的AUC
    print '调用函数auc:', metrics.roc_auc_score(y_one_hot, y_score, average='micro')
    # 2、手动计算micro类型的AUC
    #首先将矩阵y_one_hot和y_score展开,然后计算假正例率FPR和真正例率TPR
    fpr, tpr, thresholds = metrics.roc_curve(y_one_hot.ravel(),y_score.ravel())
    auc = metrics.auc(fpr, tpr)
    print '手动计算auc:', auc
    #绘图
    mpl.rcParams['font.sans-serif'] = u'SimHei'
    mpl.rcParams['axes.unicode_minus'] = False
    #FPR就是横坐标,TPR就是纵坐标
    plt.plot(fpr, tpr, c = 'r', lw = 2, alpha = 0.7, label = u'AUC=%.3f' % auc)
    plt.plot((0, 1), (0, 1), c = '#808080', lw = 1, ls = '--', alpha = 0.7)
    plt.xlim((-0.01, 1.02))
    plt.ylim((-0.01, 1.02))
    plt.xticks(np.arange(0, 1.1, 0.1))
    plt.yticks(np.arange(0, 1.1, 0.1))
    plt.xlabel('False Positive Rate', fontsize=13)
    plt.ylabel('True Positive Rate', fontsize=13)
    plt.grid(b=True, ls=':')
    plt.legend(loc='lower right', fancybox=True, framealpha=0.8, fontsize=12)
    plt.title(u'鸢尾花数据Logistic分类后的ROC和AUC', fontsize=17)
    plt.show()

      实验输出结果:

       可以从上图看出,两者计算结果一致!      

        实验绘图结果:

展开阅读全文

没有更多推荐了,返回首页