sklearn模型:求非阳性分类的precision/recall/f1评分
发布于 作者:苏南大叔 来源:程序如此灵动~目光再次来回到sklearn.metrics
里的模型评分机制,precision_score()
、recall_score()
、f1_score()
、accuracy_score()
。这些评分机制分别代表:查准率、查全率、f1得分、精准度。除了精准度accuracy_score()
外,其它这几个评分,都有个average
参数,本文分析average
参数的第一个用法:如何计算获得非阳性分类的模型结果评分。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程所学所想。本文测试环境:win10
,python@3.12.0
,pandas@2.1.3
,scikit-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
的经验文章,请点击:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。