模型评价指标 - 分类任务

  根据模型处理的任务不同,评价标准也不同,分类任务和回归任务的评价指标如下:

  • 分类:accuracy、误分类率、precision、recall、F1 score、ROC曲线、AUC、PR曲线、AP、mAP等;
  • 回归:MAE、MSE;

1. 混淆矩阵(Confusion Matrix)

混淆矩阵是能够比较全面的反映模型的性能,从混淆矩阵能够衍生出很多的指标来。


模型评价指标 - 分类任务_第1张图片

其中:

  • TP:真正例,实际为正预测为正;
  • FP:假正例,实际为负但预测为正;
  • FN:假反例,实际为正但预测为负;
  • TN:真反例,实际为负预测为负

sklearn.metrics.confusion_matrix(y_true, y_pred, labels=None, sample_weight=None)

>>> from sklearn.metrics import confusion_matrix
>>> y_true = [2, 0, 2, 2, 0, 1]
>>> y_pred = [0, 0, 2, 2, 0, 2]
>>> confusion_matrix(y_true, y_pred)
array([[2, 0, 0],
       [0, 0, 1],
       [1, 0, 2]])

>>> y_true = ["cat", "ant", "cat", "cat", "ant", "bird"]
>>> y_pred = ["ant", "ant", "cat", "cat", "ant", "cat"]
>>> confusion_matrix(y_true, y_pred, labels=["ant", "bird", "cat"])
array([[2, 0, 0],
       [0, 0, 1],
       [1, 0, 2]])

2. 准确率(正确率)(Accuracy)

准确率是分类正确的样本占总样本个数的比例,即

其中,为被正确分类的样本个数,为总样本个数。
根据Confusion Matrix,公式还可以这样写:

  准确率是分类问题中最简单直观的评价指标,但存在明显的缺陷。比如如果样本中有99%的样本为正样本,那么分类器只需要一直预测为正,就可以得到99%的准确率,但其实际性能是非常低下的。也就是说,当不同类别样本的比例非常不均衡时,占比大的类别往往成为影响准确率的最主要因素。
sklearn.metrics.accuracy_score(y_true, y_pred, normalize=True, sample_weight=None)

>>> from sklearn.metrics import accuracy_score
>>> y_pred = [0, 2, 1, 3]
>>> y_true = [0, 1, 2, 3]
>>> accuracy_score(y_true, y_pred)
0.5
>>> accuracy_score(y_true, y_pred, normalize=False)
2

# 在具有二元标签指示符的多标签分类案例中
>>> import numpy as np
>>> accuracy_score(np.array([[0, 1], [1, 1]]), np.ones((2, 2)))
0.5

  因为准确率的缺陷比较明显,所以在多分类问题中一般不直接使用整体的分类准确率,而是使用每个类别下的样本准确率的算术平均作为模型的评估指标。

3. 精确率、查准率(精准率)

精确率指模型预测为正的样本中实际也为正的样本占被预测为正的样本的比例。公式为:

sklearn.metrics.precision_score(y_true, y_pred, labels=None, pos_label=1, average=’binary’, sample_weight=None)
重要参数

  • y_true : 一维数组,或标签指示符 / 稀疏矩阵,实际(正确的)标签.
  • y_pred : 一维数组,或标签指示符 / 稀疏矩阵,分类器返回的预测标签.
  • average : 字符串,可选值为[None, ‘binary’, ‘micro’, ‘macro’, ‘samples’, ‘weighted’].多类或者多标签目标需要这个参数. 如果为None,每个类别的分数将会返回. 否则,它决定了数据的平均值类型.
    binary: 仅报告由pos_label指定的类的结果. 这仅适用于目标是二进制的情况.
    micro: 通过计算总的真正性、假负性和假正性来全局计算指标.
    macro: 为每个标签计算指标,找到它们未加权的均值. 它不考虑标签数量不平衡的情况.
    weighted: 为每个标签计算指标,并通过各类占比找到它们的加权均值(每个标签的正例数).它解决了macro的标签不平衡问题;它可以产生不在精确率和召回率之间的F-score.
    samples: 为每个实例计算指标,找到它们的均值(只在多标签分类的时候有意义,并且和函数accuracy_score不同).
  • sample_weight : 形状为[样本数量]的数组,可选参数. 样本权重.
>>> from sklearn.metrics import precision_score
>>> y_true = [0, 1, 2, 0, 1, 2]
>>> y_pred = [0, 2, 1, 0, 0, 1]
>>> precision_score(y_true, y_pred, average='macro')  
0.22...
>>> precision_score(y_true, y_pred, average='micro')  
0.33...
>>> precision_score(y_true, y_pred, average='weighted')
0.22...
>>> precision_score(y_true, y_pred, average=None)  
array([0.66..., 0.        , 0.        ])
  • Macro Average
    宏平均是指在计算均值时使每个类别具有相同的权重,最后结果是每个类别的指标的算术平均值。
  • Micro Average
    微平均是指计算多分类指标时赋予所有类别的每个样本相同的权重,将所有样本合在一起计算各个指标。

  根据precision_score接口的解释,我们可以知道,当average参数为None时,得到的结果是每个类别的precision。上面的y_true有3个类别,分别为类0、类1、类2。我们将每个类别的TP、FP、FN列在下表中。

类别 TP FP FN
类1 2 1 0
类2 0 2 2
类3 0 1 1

那么每个类别的precision也就得到了,如下所示:


从而Macro Precision也就知道了,就是(P0+P1+P2)/3=2/9≈0.222

  Micro Precision的计算要从每个样本考虑,所有样本中预测正确的有两个,那么TP就是2,剩下的4个预测结果都可以看做FP,那么Micro Precision就是2/(2+4)=1/3≈0.333
最后还有一个average='weighted’的情况,因为这里每个类别的数量都恰好占比1/3,所以结果是

虽然,我们是主要讲精确率的,但是宏平均和微平均的概念也很重要,这里顺便对比一下。

  • 如果每个类别的样本数量差不多,那么宏平均和微平均没有太大差异
  • 如果每个类别的样本数量差异很大,那么注重样本量多的类时使用微平均,注重样本量少的类时使用宏平均
  • 如果微平均大大低于宏平均,那么检查样本量多的类来确定指标表现差的原因
  • 如果宏平均大大低于微平均,那么检查样本量少的类来确定指标表现差的原因

4. 查全率(召回率)

召回率指实际为正的样本中被预测为正的样本所占实际为正的样本的比例。

sklearn中recall_score方法和precision_score方法的参数说明都是一样的,所以这里不再重复
sklearn.metrics.recall_score(y_true, y_pred, labels=None, pos_label=1, average=’binary’, sample_weight=None)

>>> from sklearn.metrics import recall_score
>>> y_true = [0, 1, 2, 0, 1, 2]
>>> y_pred = [0, 2, 1, 0, 0, 1]
>>> recall_score(y_true, y_pred, average='macro')  
0.33...
>>> recall_score(y_true, y_pred, average='micro')  
0.33...
>>> recall_score(y_true, y_pred, average='weighted')  
0.33...
>>> recall_score(y_true, y_pred, average=None)
array([1., 0., 0.])

  Recall和Precision只有计算公式不同,它们average参数为’macro’,‘micro’,'weighted’和None时的计算方式都是相同的,具体计算可以使用上节列出来的TP、FP、FN表,这里不再赘述。
  查准率和查全率是一对矛盾的度量。一般来说,查准率高时,查全率往往偏低;而查全率高时,查准率往往偏低。通常只有在一些简单任务中,才可能使二者都很高。

5. F1 score

F1 score是精确率和召回率的调和平均值,计算公式为:

Precision 体现了模型对负样本的区分能力,Precision越高,模型对负样本的区分能力越强;Recall 体现了模型对正样本的识别能力,Recall 越高,模型对正样本的识别能力越强。F1 score是两者的综合,F1 score越高,说明模型越稳健。
sklearn中f1_score方法和precision_score方法、recall_score方法的参数说明都是一样
sklearn.metrics.f1_score(y_true, y_pred, labels=None, pos_label=1, average=’binary’, sample_weight=None)

>>> from sklearn.metrics import f1_score
>>> y_true = [0, 1, 2, 0, 1, 2]
>>> y_pred = [0, 2, 1, 0, 0, 1]
>>> f1_score(y_true, y_pred, average='macro')  
0.26...
>>> f1_score(y_true, y_pred, average='micro')  
0.33...
>>> f1_score(y_true, y_pred, average='weighted')  
0.26...
>>> f1_score(y_true, y_pred, average=None)
array([0.8, 0. , 0. ])

6. P-R曲线

  P-R曲线的P就是查准率(Precision),R就是查全率(Recall)。以P作为横坐标,R作为纵坐标,就可以画出P-R曲线。

对于同一个模型,通过调整分类阈值,可以得到不同的P-R值,从而可以得到一条曲线(纵坐标为P,横坐标为R)。通常随着分类阈值从大到小变化(大于阈值认为P),Precision减小,Recall增加。比较两个分类器好坏时,显然是查得又准又全的比较好,也就是的PR曲线越往坐标(1,1)的位置靠近越好。若一个学习器的P-R曲线被另一个学习器完全”包住”,则后者的性能优于前者。当存在交叉时,可以计算曲线围住面积,不太容易判断,但是可以通过平衡点(查准率=查全率,Break-Even Point,BEP)来判断。

下图中,基于BEP的比较,可以认为模型A优于模型B。

模型评价指标 - 分类任务_第2张图片

7. ## ROC曲线和AUC

  AUC(Area Under the ROC Curve)指标是在二分类问题中,模型评估阶段常被用作最重要的评估指标来衡量模型的稳定性。

根据混淆矩阵,我们可以得到另外两个指标:

真正例率,True Positive Rate:TPR = TP/ (TP+FN)

假正例率, False Postive Rate:FPR = FP/(TN+FP)

另外,真正率是正确预测到的正例数与实际正例数的比值,所以又称为灵敏度(敏感性,sensitive);

对应于灵敏度有一个特异度(特效性,specificity)是正确预测到的负例数与实际负例数的比值(NPV = TN / (TN+FN))。

我们以真正例率(TPR)作为纵轴,以假正例率(FPR)作为横轴作图,便得到了ROC曲线,而AUC则是ROC曲线下的面积。AUC的取值为[0.5-1],0.5对应于对角线的“随机猜测模型”。

模型评价指标 - 分类任务_第3张图片

  AUC值是一个概率值,当你随机挑选一个正样本以及负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值,AUC值越大,当前分类算法越有可能将正样本排在负样本前面,从而能够更好地分类。例如一个模型的AUC是0.7,其含义可以理解为:给定一个正样本和一个负样本,在70%的情况下,模型对正样本的打分(概率)高于对负样本的打分。

  那么为什么要用AUC作为二分类模型的评价指标呢?为什么不直接通过计算准确率来对模型进行评价呢?

  因为机器学习中的很多模型对于分类问题的预测结果大多是概率,即属于某个类别的概率,如果计算准确率的话,就要把概率转化为类别,这就需要设定一个阈值,概率大于某个阈值的属于一类,概率小于某个阈值的属于另一类,而阈值的设定直接影响了准确率的计算。也就是说AUC越高说明阈值分割所能达到的准确率越高。

8. PR曲线与ROC曲线对比

  与PR曲线相比,相对来讲ROC曲线会更稳定,在正负样本量都足够的情况下,ROC曲线足够反映模型的判断能力。而在正负样本分布得极不均匀(highly skewed datasets)的情况下(正样本极少),PRC比ROC能更有效地反映分类器对于整体分类情况的好坏。

  总之,只画一个曲线时,如果没有data imbalance,倾向于用ROC(更简洁,更好理解)。如果数据样本不均衡,分两种情况:

情况1:如正样本远小于负样本,PRC更敏感,因为用到了precision=(TP/(TP+FP))。

情况2:正样本远大于负样本,PRC和ROC差别不大,都不敏感。

对于同一模型,PRC和ROC曲线都可以说明一定的问题,而且二者有一定的相关性,如果想评测模型效果,也可以把两条曲线都画出来综合评价。

你可能感兴趣的:(模型评价指标 - 分类任务)