sklearn.metrics.accuracy_score/precision_score/recall_score、micro/macro/weighted(准确率、召回率)

总结:

假设原始样本中有两类,其中:
1:总共有 P个类别为1的样本,假设类别1为正例。 
2:总共有N个类别为0 的样本,假设类别0为负例。 
经过分类后:
3:有 TP个类别为1 的样本被系统正确判定为类别1,FN 个类别为1 的样本被系统误判定为类别 0,显然有P=TP+FN; 
4:有 FP 个类别为0 的样本被系统误判断定为类别1,TN 个类别为0 的样本被系统正确判为类别 0,显然有N=FP+TN; 

比如:trueY = [1,1,2,2,2,3]

          predY = [2,1,1,3,2,1]
那么:
精确度(Precision):( 以predY的角度考虑,所有分类为1的值中正确的比重 1/(1+1+1)=0.33 )
P = TP/(TP+FP) ;  反映了被分类器判定的正例中真正的正例样本的比重( 

准确率(Accuracy)
A = (TP + TN)/(P+N) = (TP + TN)/(TP + FN + FP + TN);    

反映了分类器统对整个样本的判定能力——能将正的判定为正,负的判定为负 
 
召回率(Recall),也称为查全率--True Positive Rate:( 以trueY的角度考虑,所有真实类别为1的值(位于trueY中的)被正确分类为1的比重 1/(1+1)=0.5 )
R = TP/(TP+FN) = 1 - FN/T;  反映了被正确判定的正例占总的正例的比重 

转移性(Specificity,不知道这个翻译对不对,这个指标用的也不多),

也称为 True NegativeRate 
S = TN/(TN + FP) = 1 – FP/N;   明显的这个和召回率是对应的指标,

只是用它在衡量类别0 的判定能力。 
 
F-measure or balanced F-score
F = 2 *  召回率 *  准确率/ (召回率+准确率);这就是传统上通常说的F1 measure,

为什么会有这么多指标呢?
        这是因为模式分类和机器学习的需要。判断一个分类器对所用样本的分类能力或者在不同的应用场合时,需要有不同的指标。
 
因此在统计信号分析中,有另外两个指标来衡量分类器错误判断的后果:
漏警概率(Missing Alarm)
MA = FN/(TP + FN) = 1 – TP/T = 1 - R;  反映有多少个正例被漏判了(我们这里就是真正的导弹信号被判断为模拟信号,可见MA此时为 33.33%,太高了) 
虚警概率(False Alarm)
FA = FP / (TP + FP) = 1 – P;反映被判为正例样本中,有多少个是负例。 

统计信号分析中,希望上述的两个错误概率尽量小。而对分类器的总的惩罚旧

是上面两种错误分别加上惩罚因子的和:COST = Cma *MA + Cfa * FA。

不同的场合、需要下,对不同的错误的惩罚也不一样的。像这里,我们自然希望对漏警的惩罚大,

因此它的惩罚因子 Cma 要大些。 

       个人观点:虽然上述指标之间可以互相转换,但在模式分类中,一般用 P、R、A 三个指标,不用MA和 FA。而且统计信号分析中,也很少看到用 R 的。

为什么先讲Precision和Recall呢?因为IR中很多算法的评估都用到Precision和Recall来评估好坏。所以我先讲什么是"好人",再告诉你他是"好人"




查准与召回(Precision & Recall)

先看下面这张图来理解了,后面再具体分析。下面用P代表Precision,R代表Recall

   通俗的讲,Precision 就是检索出来的条目中(比如网页)有多少是准确的,Recall就是所有准确的条目有多少被检索出来了。

下面这张图介绍True Positive,False Negative等常见的概念,P和R也往往和它们联系起来。

 我们当然希望检索的结果P越高越好,R也越高越好,但事实上这两者在某些情况下是矛盾的。比如极端情况下,我们只搜出了一个结果,且是准确的,那么P就是100%,但是R就很低;而如果我们把所有结果都返回,那么必然R是100%,但是P很低。

因此在不同的场合中需要自己判断希望P比较高还是R比较高。如果是做实验研究,可以绘制Precision-Recall曲线来帮助分析(我应该会在以后介绍)

F1  Measure

前面已经讲了,P和R指标有的时候是矛盾的,那么有没有办法综合考虑他们呢?我想方法肯定是有很多的,最常见的方法应该就是F Measure了,有些地方也叫做F Score,都是一样的。

F Measure是Precision和Recall加权调和平均:

F = (a^2+1)P*R / a^2P +R

当参数a=1时,就是最常见的F1了:

F1 = 2P*R / (P+R)

很容易理解,F1综合了P和R的结果

具体介绍

  • 1、accuracy即我们通常理解的准确率,计算的时候是指在预测值pred与目标值target之间重叠的部分的大小除以pred的大小(或target的大小,因为sklearn要求pred与target大小必须一致)。
  • 比如target=[2,2,2,3,2] pred=[2,2,1,3,4]

  • 此时重叠的部分为pred[0]、pred[1]、pred[3],accuracy=3/5=0.6

    而precision_score意思类似,但不完全一样,它是从pred的角度考虑,意思是我虽然预测了这么多个,但有几个预测对了?占比多少?这就是precision。
    举例:

  • target=np.array([1,1,1,1,1])
    pred=np.array([2,2,1,1,1])
    p=precision_score(target,pred)
    print(p)#1.0

    的结果为1.0(看不懂?马上解释);
    但如果是accuracy_score(target,pred),就会输出0.60(预测了5个,对了3个)  此外,

  • p=precision_score(target,pred)

    其实等价于

  • p=precision_score(target,pred,average='binary',pos_label=1)

    average='binary'表示pred当中(最多)只有两种标签(此处是1,2),pos_label=1表示最后输出的结果是针对类别值"1"的计算结果。

    如果改成pos_label=2

  • p=precision_score(target,pred,average='binary',pos_label=2)

    则表示计算结果是针对类别为"2"的统计结果,结果为0.0(因为pred中有两个2,但都预测错了,所以为0)。

    pos_label这个参数只有average='binary'时管用,若pred中出现3种及以上类别的标签,则pos_label参数即使设置了也会被忽略。

  • 2、下面说说average参数的作用,当pred当中有3种或以上类别时,average的值只能取[None, 'micro', 'macro', 'weighted']当中的一种,其中,有趣的是,当average='micro'时,precision_score(target,pred,average='micro')等价于accuracy的算法,就是看预测对的标签总个数,再除以pred的大小。
  • 而当average='macro'时,会计算每个种类标签的precision_score,再取平均(不考虑各个类别的样本分布差异)。例如:

  • target=np.array([1,1,2,3,3])
    pred=np.array([2,2,1,3,4])
    precision_score(target,pred,average='macro')

    的结果为0.25,怎么算出来的0.25?

    这样算:首先确定,pred中一共是4个类别(1,2,3,4),预测对的只有pred[3],

  • 类别1的precision=0/1(pred中只有1个标签1,预测对了0个)结果为0
    类别2的precision=0/2(pred中有2个标签2,预测对了0个),结果为0
    类别3的precision=1/1(pred中有1个标签3,预测对了1个),结果为1
    类别4的precision=0/1(pred中有1个标签4,预测对了0个),结果为0

    再取平均(不考虑类别的分布差异):(0+0+1+0)/4=0.25。

    Macro另外一个需要注意的地方在于,它在做平均的时候,它认为的类别数不是看target有多少个类别,也不是看pred有多少个类别,而是两者取并集,作为总的类别数。

    例如,

  • target=np.array([1,1,3,3,4])
    pred = np.array([1,1,2,0,0,])
    print(precision_score(target,pred,average='macro'))#输出0.2

    输出0.2,你敢信?并且报了一个警告:

  • D:\Anaconda3\lib\site-packages\sklearn\metrics\_classification.py:1221: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
      _warn_prf(average, modifier, msg_start, len(result))

    说那些没有被预测的类别的precision_score默认为0,

    于是,就是类别1的预测precision_score=1,但一共有0,1,2,3,4,共5类别,而其余类别的precison均为0,所以1/5=0.2。

    而当average='weighted'时,前面的步骤跟macro相同,分别计算pred中各个类别的precision_score,但汇总时则会考虑各个类别的样本的分布差异。例如,

  • target=np.array([1,1,2,2,3,3])
    pred=np.array([2,2,1,3,4,3])
    precision_score(target,pred,average='macro')

    输出0.125

    计算过程:pred中有4个类别,类别1、2、4预测正确的个数为0,precision_score均为0,而类别3,预测了2个(pred[3]、pred[5]),仅对了1个(pred[5]),precision_score=0.5,再取平均(0+0+0.5+0)/4=0.125,而

  • precision_score(target,pred,average='weighted')

    则输出0.1666

    因为average='weighted'时,会考虑各个类别(在target中,而非pred中)的分布比例,比如,类别1在target中出现占比为2/6,同理类别3的占比为2/6=1/3,
    因此最后结果等于0*1/3+0*1/3+0.5*1/3+0*1/3=1/6=0.1666

  • 3、再讲讲召回率recall_score的计算方法。
  • 举例:

  • target=np.array([1,2,2,2,3,3])
    pred=np.array([2,2,1,3,4,3])
    recall_score(target,pred,average='macro')

    输出0.20833333333333331,其实就是5/24。怎么来的?

    首先依据定义,pred的召回率是指pred中出现的各类标签,预测正确的次数占target中该类标签数的比例。

  • 类别1的recall=0/1=0
    类别2的recall=1/3(1个,即pred[1]预测正确,target中类别2出现了3次)
    类别3的recall=1/2(1个,即pred[5]预测正确,target中类别3出现2次)
    类别4的recall=0,类别4在target中没有出现,因此预测错误。

    最后求平均:(1/3+1/2)/4=5/24=0.20833333333333334

    同理,average='weighted'时,

  • recall_score(np.array([1,2,2,2,3,3]),np.array([2,2,1,3,4,3]),average='weighted')

    输出0.333333=1/3

    即分别用标签1、2、3、4的recall_score再乘上它们再target中的占比,0*1/6+1/3*3/6+1/2*2/6+0*0/6=1/3。

  • 4、另外,需要注意的是sklearn.metrics模块中的precision_score,recall_score中对比的target和pred参数都是一维数组(若不是一维数组,则会认为某一行代表一个样本有多个标签),因此在模型的批训练时,获得的预测结果,需要先转换成一维数组再计算precision,recall,f1等指标。
  • 参考:https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_score.html
  • 11
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值