分类器(二分类和多分类)性能评价指标及python计算

一、二分类

real\predict Positive Negative
True TP FN
False FP TN
  • TP、TN、FP、FN 中的第二个字母(列标首字母)是机器学习算法或模型预测的结果(正例:P、反例:N)
  • TP、TN、FP、FN 中的第一个字母(行标首字母)是根据真实情况判断预测结果是否正确(正确:T、错误:F)

即:

  • 正确地预测为正例:TP
  • 正确地预测为反例:TN
  • 错误地预测为正例:FP
  • 错误地预测为反例:FN

准确率Accuracy:被预测正确的比例
a c c u r a c y = T P + T N T P + F P + F N + T N accuracy = \frac{TP+TN }{TP + FP + FN + TN}
精确率(查准率) Precision :"正确被预测为正(TP)"占所有"实际被预测为正的(TP+FP)"的比例(混淆矩阵中除以所在的那一列之和)

p r e c i s i o n = T P T P + F P precision = \frac{TP }{TP + FP}

召回率(查全率) Recall:"正确被预测为正(TP)"占所有"应该被预测为正(TP+FN)"的比例(混淆矩阵中除以所在的那一行之和)

r e c a l l = T P T P + F N recall = \frac{TP }{TP + FN}

F-measure

F m e a s u r e = ( a 2 + 1 ) P R a 2 ( P + R ) F- measure = \frac{(a^2 + 1 )*P*R}{a^2(P+R)}

如果A取1,那么F-measure实际上就是precison和recall的调和平均值, 此时的F-measure就称为F1值。

F 1 = 2 P R P + R F- 1 = \frac{2PR}{P+R}

二、多分类

real\predict 类1 类2 类3
类1 43 5 2
类2 2 45 3
类3 0 1 49

每一行之和为50,表示50个样本。
第一行说明类1的50个样本有43个分类正确,5个错分为类2,2个错分为类3。

类似于二分类,多类分类问题中,分类结果一般有4种情况:

  • 属于类C的样本被正确分类到类C,记这一类样本数为 TP
  • 不属于类C的样本(可能是A也可能是B…)被错误分类到类C,记这一类样本数为 FN
  • 属于类别C的样本被错误分类到类C的其他类,记这一类样本数为 TN
  • 不属于类别C的样本被正确分类到了类别C的其他类,记这一类样本数为 FP

宏平均 Macro-average

Macro F1:将n分类的评价拆成n个二分类的评价,计算每个二分类的F1 score,n个F1 score的平均值即为Macro F1。

微平均Micro-average

Micro F1:将n分类的评价拆成n个二分类的评价,将n个二分类评价的TP、FP、TN、FN对应相加,计算评价准确率和召回率,由这2个准确率和召回率计算的F1 score即为Micro F1。
(TP + FP) / (TP + TN + FP + FN),实际上就是accuracy,分母就是输入分类器的预测样本个数,分子就是预测正确的样本个数(无论类别)。

一般来讲,Macro F1、Micro F1高的分类效果好。Macro F1受样本数量少的类别影响大。
宏平均比微平均更合理,但也不是说微平均一无是处,具体使用哪种评测机制,还是要取决于数据集中样本分布。

例:

考虑现在输入分类器的样本有10个,他们属于类别A B C。

假设这10个样本的真实类标为(有序)和分类器预测的类标分别是:

真实:A A A C B C A B B C
预测:A A C B A C A C B C

precision(A) = 3(正确预测为A类的样本个数为3) / 4(预测为A类的样本数为4) = 0.75 recall(A) = 3 / 4(真实A类样本有4个) = 0.75

precision(B) = 1 / 2 = 0.5 recall(B) = 1 / 3 = 0.3333

precision© = 2 / 3 = 0.6667 recall© = 2 / 3 = 0.6667

F值计算出来之后,取算术平均就是Macro-average

Micro-average = 6(预测正确的样本个数) / 10 = 0.6

三、ROC曲线和AUC

ROC的全名叫做Receiver Operating Characteristic,即受试者工作特征曲线。

ROC关注两个指标:

True Positive Rate ( TPR ) = TP / [ TP + FN] ,TPR真阳性率,即判断为正例且实际为正例的个数占全部正例的比例,即precision

False Positive Rate( FPR ) = FP / [ FP + TN] ,FPR假阳性率,即判断为正例但实际为负例的比例

ROC曲线只对二分类问题有效。而尤其当正负样本不平衡时,这种评价比起准确率更有效(只要想想把垃圾邮件分类器如果把所有邮件都识别为不是垃圾邮件,也可以得到90%以上的准确率,但这没有任何意义)。

在ROC 空间中,每个点的横坐标是FPR,纵坐标是TPR,这也就描绘了分类器在TP(真正的正例)和FP(错误的正例)间的trade-off。ROC的主要分析工具是一个画在ROC空间的曲线——ROC curve。

我们知道,对于二值分类问题,实例的值往往是连续值,我们通过设定一个阈值,将实例分类到正类或者负类(比如大于阈值划分为正类)。因此我们可以变化阈值,根据不同的阈值进行分类,根据分类结果计算得到ROC空间中相应的点,连接这些点就形成ROC curve。

ROC curve经过(0,0)(1,1),实际上(0, 0)和(1, 1)连线形成的ROC curve实际上代表的是一个随机分类器。一般情况下,这个曲线都应该处于(0, 0)和(1, 1)连线的上方。

用ROC curve来表示分类器的performance很直观好用。可是,人们总是希望能有一个数值来标志分类器的好坏。

于是Area Under roc Curve(AUC) 就出现了。AUC(Area Under Curves)指的是ROC曲线下的面积,该指标能较好的概括不平衡样本分类器的性能而成为很多数据挖掘竞赛的判定标准。由于仅有有限个样本,无论训练样本还是测试样本,因此无法获得最精确的ROC曲线,从而无法精确计算AUC。在实际计算中,使用类似微积分的方法,用梯形面积的和去近似。通常,AUC的值介于0.5到1.0之间,较大的AUC代表了较好的Performance。

AUC的物理意义
假设分类器的输出是样本属于正类的socre(置信度),则AUC的物理意义为,任取一对(正、负)样本,正样本的score大于负样本的score的概率。从而我们能够理解对于AUC而言,并不关心具体预测的结果是标签或者概率,也不需要卡什么阈值,只要在预测结果之间有排序即可。

P/R和ROC是两个不同的评价指标和计算方式,一般情况下,检索用前者,分类、识别等用后者。

四、python 计算混淆矩阵和accuracy、precision、recall、f1-score

一些机器学习库封装了计算评价指标的库,pytorch只能自己计算。

confusion_matrix1 = np.array([[0 for _ in range(len(tag2idx))] for _ in range(len(tag2idx))])
n1 = len(confusion_matrix1)
       
with torch.no_grad():
    for bidx, batch in enumerate(testset_loader):
		......
        predict_tags = model(seq, mask)
        pre_tag = torch.argmax(predict_tags, dim=1)      # 预测值
        tag = tag.view(-1)                                                 # 真实值
        for i in range(len(tag)):
            confusion_matrix1[tag[i]][pre_tag[i]] += 1
        for i in range(len(punctag)):
            confusion_matrix2[punctag[i]][pre_punctag[i]] += 1
            
for i in range(n1):
    rowsum, colsum = sum(confusion_matrix1[i]), sum(confusion_matrix1[r][i] for r in range(n1))
    try:
        precision.append(confusion_matrix1[i][i] / float(colsum))
        recall.append(confusion_matrix1[i][i] / float(rowsum))
        f1score.append(
            2 * precision[i] * recall[i] / (precision[i] + recall[i]) if (precision[i] + recall[i]) > 0 else 0)
        print(
                "precision: {:.4f}  recall: {:.4f}  f1: {:.4f} ".format(precision[i], recall[i], f1score[i]))
    
    except ZeroDivisionError:
        precision.append(0)
        recall.append(0)
        f1score.append(0)
        print(
                "precision: {}  recall: {}  f1: {} ".format(0, 0, 0))
              
correct1 = [confusion_matrix1[i][i] for i in range(len(tag2idx))]
total_acc1 = sum(correct1) / sum(map(sum, confusion_matrix1))
print("total accuracy: {:.4} ".format(total_acc1))

参考网址:
多类分类(Multi-label classification)性能评价之宏平均(macro-average)与微平均(micro-average)
二分类与多分类评估(混淆矩阵,准确率,召回率,F1,mAP)
对多分类数据的模型比较选择,应该参考什么指标?
理解AUC的意义

发布了143 篇原创文章 · 获赞 161 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/vivian_ll/article/details/99627094