【机器学习-评估方法】评价指标

在选择模型的时候,我们会选择好的模型,丢弃不好的模型。模型的好或者不好是根据评价指标来衡量的,这篇文章介绍了分类任务中几种常用的评价指标,包括:错误率(error rate)精度(accuracy)查准率(precision)查全率(recall)F1ROC-AUC

错误率和精度

错误率(error rate)和精度(accuracy)是一对互补的指标,既可以应用于二分类任务,也可以应用于多分类任务。错误率是分类错误的样本数占总样本数的比例,而精度是分类正确的样本数占总样本数的比例。假设样本总数为 n,分类错误的样本为 m,则

[ ext{error rate} = frac{m}{n} \ ext{accuracy} = frac{n-m}{n} = 1 - ext{error rate} ]

查准率、查全率和 F1

首先看一下真正例(true positive,TP)假正例(false positive,FP)真反例(true negative,TN)假反例(false negative,FN),用 TP、FP、TN、FN 分别代表这 4 类样本的数量。假设问题为二分类问题(样本有两个类别:正例或者反例)。真正例和真反例都是我们的模型预测对的那些样本,比如对于一些样本模型预测为正例,实际也为正例,那么这些样本就是真正例;模型预测为反例,实际也为反例,那么这些样本就是真反例。假正例和假反例是模型预测错误的样本:如果对于一些样本模型预测为正例,而实际为反例,说明模型预测错了,那么这些样本叫做假正例(真假是对模型的预测结果做判断,而不是实际的结果);同样地,如果对于一些样本模型预测为反例,而实际为正例,那么这些样本叫做假反例。

上图中的矩阵被称为混淆矩阵(confusion matrix)。对于真正例(TP)、假正例(FP)、真反例(TN)和假反例(FN),有 TP + FP + TN + FN = 样本总数,样本中实际为正例的数量为 TP + FN,样本中实际为反例的数量为 TN + FP。

有了 TP、FP、TN、FN,我们就可以定义查准率(precision,P,又称“准确率”)查全率(recall,R,又称“召回率”)

[ ext{P} = frac{TP}{TP+FP} \ ext{R} = frac{TP}{TP+FN} ]

查准率就是我们模型预测为正例的样本(TP+FP)当中,实际为正例(TP)的比例,而查全率是实际为正例的样本(TP+FN)当中,有多少被预测为正例(TP),注意这里不是 TP+FP,因为虽然 FP 也被预测为正例,但 FP 不在 TP+FN 当中。

举个例子,假设我们有 6 个样本,样本的实际标签和模型预测的标签如下,1 代表正例,0 代表反例:

实际:[1, 1, 1, 0, 0, 0]
预测:[1, 1, 0, 0, 1, 1]

那么,查准率 = TP / (TP+FP) = 2 / (2+2) = 1/2,查全率 = TP / (TP + FN) = 2 / (2+1) = 2/3.

查准率和查全率是一对矛盾的度量。也就是说,查准率较高时,查全率会比较低;查全率较高时,查准率会比较低。使用单一的查准率或者查全率来度量一个模型显得有些片面,所以根据查准率(P)和查全率(R)引出了 F1 度量:

[F_1 = frac{2*P*R}{P+R} ]

F1 实际上是查准率和查全率的调和平均:(frac{1}{F1}=frac{1}{2}(frac{1}{p}+frac{1}{R}))。F1 度量综合考虑了查准率和查全率。对于一些情况,我们比较重视查准率,例如推荐系统,而另一些情况我们更加重视查全率,例如在逃犯信息检索系统中,我们希望少漏掉逃犯。当对查准率和查全率有不同的重视情况时,我们可以使用 F1 度量的一般形式 (F_{eta})

[F_{eta} = frac{(1+eta^2)*P*R}{(eta^2*P)+R} ]

其中,(eta>0) 度量了查全率对查准率的相对重要性。(eta=1) 时,(F_{eta}) 退化为普通的 (F1)(eta>1) 时查全率有更大的影响,(eta<1) 时查准率有更大的影响。

有时,我们会得到多个混淆矩阵。例如,我们进行了多次训练和测试,每次都能得到一个混淆矩阵;或者是在多分类任务中,每两个类别都对应一个混淆矩阵。假如我们想要根据这 n 个混淆矩阵中综合考察查准率和查全率。一种方法是我们可以先对每个混淆矩阵计算查准率(P)和查全率(R),对于 n 个混淆矩阵,有 ((P_1, R_1),(P_2,R_2),dots,(P_n,R_n)),然后计算查准率的平均值,可以得到宏查准率(macro-P);计算查全率的平均值,可以得到宏查全率(macro-recall);根据宏查准率和宏查全率,可以得到宏F1(macro-F1)

[ ext{macro-P} = frac{1}{n}sum_{i=1}^nP_i \ ext{macro-R} = frac{1}{n}sum_{i=1}^nR_i \ ext{macro-F1} = frac{2* ext{macro-P}* ext{macro-R}}{ ext{macro-P}+ ext{macro-R}} ]

还有一种方法就是先计算出所有混淆矩阵中 TP、FP、TN、FN 的平均值 (overline{TP}、overline{FP}、overline{TN}、overline{FN}),然后再基于这些平均值计算出微查准率(micro-P)微查全率(micro-R)微F1(micro-F1)

[ ext{micro-P} = frac{overline{TP}}{overline{TP}+overline{FP}} \ ext{micro-R} = frac{overline{TP}}{overline{TP}+overline{FN}} \ ext{micro-F1} = frac{2* ext{micro-P}* ext{micro-R}}{ ext{micro-P}+ ext{micro-R}} ]

ROC-AUC

很多分类模型的输出是一个概率,我们将输出的概率与阈值比较,如果输出概率大于阈值,则预测为正例,否则预测为反例. 我们将输出概率降序排序,阈值实际上就是输出概率中的一个截断点,在该截断点前的样本都是正例,之后的都是反例。这样的话,假设有 n 个样本,就会有 n 个输出概率,我们将这 n 个概率降序排序,然后每次拿一个概率作为截断点,该截断点之前的都预测为正例,之后的都预测为反例。每次分类后计算两个值叫做假正例率(False Positive Rate,FPR)真正例率(True Positive Rate,TPR)

[ ext{FPR} = frac{FP}{TN+FP} \ ext{TPR} = frac{TP}{TP+FN} ]

将坐标(FPR,TPR)画在二维坐标系中,就会得到ROC曲线(Receiver Operating Characteristic,受试者工作特征),如下图:

ROC 曲线下的面积叫做AUC(Area Under Curve),图中的斜对角虚线代表随机猜测的模型。随机猜测的 AUC 是 0.5,所以正常情况下,ROC-AUC 的取值范围为 [0.5, 1]。左图是理想情况,而实际只有有限个样本,所以 ROC 曲线并不是光滑的。如果模型 A 的 AUC 大于 模型 B 的 AUC,我们说模型 A 优于模型 B。

AUC 还可以从概率角度进行解释:我们取一个正例和一个负例,模型将正例预测为正例的概率大于模型将负例预测为正例的概率的概率就是 AUC。或者说,模型根据样本的输出值将正例排在负例前面的概率就是 AUC。从这个角度,我们可以很容易地计算 AUC:给定正样本M个,负样本N个,以及他们的预测概率(0-1)之间,那么 AUC 的含义就是所有穷举所有的正负样本对,如果正样本的预测概率大于负样本的预测概率,那么就+1;如果如果正样本的预测概率等于负样本的预测概率,那么就+0.5, 如果正样本的预测概率小于负样本的预测概率,那么就+0;最后把统计处理的个数除以M×N就得到我们的 AUC,公式描述如下:

[frac{sum I(P_{正例},P_{负例})}{M imes N} ]

代码实现如下:

def roc_auc(y_true, y_pred):
    pos = [i for i in range(len(y_true)) if y_true[i]==1]
    neg = [i for i in range(len(y_true)) if y_true[i]==0]
    
    score = 0
    for i in pos:
        for j in neg:
            if y_pred[i]>y_pred[j]:
                score += 1
            elif y_pred[i]==y_pred[j]:
                score += 0.5
    return score/(len(pos)*len(neg))

测试:

y_true = [1,1,0,0,0]
y_pred = [0.3,0.8,0.1,0.5,0.4]
roc_auc(y_true, y_pred)  # 0.6666666666666666
sklearn.metrics.roc_auc_score(y_true, y_pred) # 0.6666666666666667

y_true = [1,1,0,0,0,1,1,0,0]
y_pred = [0.3,0.8,0.1,0.5,0.4,0.6,0.7,0.2,0.3]
roc_auc(y_true, y_pred) # 0.875
sklearn.metrics.roc_auc_score(y_true, y_pred) # 0.875

参考

1、周志华《机器学习》

原文地址:https://www.cnblogs.com/flix/p/12846666.html