《机器学习(周志华)》笔记--模型的评估与选择(5)--衡量分类任务的性能指标:精准度、召回率与F1 Score计算

五、衡量分类任务的性能指标

  3、精准度与召回率

  精准率(Precision)指的是模型预测为 Positive 时的预测准确度,其计算公式如下:

                       

  召回率(Recall)指的是我们关注的事件发生了,并且模型预测正确了的比值,其计算公式如下:

                        

混淆矩阵:

真实预测01
0 TN FP
1 FN TP

 

举例:

  假如癌症检测系统的混淆矩阵如下:

真实预测01
0 9978 12
1 2 8

  (1)该系统的精准率 =8/(8+12)=0.4。

    从计算出的精准率可以看出,如果有 100 个人被预测成患有癌症,那么其中有 40 人是真的患有癌症。也就是说,精准率越高,那么癌症检测系统预测某人患有癌症的可信度就越高。

  (2)该系统的召回率 =8/(8+2)=0.8。

    从计算出的召回率可以看出,假设有 100 个患有癌症的病人使用这个系统进行癌症检测,系统能够检测出 80 人是患有癌症的。也就是说,召回率越高,那么我们感兴趣的对象成为漏网之鱼的可能性越低。

   精准率与召回率之间的关系:

    假设有这么一组数据,菱形代表 Positive,圆形代表 Negtive 。

      

     现在需要训练一个模型对数据进行分类,假如该模型非常简单,就是在数据上画一条线作为分类边界。模型认为边界的左边是 Negtive,右边是 Positive。如果该模型的分类边界向左或者向右移动的话,模型所对应的精准率和召回率如下图所示:

           

    从上图可知,模型的精准率变高,召回率会变低,精准率变低,召回率会变高。

  到底应该使用精准率还是召回率作为性能指标,其实是根据具体业务来决定的。比如我现在想要训练一个模型来预测我关心的股票是涨( Positive )还是跌( Negtive ),那么我们应该主要使用精准率作为性能指标。因为精准率高的话,则模型预测该股票要涨的可信度就高(很有可能赚钱!)。比如现在需要训练一个模型来预测人是( Positive )否( Negtive )患有艾滋病,那么我们应该主要使用召回率作为性能指标。因为召回率太低的话,很有可能存在漏网之鱼(可能一个人本身患有艾滋病,但预测成了健康),这样就很可能导致病人错过了最佳的治疗时间,这是非常致命的。

  4、F1 Score

  精准率变高,召回率会变低,精准率变低,召回率会变高。那如果想要同时兼顾精准率和召回率,这个时候就可以使用 F1 Score 来作为性能度量指标了。

  F1 Score 是统计学中用来衡量二分类模型精确度的一种指标。它同时兼顾了分类模型的准确率和召回率。 F1 Score 可以看作是模型准确率和召回率的一种加权平均,它的最大值是 1,最小值是 0。其公式如下:

                                  

举例:

模型\指标

精准率

召回率

F1

A

0.2

0.7

0.311

B

0.7

0.2

0.311

C

0.8

0.7

0.746

D

0.2

0.3

0.24


  从上述 4 个模型的各种性能可以看出,模型C的精准率和召回率都比较高,因此它的 F1 Score 也比较高。而其他模型的精准率和召回率要么都比较低,要么一个低一个高,所以它们的 F1 Score 比较低。

  这也说明了只有当模型的精准率和召回率都比较高时 F1 Score 才会比较高。这也是 F1 Score 能够同时兼顾精准率和召回率的原因。

代码实现:

import numpy as np

def precision_score(y_true, y_predict):
    '''
    计算精准率并返回
    :param y_true: 真实类别,类型为ndarray
    :param y_predict: 预测类别,类型为ndarray
    :return: 精准率,类型为float
    '''

    def TN(y_true, y_predict):
        return np.sum((y_true == 0) & (y_predict == 0))
    
    def FP(y_true, y_predict):
        return np.sum((y_true == 0) & (y_predict == 1))

    def FN(y_true, y_predict):
        return np.sum((y_true == 1) & (y_predict == 0))

    def TP(y_true, y_predict):
        return np.sum((y_true == 1) & (y_predict == 1))

    return TP(y_true, y_predict)/(TP(y_true, y_predict)+FP(y_true, y_predict))
 

def recall_score(y_true, y_predict):
    '''
    计算召回率并召回
    :param y_true: 真实类别,类型为ndarray
    :param y_predict: 预测类别,类型为ndarray
    :return: 召回率,类型为float
    '''

    def TN(y_true, y_predict):
        return np.sum((y_true == 0) & (y_predict == 0))
    
    def FP(y_true, y_predict):
        return np.sum((y_true == 0) & (y_predict == 1))

    def FN(y_true, y_predict):
        return np.sum((y_true == 1) & (y_predict == 0))

    def TP(y_true, y_predict):
        return np.sum((y_true == 1) & (y_predict == 1))

    return TP(y_true, y_predict)/(TP(y_true, y_predict)+FN(y_true, y_predict))


def f1_score(precision, recall):
    '''
    计算f1 score并返回
    :param precision: 模型的精准率,类型为float
    :param recall: 模型的召回率,类型为float
    :return: 模型的f1 score,类型为float
    '''

   score = (2*precision*recall)/(precision+recall)
    return score 
posted @ 2020-01-14 22:45  泰初  阅读(1383)  评论(0编辑  收藏  举报