metrics.classification_report函数记录

机器学习/深度学习中,我们经常使用sklearn包中的metrics.classification_report来输出评价指标。本文主要是通过示例方式来记录该函数的常见输入与输出的含义。

示例1

>>> from sklearn.metrics import classification_report
>>> y_true = [0, 3, 2, 2, 1, 1, 4, 3, 2, 4, 1, 0, 0]
>>> y_pred = [0, 3, 1, 2, 1, 2, 4, 3, 2, 2, 1, 3, 0]
>>> print(classification_report(y_true, y_pred))
              precision    recall  f1-score   support
           0       1.00      0.67      0.80         3
           1       0.67      0.67      0.67         3
           2       0.50      0.67      0.57         3
           3       0.67      1.00      0.80         2
           4       1.00      0.50      0.67         2
    accuracy                           0.69        13
   macro avg       0.77      0.70      0.70        13
weighted avg       0.76      0.69      0.70        13

其中,
accuracy表示准确率,也即正确预测样本量与总样本量的比值,即9/13=0.69
macro avg表示宏平均,表示所有类别对应指标的平均值,即
      precision = (1.0+0.67+0.5+0.67+1.0)/5=0.77
      recall = (0.67+0.67+0.67+1.0+0.5)/5=0.70
      f1-score = (0.8+0.67+0.57+0.8+0.67)/5=0.70
weighted avg表示带权重平均,表示类别样本占总样本的比重与对应指标的乘积的累加和,即
      precision = 1.0*3/13 + 0.67*3/13 + 0.5*3/13 + 0.67*2/13 + 1.0*2/13=0.76
      recall = 0.67*3/13 + 0.67*3/13 + 0.67*3/13 + 1.0*2/13 + 0.5*2/13=0.69
      f1-score = 0.8*3/13 + 0.67*3/13 + 0.57*3/13 + 0.8*2/13 + 0.67*2/13=0.70

示例2

>>> from sklearn.metrics import classification_report
>>> label = {0: '科技', 1: '体育', 2: '社会', 3: '娱乐', 4: '股票'}
>>> y_true = [0, 3, 2, 2, 1, 1, 4, 3, 2, 4, 1, 0, 0]
>>> y_pred = [0, 3, 1, 2, 1, 2, 4, 3, 2, 2, 1, 3, 0]
>>> print(classification_report(y_true, y_pred, target_names=['科技', '体育', '社会', '娱乐', '股票']))
              precision    recall  f1-score   support
          科技       1.00      0.67      0.80         3
          体育       0.67      0.67      0.67         3
          社会       0.50      0.67      0.57         3
          娱乐       0.67      1.00      0.80         2
          股票       1.00      0.50      0.67         2
    accuracy                           0.69        13
   macro avg       0.77      0.70      0.70        13
weighted avg       0.76      0.69      0.70        13

示例1跟示例2的区别是示例2加入了target_names参数,该参数的主要作用是将实际的类别与输出id对应起来。

示例3

>>> print(metrics.classification_report(true_y, pred_y, target_names=['体育', '社会', '娱乐', '股票', '科技']))
              precision    recall  f1-score   support
          体育       1.00      0.67      0.80         3
          社会       0.67      0.67      0.67         3
          娱乐       0.50      0.67      0.57         3
          股票       0.67      1.00      0.80         2
          科技       1.00      0.50      0.67         2
    accuracy                           0.69        13
   macro avg       0.77      0.70      0.70        13
weighted avg       0.76      0.69      0.70        13

对比示例2跟示例3,我们可以看到参数target_names中元素的顺序与输出id的大小顺序相同。

示例4
对于classification_report,我们通常会看到如下的输出

>>> import numpy as np
>>> from sklearn.metrics import classification_report
>>> y_true = np.array([[1, 0, 1, 0, 0],
                       [0, 1, 0, 1, 1],
                       [1, 1, 1, 0, 1]])
>>> y_pred = np.array([[1, 0, 0, 0, 1],
                       [0, 1, 1, 1, 0],
                       [1, 1, 1, 0, 0]])
>>> print(classification_report(y_true, y_pred, digits=3))
              precision    recall  f1-score   support

           0      1.000     1.000     1.000         2
           1      1.000     1.000     1.000         2
           2      0.500     0.500     0.500         2
           3      1.000     1.000     1.000         1
           4      0.000     0.000     0.000         2

   micro avg      0.750     0.667     0.706         9
   macro avg      0.700     0.700     0.700         9
weighted avg      0.667     0.667     0.667         9
 samples avg      0.722     0.639     0.675         9

对比示例1跟示例4两个classification_report函数的输出,我们可以看到,示例1输出的是一个accuracy,外加两个平均值,而示例4输出的是四个平均值。
造成这种不同的原因是示例4是多标签分类,而示例1是一个单标签分类。

关于示例4输出的四个平均值,我们看看官方的解释

average : {'binary', 'micro', 'macro', 'samples','weighted'},
default=None
If None, the scores for each class are returned. Otherwise, this
determines the type of averaging performed on the data:
'binary':
Only report results for the class specified by pos_label.
This is applicable only if targets (y_{true,pred}) are binary.
'micro':
Calculate metrics globally by counting the total true positives,
false negatives and false positives.
'macro':
Calculate metrics for each label, and find their unweighted
mean. This does not take label imbalance into account.
'weighted':
Calculate metrics for each label, and find their average weighted
by support (the number of true instances for each label). This
alters 'macro' to account for label imbalance; it can result in an
F-score that is not between precision and recall.
'samples':
Calculate metrics for each instance, and find their average (only
meaningful for multilabel classification where this differs from
:func:accuracy_score).

其中,micro avgmacro avgweighted avg针对的对象都是label,而samples avg针对的对象则是instance。
label表示示例4中值为1的三个样本中的元素,而instance表示实际的三个样本,具体不同可参考下面四个平均值的计算过程。

说明:classification_report函数的输出结果标签中0、1、2、3、4表示的是每个样本的5列,每列代表一个标签。因此,对于标签0,表示样本中元素处于第一列的1;对于标签1,表示样本中元素处于第一列的1;以此类推。

micro avg表示微平均,表示所有类别中预测正确量与总样本量的比值,即
      precision = (2+2+1+1) / 8 = 0.750
      recall = (2+2+1+1) / 9 = 0.667
      f1-score = 2*precision*recall/(precision+recall) = 0.706
macro avg表示宏平均,表示所有类别对应指标的平均值,即
      precision = (1.0+1.0+0.5+1.0+0.0)/5 = 0.700
      recall = (1.0+1.0+0.5+1.0+0.0)/5 = 0.700
      f1-score = (1.0+1.0+0.5+1.0+0.0)/5 = 0.700
weighted avg表示带权重平均,表示类别样本占总样本的比重与对应指标的乘积的累加和,即
      precision = 1.0*2/9 + 1.0*2/9 + 0.5*2/9 + 1.0*1/9 + 0.0*2/9 = 0.667
      recall = 1.0*2/9 + 1.0*2/9 + 0.5*2/9 + 1.0*1/9 + 0.0*2/9 = 0.667
      f1-score = 1.0*2/9 + 1.0*2/9 + 0.5*2/9 + 1.0*1/9 + 0.0*2/9 = 0.667
samples avg表示带权重平均,表示类别样本占总样本的比重与对应指标的乘积的累加和,即
      precision = (1/2 + 2/3 + 3/3) / 3 = 0.722
      其中,1/2表示第1行中,标签值为1的预测准确率;2/3表示第二行中标签值为1的预测准确率,以此类推
      recall = (1/2 + 2/3 + 3/4) / 3 = 0.639
      f1-score = ((2*(1/2)*(1/2))/(1/2+1/2) + (2*(2/3)*(2/3))/(2/3+2/3) + (2*(3/3)*(3/4))/(3/3+3/4)) / 3 = 0.675
      其中,f1-score的计算过程中,分别为三个样本中标签值为1的f1值的平均值。

至此,classification_report函数的常见输出结果介绍完成了,在此做个记录,方便自己与他人后续查阅。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容