我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

目光再次来回到sklearn.metrics里的模型评分机制,precision_score()recall_score()f1_score()accuracy_score()。这些评分机制分别代表:查准率、查全率、f1得分、精准度。除了精准度accuracy_score()外,其它这几个评分,都有个average参数,本文分析average参数的第一个用法:如何计算获得非阳性分类的模型结果评分。

苏南大叔:sklearn模型:求非阳性分类的precision/recall/f1评分 - sklearn得分再次审视
sklearn模型:求非阳性分类的precision/recall/f1评分(图1-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程所学所想。本文测试环境:win10python@3.12.0pandas@2.1.3scikit-learn@1.3.2

前文回顾

关于什么是模型的查准率、查全率、f1得分,参考下面这篇文章:

关于在二分类的情况下,如何理解模型的查准率、查全率、f1得分。可以参考:

如何理解分析sklearn.metrics.classification_report()功能?参考文章:

龙套角色

两个数据例子:

y_true  = [0, 1, 0, 1, 0]          # 二分类
y_pred  = [0, 1, 0, 1, 1]
y_true_ = [0, 1, 0, 1, 0, 1, 2]    # 多分类
y_pred_ = [0, 1, 0, 1, 1, 2, 2]

为什么准备两个例子呢?因为多分类的情况,计算各种得分的时候,必须添加average参数,否则报错。

ValueError: Target is multiclass but average='binary'. Please choose another average setting, one of [None, 'micro', 'macro', 'weighted'].

这里的average参数,本文仅仅取值None,不考虑其它的情况。

average=None

本文中,关于【目标属性】:

  • 一般来说,目标属性指的是阳性数据【标签为1】。
  • 但事实上,这种目标属性标签为哪个都可以计算。

【二分类可用】,本文的precision_score()recall_score()f1_score(),正常情况下求得都是阳性样本的数据。

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
a = accuracy_score(y_true, y_pred)    # 准确率
print("精确度  : ", a)

p = precision_score(y_true, y_pred)   # 查准率
r = recall_score(y_true, y_pred)      # 查全率
f = f1_score(y_true, y_pred)          # f1得分(f1值越高,模型预测越有价值)

print("查准率  : ", p)
print("查全率  : ", r)
print("f1得分  : ", f)

输出:

精确度  :  0.8
查准率  :  0.6666666666666666
查全率  :  1.0
f1得分  :  0.8

【二分类、多分类,都可用】如果添加一个average=None实参的话,返回值就会从统计【阳性样本】的float变量,变成统计所有目标标签的样本[float,float...]。

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
p2 = precision_score(y_true, y_pred, average=None)   # 查准率
r2 = recall_score(y_true, y_pred, average=None)      # 查全率
f2 = f1_score(y_true, y_pred, average=None)          # f1得分(f1值越高,模型预测越有价值)

print("查准率  : ", p2)
print("查全率  : ", r2)
print("f1得分  : ", f2)

输出:

查准率  :  [1.         0.66666667]
查全率  :  [0.66666667 1.        ]
f1得分  :  [0.8 0.8]

换成多分类(y_true_+y_pred_)的话,输出:

查准率  :  [1.         0.66666667 0.5       ]
查全率  :  [0.66666667 0.66666667 1.        ]
f1得分  :  [0.8        0.66666667 0.66666667]

查准率 precision_score()

查准率,被预测为目标标签的样本中(目前焦点在y_pred),真正是属于目标标签样本的比例。
公式表述:【真正被预测出目标标签的样本总数/y_test中被预测为属于目标的样本总数】。
如果用二分类的那种理论表述的话,就是【TP/(TP+FP)】。

苏南大叔再次解释的话,就是:

  • y_true中是目标属性,y_pred中也是目标属性,预测正确和事实相符,这种【预测对目标属性】数据的总数就是分子。
  • y_pred中被预测为目标属性的总计数值(包括预测对的,也包括预测错的),就是分母。

第三次解释:
查准率precision_score(),主打一个【不冤枉好人,也尽量不放过一个坏人】。查准率,查的就是:被预测为目标属性中,真正被预测正确的数据的比率。

举例解释二分类

y_true  = [0, 1, 0, 1, 0]          # 二分类
y_pred  = [0, 1, 0, 1, 1]
p2 = precision_score(y_true, y_pred, average=None)   # 查准率
# [1.         0.66666667]
  • 目标标签为0的话,被预测为0的数据有2个,真实的值都确实是0,所以标签0的查准率是100%。
  • 目标标签为1的话,被预测为1的数据有3个,真实的值两个是1,一个是0。所以标签1的查准率是66.7%。

举例解释多分类

y_true_ = [0, 1, 0, 1, 0, 1, 2]    # 多分类
y_pred_ = [0, 1, 0, 1, 1, 2, 2]
p2 = precision_score(y_true_, y_pred_, average=None)   # 查准率
# [1.         0.66666667 0.5       ]
  • 目标标签为0的话,被预测为0的样本有两个,都被预测正确,确实为0。所以,标签0的查准率为100%。
  • 目标标签为1的话,被预测为1的样本有三个,预测正确的数据是2个,预测错的数据是1个。所以,标签1的查准率是66.7%。
  • 目标标签为2的话,被预测为2的样本有两个,预测正确的数据是1个,预测错的数据是1个。所以,标签1的查准率是50%。

查全率 recall_score()

查全率,应该被预测为目标属性的样本中(目前焦点在y_true)(可能存在被预测为其它标签的样本),真正被预测出来的样本比率。
公式表述:【真正被预测出目标标签的样本总数/y_true中应该被预测为目标属性的样本总数】
二分类公式表述:【TP/(TP+FN)】

苏南大叔再次解释:

  • 分子和查准率一样,都是被正确预测为目标标签的数据总数。
  • 分母和查准率不一样,其聚焦点是y_true,应该被预测目标标签的数据总数,或者说是真实为目标标签的数据总数。

第三次解释:
查全率recall_score,主打的是【宁可错杀一千,不可放过敌军一个】。预测错了不要紧,只要把目标数据找出来就行。查全率,查的就是应该被查出的样本,真正被查出来的概率。是不是真的被查出来了,被查错是不要紧的。

举例解释二分类

y_true  = [0, 1, 0, 1, 0]          # 二分类
y_pred  = [0, 1, 0, 1, 1]
r2 = recall_score(y_true, y_pred, average=None)      # 查全率
# [0.66666667 1.        ]
  • 目标标签为0的话,本身就是0的数据有3个,真实被预测为0的2个,所以,标签0的查全率是66.7%。
  • 目标标签为1的话,本身就是1的数据有2个,真实被预测为1的2个。所以,标签1的查准率是100%。

举例解释多分类

y_true_ = [0, 1, 0, 1, 0, 1, 2]    # 多分类
y_pred_ = [0, 1, 0, 1, 1, 2, 2]
r2 = recall_score(y_true_, y_pred_, average=None)      # 查全率
# [0.66666667 0.66666667 1.        ]
  • 目标标签为0的话,本身为0的样本有三个,其中有两个被预测正确。所以,标签0的查全率为66.7%。
  • 目标标签为1的话,本身为1的样本有三个,其中有两个被预测正确。所以,标签1的查准率是66.7%。
  • 目标标签为2的话,本身为1的样本有一个,其中有一个被预测正确。所以,标签2的查准率是100%。

f1得分 f1_score()

f1得分是根据查全率precision_score()和查准率recall_score(),计算得到的。虽然原始上来说,和各种预测是否准确的个数统计还是有关系的,但是并不是直接的关系。

计算公式是:

f1 = 2 * p * r / (p + r)

举例二分类

查准率  :  [1.         0.66666667]
查全率  :  [0.66666667 1.        ]
f1得分  :  [0.8 0.8]

0.8 = (2*1*0.67)/(1+0.67)

举例多分类

查准率  :  [1.         0.66666667 0.5       ]
查全率  :  [0.66666667 0.66666667 1.        ]
f1得分  :  [0.8        0.66666667 0.66666667]

0.8 = (2*1*0.67)/(1+0.67)
0.67 = (2*0.67*0.67)/(0.67+0.67)
0.67 = (2*1*0.5)/(1+0.5)

精准度accuracy_score

精准度只是涉及被预测正确的数据所占比率,并不涉及到average=None的问题。

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
a = accuracy_score(y_true, y_pred)    # 准确率
print("精确度  : ", a)

这个就是大家所想象的那样,被预测准确的数/全部样本数。

查准率和准确率有什么区别?可以参考:

结语

更多苏南大叔关于sklearn的经验文章,请点击:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python