多分类性能评估方法

多分类性能评估方法

  • [1. micro-averaging(微平均)](#1. micro-averaging(微平均))
  • [2. macro-averaging(宏平均)](#2. macro-averaging(宏平均))
  • [3. weighted-averaging(加权平均)](#3. weighted-averaging(加权平均))

在评估多分类模型性能时,我们经常会使用一些指标来衡量其表现。其中,micro-averaging、macro-averaging 和 weighted-averaging 是常见的评估指标之一。它们在衡量分类器的精确度、召回率和 F1 分数时发挥着重要作用。

假设:三分类的真实标签和预测标签如下:

python 复制代码
y_true = ['好评', '好评', '好评', '中评', '中评', '差评', '差评', '差评', '差评', '差评']
y_pred = ['好评', '好评', '好评', '好评', '中评', '差评', '好评', '中评', '差评', '中评']

对应的混淆矩阵:

python 复制代码
    好评  中评  差评
好评   3   0   0
中评   1   1   0
差评   1   2   2

每个类别的评估分数:

python 复制代码
精确率:         [0.6        0.33333333      1.        ]
召回率:         [1.         0.5             0.4       ]
f1-score:     [0.75       0.4             0.57142857]
python 复制代码
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score
from sklearn.metrics import confusion_matrix
import pandas as pd


if __name__ == '__main__':

    y_true = ['好评', '好评', '好评', '中评', '中评', '差评', '差评', '差评', '差评', '差评']
    y_pred = ['好评', '好评', '好评', '好评', '中评', '差评', '好评', '中评', '差评', '中评']

    # 混淆矩阵
    labels = ['好评', '中评', '差评']
    matrix = confusion_matrix(y_true, y_pred, labels=labels)
    matrix = pd.DataFrame(matrix, columns=labels, index=labels)
    print(matrix)
    print()

    # 返回所有类别分数
    result = precision_score(y_true, y_pred, average=None, labels=['好评', '中评', '差评'])
    print('精确率:\t\t', result)

    result = recall_score(y_true, y_pred, average=None, labels=['好评', '中评', '差评'])
    print('召回率:\t\t', result)

    result = f1_score(y_true, y_pred, average=None, labels=['好评', '中评', '差评'])
    print('f1-score:\t', result)

输出即是以上结果

缩写 全称 含义
TP True Positive(真正) 实际为正类,模型也预测为正类(正确地预测为正)
FN False Negative(假负) 实际为正类,但模型预测为负类(错把正类判为负类)
FP False Positive(假正) 实际为负类,但模型预测为正类(错把负类判为正类)
TN True Negative(真负) 实际为负类,模型也预测为负类(正确地预测为负)

1. micro-averaging(微平均)

做法:将所有类别的 TP、FP、FN 累加,然后再计算 Precision、Recall、F1。

特点对每个样本等权处理更关注整体表现

适用场景:当你希望模型整体上表现好(尤其在样本数差异大时)。

P r e c i s i o n m i c r o = ∑ i = 1 N T P i ∑ i = 1 N ( T P i + F P i ) \displaystyle Precision_{micro}=\dfrac{\sum_{i=1}^{N}TP_i}{\sum_{i=1}^{N}(TP_i+FP_i)} Precisionmicro=∑i=1N(TPi+FPi)∑i=1NTPi

R e c a l l m i c r o = ∑ i = 1 N T P i ∑ i = 1 N ( T P i + F N i ) \displaystyle Recall_{micro}=\dfrac{\sum_{i=1}^{N}TP_i}{\sum_{i=1}^{N}(TP_i+FN_i)} Recallmicro=∑i=1N(TPi+FNi)∑i=1NTPi

F 1 m i c r o = 2 ⋅ P r e c i s i o n m i c r o ⋅ R e c a l l m i r c o P r e c i s i o n m i c r o + R e c a l l m i c r o F1_{micro}=\dfrac{2 \cdot Precision_{micro} \cdot Recall_{mirco}}{Precision_{micro}+Recall_{micro}} F1micro=Precisionmicro+Recallmicro2⋅Precisionmicro⋅Recallmirco

  • N N N是类别总数
  • T P i TP_i TPi是第 i i i个类的 T P TP TP之和
  • F P i FP_i FPi是第 i i i个类的 F P FP FP之和
  • F N i FN_i FNi是第 i i i个类的 F N FN FN之和

我们以前面例子为例:

python 复制代码
好评:
TP = 3 (预测为好评且实际为好评)
FP = 1+1 = 2 (预测为好评但实际为中评和差评)
TN = 1+2+2 = 5 (预测不是好评且实际也不是好评,包括中评和差评)
FN = 0+0 = 0 (实际为好评但预测不是好评)

中评:
TP = 1 (预测为中评且实际为中评)
FP = 0+2 = 2 (预测为中评但实际为好评和差评)
TN = 3+2+1+0 = 6 (预测不是中评且实际也不是中评,包括好评和差评)
FN = 1+0 = 1 (实际为中评但预测不是中评)

差评:
TP = 2 (预测为差评且实际为差评)
FP = 0+0 = 0 (没有将其他类别预测为差评)
TN = 3+1+1 = 5 (预测不是差评且实际也不是差评,包括好评和中评)
FN = 1+2 = 3 (实际为差评但预测不是差评)


每个类别的 TP、FP、TN、FN 值分别是:
好评:TP=3, FP=2, TN=5, FN=0
中评:TP=1, FP=2, TN=6, FN=1
差评:TP=2, FP=0, TN=6, FN=3


此时:
TP = 3 + 1 + 2 = 6
FP = 2 + 2 + 0 = 4
TN = 5 + 7 + 6 = 18
FN = 0 + 1 + 3 = 4

使用上述计算得到的 TP、FP、TN、FN 值:

  • micro-averaged precisionTP/(TP+FP) = 6/(6+4) = 0.6
  • micro-averaged recallTP/(TP+FN) = 6/(6+4) = 0.6
  • micro-averaged f1-score2*(micro-averaged precision * micro-averaged recall) / (micro-averaged precision+micro-averaged recall) = 2*(0.6*0.6)/(0.6+0.6) = 0.6

下面用代码来实现一下

python 复制代码
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score


if __name__ == '__main__':

    y_true = ['好评', '好评', '好评', '中评', '中评', '差评', '差评', '差评', '差评', '差评']
    y_pred = ['好评', '好评', '好评', '好评', '中评', '差评', '好评', '中评', '差评', '中评']

    result = precision_score(y_true, y_pred, average='micro')
    print('精确率:\t\t', result)

    result = recall_score(y_true, y_pred, average='micro')
    print('召回率:\t\t', result)

    result = f1_score(y_true, y_pred, average='micro')
    print('f1-score:\t', result)

可以看到

python 复制代码
精确率:		 0.6
召回率:		 0.6
f1-score:	 0.6

2. macro-averaging(宏平均)

做法 :先分别计算每个类别的 Precision、Recall、F1,然后对这些类别的指标 取平均

特点每个类别权重相同忽略类别不平衡问题

适用场景:当你希望模型对所有类别都一样重视时(比如类别数量差不多,但样本数量可能差很多)。

P r e c i s i o n m a c r o = 1 N ∑ i = 1 N T P i T P i + F P i \displaystyle Precision_{macro}=\dfrac{1}{N}\sum_{i=1}^{N}\dfrac{TP_i}{TP_i+FP_i} Precisionmacro=N1i=1∑NTPi+FPiTPi

R e c a l l m a c r o = 1 N ∑ i = 1 N T P i T P i + F N i \displaystyle Recall_{macro}=\dfrac{1}{N}\sum_{i=1}^{N}\dfrac{TP_i}{TP_i+FN_i} Recallmacro=N1i=1∑NTPi+FNiTPi

F 1 m a c r o = 1 N ∑ i = 1 N 2 ⋅ P r e c i s i o n i ⋅ R e c a l l i P r e c i s i o n i + R e c a l l i F1_{macro}=\displaystyle \dfrac{1}{N}\sum_{i=1}^{N}\dfrac{2 \cdot Precision_i \cdot Recall_i}{Precision_i+Recall_i} F1macro=N1i=1∑NPrecisioni+Recalli2⋅Precisioni⋅Recalli

macro-averaging 计算每个类别的精确度、召回率和 F1 分数,然后对它们取算术平均值。

python 复制代码
好评:
精确率:0.6
召回率:1.0
f1-score:0.75


中评:
精确率:0.33
召回率:0.5
f1-score:0.4


差评:
精确率:1
召回率:0.4
f1-score:0.57
  • macro-averaged precision : (0.6 + 0.33 + 1) / 3 = 0.64
  • macro-averaged recall:(1.0 + 0.5 + 0.4) / 3 = 0.63
  • macro-averaged f1-score:(0.75 + 0.4 + 0.57) / 3 = 0.57
python 复制代码
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score


if __name__ == '__main__':

    y_true = ['好评', '好评', '好评', '中评', '中评', '差评', '差评', '差评', '差评', '差评']
    y_pred = ['好评', '好评', '好评', '好评', '中评', '差评', '好评', '中评', '差评', '中评']

    result = precision_score(y_true, y_pred, average='macro')
    print('精确率:\t\t', result)

    result = recall_score(y_true, y_pred, average='macro')
    print('召回率:\t\t', result)

    result = f1_score(y_true, y_pred, average='macro')
    print('f1-score:\t', result)
python 复制代码
精确率:		 0.6444444444444445
召回率:		 0.6333333333333333
f1-score:	 0.5738095238095238

3. weighted-averaging(加权平均)

做法:先计算每个类别的指标,然后按该类别的样本数占比进行加权平均。

特点兼顾类别表现和样本分布,适合处理样本不均衡。

适用场景:样本分布不均时,比 macro 更合理;但仍保留对每类评估的透明度。

假设:共有 100 个样本:

好评:70,精度为:0.3

中评:20,精度为:0.6

差评:10,精度为:0.9

宏平均 = (0.3 + 0.6 + 0.9) / 3 = 0.6

在大多数样本上,模型只有 0.3 的精度,但是宏平均的精度却达到了 0.6。所以,宏平均不能真实的反映出模型在大多数样本上的表现。

weighted-averaging 计算每个类别的精确度、召回率和 F1 分数,然后将它们乘以每个类别的样本数或权重,最后将所有类别的加权平均值。它能够反应出样本在大多数样本上的表现。

加权平均:0.3 * 0.7 + 0.6 * 0.2 + 0.9 * 0.1 = 0.42,由此可以看到加权平均更加能够反映出模型在大多数样本上的表现。

接着前面的例子:

y_true = ['好评', '好评', '好评', '中评', '中评', '差评', '差评', '差评', '差评', '差评']

可知每个类别的权重分别为:0.3、0.2、0.5

  • weighted-averaged precision:0.6 * 0.3 + 0.33 * 0.2 + 1 * 0.5 = 0.746
  • weighted-averaged recall:1 * 0.3 + 0.5 * 0.2 + 0.4 * 0.5 = 0.6
  • weighted-averaged f1-score:0.75 * 0.3 + 0.4 * 0.2 + 0.57 * 0.5 = 0.59
python 复制代码
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score


if __name__ == '__main__':

    y_true = ['好评', '好评', '好评', '中评', '中评', '差评', '差评', '差评', '差评', '差评']
    y_pred = ['好评', '好评', '好评', '好评', '中评', '差评', '好评', '中评', '差评', '中评']

    result = precision_score(y_true, y_pred, average='weighted')
    print('精确率:\t\t', result)

    result = recall_score(y_true, y_pred, average='weighted')
    print('召回率:\t\t', result)

    result = f1_score(y_true, y_pred, average='weighted')
    print('f1-score:\t', result)
python 复制代码
精确率:		 0.7466666666666667
召回率:		 0.6
f1-score:	 0.5907142857142856
相关推荐
TMT星球17 分钟前
虎鲸文娱春苗编剧计划全面升级,已孵化20个剧本进入前期开发
大数据·人工智能
奔跑中的小象7 小时前
统信UOS + 天数AI卡部署SGLang服务手册
人工智能·uos·sglang·天数智芯
DevSecOps选型指南7 小时前
中国版Mythos,为何是悬镜安全灵脉CodeAI?
人工智能·安全
Shockang7 小时前
LangGraph 状态机实战
人工智能
刹那芳华19927 小时前
循环神经网络的从零开始实现(RNN)
人工智能·rnn·深度学习
阿童木写作7 小时前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
科技之门7 小时前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
宇宙第一小趴菜7 小时前
二、机器学习的应用领域和发展史
人工智能·机器学习
前端开发江鸟7 小时前
我写过 MCP Server,却一直以为 MCP 只有 Tool
人工智能
天国梦8 小时前
自习室智能化升级避坑指南:天学网AI智习室方案实测与选型建议
大数据·人工智能