sklearn中分类模型评估指标(三):精确率、召回率、F值

简介: 简述直观地说,精确率是指分类器不将负样本标记为正样本的能力,召回率是指分类器查找所有正样本的能力。而F值(F1F_1F1​和FβF_{\beta}Fβ​值)则可以解释为精确率和召回率的加权调和平均值。FβF_{\beta}Fβ​值的取值范围为[0,1],在1处表示模型效果最好,在0处表示模型效果最差。

简述

直观地说,精确率是指分类器不将负样本标记为正样本的能力,召回率是指分类器查找所有正样本的能力。

而F值(F1F_1F1FβF_{\beta}Fβ值)则可以解释为精确率和召回率的加权调和平均值。

FβF_{\beta}Fβ值的取值范围为[0,1],在1处表示模型效果最好,在0处表示模型效果最差。

β=1\beta =1β=1时,F1F_1F1FβF_{\beta}Fβ等价,表示精确率和召回率同等重要。

关于精确率、召回率和F值的详细内容,请参考我的另一篇博文:十分钟掌握分类算法的评估指标

precision_recall_curve:根据真实标签和分类器通过改变决策阈值给出的分数,计算精度率-召回率曲线。

average_precision_score:根据预测分数计算平均精确率(AP),该值介于 0 和 1 之间,越高越好。 AP被定义为

AP=∑n(Rn−Rn−1)Pn\text{AP} = \sum_n (R_n - R_{n-1}) P_nAP=n(RnRn1)Pn

其中,PnP_nPnRnR_nRn 是第 n 个阈值的准确率和召回率。

这种实现是没有插值的,不同于用梯形规则计算precision-recall曲线下的面积,后者使用线性插值,可能过于乐观。

注意:此实现仅限于二分类任务或多标签分类任务。

以下几个函数允许您计算精确率、召回率和F值分数:


函数 说明
average_precision_score(y_true, y_score, *) 根据预测分数计算平均精确率 (AP)
f1_score(y_true, y_pred, *[, labels, …]) 计算F1值
fbeta_score(y_true, y_pred, *, beta[, …]) 计算F-beta值
precision_recall_curve(y_true, probas_pred, *) 计算不同概率阈值下的精确率召回率对
precision_recall_fscore_support(y_true, …) 计算每个类的精确率、召回率、F值和真实值的标签数量
precision_score(y_true, y_pred, *[, labels, …]) 计算精确率
recall_score(y_true, y_pred, *[, labels, …]) 计算召回率

注意:

precision_recall_curve函数仅限于二分类场景。 average_precision_score函数仅适用于二分类和多标签分类场景。


二分类场景

在二分类任务中,术语“正”和“负”是指分类器的预测,术语“真”和“假”是指该预测结果是否对应于外部(实际值)判断, 鉴于这些定义,我们可以制定下表:

网络异常,图片无法展示
|


在这种情况下,精确率、召回率和 F值的公式如下:

precision=tptp+fp,\text{precision} = \frac{tp}{tp + fp},precision=tp+fptp,

recall=tptp+fn,\text{recall} = \frac{tp}{tp + fn},recall=tp+fntp,

Fβ=(1+β2)precision×recallβ2precision+recall.F_\beta = (1 + \beta^2) \frac{\text{precision} \times \text{recall}}{\beta^2 \text{precision} + \text{recall}}.Fβ=(1+β2)β2precision+recallprecision×recall.

示例代码:

from sklearn import metrics
import numpy as np
import pprint
y_pred = [0, 1, 0, 0]
y_true = [0, 1, 0, 1]
# average参数的默认值为binary, "binary"表示用于二分类
print(metrics.precision_score(y_true, y_pred))
print(metrics.precision_score(y_true, y_pred, average='binary'))
print(metrics.recall_score(y_true, y_pred))
print(metrics.recall_score(y_true, y_pred, average='binary'))
print(metrics.f1_score(y_true, y_pred))
print(metrics.f1_score(y_true, y_pred, average='binary'))
print(metrics.fbeta_score(y_true, y_pred, beta=0.5))
print(metrics.fbeta_score(y_true, y_pred, beta=1))
print(metrics.fbeta_score(y_true, y_pred, beta=2))
print("------------------")
pprint.pprint(metrics.precision_recall_fscore_support(y_true, y_pred, beta=0.5))
print("------------------")
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
# PR曲线实则是以precision(精准率)和recall(召回率)这两个为变量而做出的曲线,其中recall为横坐标,precision为纵坐标。
# 设定一系列阈值,计算每个阈值对应的recall和precision,即可计算出PR曲线各个点。
precision, recall, threshold = metrics.precision_recall_curve(y_true, y_scores)
print("", precision, "\n",recall,"\n", threshold)
# 其中,y_true是正确标签,y_score是概率输出值,thresholds是阈值,
# 当y_score>=thresholds,则预测为正样本,当y_score<thresholds,则预测为负样本。
# 注意,输出的precision和recall最后一个值分别为1和0,并且没有对应的阈值。
# 该例子中,在实际的数据集中,正样本实际数量为2个,负样本实际数量为2个。
# 当index=0,thresholds[index]=0.35,此时预测的标签为[0,1,1,1],
# tp=2,fp=1,fn=0,所以precision=0.67,recall=1
# 当index=1,thresholds[index]=0.4,此时预测的标签为[0,1,0,1],
# tp=1,fp=1,fn=1,所以precision=0.5,recall=0.5
# 当index=2,thresholds[index]=0.8,此时预测的标签为[0,0,0,1],
# tp=1,fp=0,fn=1,所以precision=1,recall=0.5
print("------------------")
print(metrics.average_precision_score(y_true, y_scores))
复制代码


运行结果:

1.0
1.0
0.5
0.5
0.6666666666666666
0.6666666666666666
0.8333333333333334
0.6666666666666666
0.5555555555555556
------------------
(array([0.66666667, 1.        ]),
 array([1. , 0.5]),
 array([0.71428571, 0.83333333]),
 array([2, 2]))
------------------
 [0.66666667 0.5        1.         1.        ] 
 [1.  0.5 0.5 0. ] 
 [0.35 0.4  0.8 ]
------------------
0.8333333333333333
复制代码


多分类与多标签场景

在多分类和多标签分类任务中,精确率、召回率和F值的概念可以独立应用于每个标签。

这里有几种遍历标签组合结果方法,由average_precision_score(仅限多标签)、f1_scorefbeta_scoreprecision_recall_fscore_supportprecision_scorerecall_score函数的average(平均)参数指定。 请注意,如果包含所有标签,则多类设置中的“微”平均将产生精度、召回率,并且这些都与准确度相同。 另请注意,“加权”平均可能会产生不在精度和召回率之间的 F 分数。

请注意:如果包含所有标签,则多分类场景中设置的“micro”平均,产生的精确率、召回率和F值,这些都与准确率相同。

同时也请注意:“weighted”平均可能会产生不在精度和召回率之间的F分数。

为了使这更加清晰,请参考以下符号:

  • yyy表示预测对(sample,label)(sample, label)(sample,label)的集合(分类器的预测值)
  • y^\hat{y}y^表示真实对(sample,label)(sample, label)(sample,label)的集合(实际值)
  • LLL表示标签集
  • SSS表示样本集
  • ysy_sys表示yyy的子集,样本sss
  • yly_lyl表示yyy的子集,标签lll
  • 同样的,y^s\hat{y}_sy^sy^l\hat{y}_ly^ly^\hat{y}y^的子集
  • P(A,B):=∣A∩B∣∣A∣P(A, B) := \frac{\left| A \cap B \right|}{\left|A\right|}P(A,B):=AAB ,表示精确率,其中B为真实为正的集合,A为预测为正的集合
  • R(A,B):=∣A∩B∣∣B∣R(A, B) := \frac{\left| A \cap B \right|}{\left|B\right|}R(A,B):=BAB,表示召回率,其中B为真实为正的集合,A为预测为正的集合
  • Fβ(A,B):=(1+β2)P(A,B)×R(A,B)β2P(A,B)+R(A,B)F_\beta(A, B) := \left(1 + \beta^2\right) \frac{P(A, B) \times R(A, B)}{\beta^2 P(A, B) + R(A, B)}Fβ(A,B):=(1+β2)β2P(A,B)+R(A,B)P(A,B)×R(A,B)

指标定义如下表所示:

average参数 Precision Recall F_beta
"micro" P(y,y^)P(y, \hat{y})P(y,y^) R(y,y^)R(y, \hat{y})R(y,y^) Fβ(y,y^)F_\beta(y, \hat{y})Fβ(y,y^)
"samples" 1S∑s∈SP(ys,y^s)\frac{1}{S} \sum_{s \in S} P(y_s, \hat{y}_s)S1sSP(ys,y^s) 1S∑s∈SR(ys,y^s)\frac{1}{S} \sum_{s \in S} R(y_s, \hat{y}_s)S1sSR(ys,y^s) 1S∑s∈SFβ(ys,y^s)\frac{1}{S} \sum_{s \in S} F_\beta(y_s, \hat{y}_s)S1sSFβ(ys,y^s)
"macro" 1L∑l∈LP(yl,y^l)\frac{1}{L} \sum_{l \in L} P(y_l, \hat{y}_l)L1lLP(yl,y^l) 1L∑l∈LR(yl,y^l)\frac{1}{L} \sum_{l \in L} R(y_l, \hat{y}_l)L1lLR(yl,y^l) 1L∑l∈LFβ(yl,y^l)\frac{1}{L} \sum_{l \in L} F_\beta(y_l, \hat{y}_l)L1lLFβ(yl,y^l)
"weighted" 1∑l∈Ly^l∑l∈Ly^lP(yl,y^l)\frac{1}{\sum_{l \in L} \hat{y}_l} \sum_{l \in L} \hat{y}_l P(y_l, \hat{y}_l)lLy^l1lLy^lP(yl,y^l) 1∑l∈Ly^l∑l∈Ly^lR(yl,y^l)\frac{1}{\sum_{l \in L} \hat{y}_l} \sum_{l \in L} \hat{y}_l R(y_l, \hat{y}_l)lLy^l1lLy^lR(yl,y^l) 1∑l∈Ly^l∑l∈Ly^lFβ(yl,y^l)\frac{1}{\sum_{l \in L} \hat{y}_l} \sum_{l \in L} \hat{y}_l F_\beta(y_l, \hat{y}_l)lLy^l1lLy^lFβ(yl,y^l)
None ⟨P(yl,y^l),l∈L⟩\langle P(y_l, \hat{y}_l) , l \in L \rangleP(yl,y^l),lL ⟨R(yl,y^l),l∈L⟩\langle R(y_l, \hat{y}_l), l \in L \rangleR(yl,y^l),lL ⟨Fβ(yl,y^l),l∈L⟩\langle F_\beta(y_l, \hat{y}_l) , l \in L \rangleFβ(yl,y^l),lL

备注:

关于分类评估指标(精确率、召回率和F值)的详细说明,请参考我的另一篇博客:十分钟掌握分类算法的评估指标

关于average参数的详细说明,请参考我的另一篇博客::sklearn中针对不同分类场景模型评估指标函数概述

示例代码:

from sklearn import metrics
import pprint
y_true = [0, 1, 2, 0, 1, 2]
y_pred = [0, 2, 1, 0, 0, 1]
print(metrics.precision_score(y_true, y_pred, average='macro'))
print(metrics.recall_score(y_true, y_pred, average='micro'))
print(metrics.f1_score(y_true, y_pred, average='weighted'))
print(metrics.fbeta_score(y_true, y_pred, average='macro', beta=0.5))
print("++++++++++++")
# 对于具有“负类”的多分类,可以排除一些标签:
# 比如,排除0之后,没有标签被正确召回的情况
print(metrics.recall_score(y_true, y_pred, labels=[1, 2], average='micro'))
# 数据样本中不存在的标签可能会在宏观平均中考虑在内。
print(metrics.precision_score(y_true, y_pred, labels=[0, 1, 2, 3], average='macro'))
print("------------")
# 计算精确率、召回率、F值、真实值数据集中每个标签的数量
pprint.pprint(metrics.precision_recall_fscore_support(y_true, y_pred, beta=0.5, average=None))
print("------------")
# 计算指定标签,每个标签的指标
print(metrics.precision_score(y_true, y_pred, average=None, labels=[0, 2]))
print(metrics.recall_score(y_true, y_pred, average=None, labels=[0, 2]))
print("------------")
# 计算所有标签,每个标签的指标
print(metrics.precision_score(y_true, y_pred, average=None))
print(metrics.recall_score(y_true, y_pred, average=None))
print("------------")
# 计算指定标签的宏平均
print(metrics.precision_score(y_true, y_pred, average='macro', labels=[0, 2]))
print(metrics.recall_score(y_true, y_pred, average='macro', labels=[0, 2]))
复制代码

运行结果:

0.2222222222222222
0.3333333333333333
0.26666666666666666
0.23809523809523805
++++++++++++
0.0
0.16666666666666666
------------
(array([0.66666667, 0.        , 0.        ]),
 array([1., 0., 0.]),
 array([0.71428571, 0.        , 0.        ]),
 array([2, 2, 2]))
------------
[0.66666667 0.        ]
[1. 0.]
------------
[0.66666667 0.         0.        ]
[1. 0. 0.]
------------
0.3333333333333333
0.5
复制代码

在多分类标签场景下,微平均的示例代码如下所示:

from sklearn import metrics
y_true = [0, 1, 2, 0, 4, 2, 3]
y_pred = [0, 1, 1, 0, 4, 1, 2]
print(metrics.recall_score(y_true, y_pred, average='micro'))
print(metrics.f1_score(y_true, y_pred, average='micro'))
print(metrics.precision_score(y_true, y_pred, average='micro'))
print(metrics.accuracy_score(y_true, y_pred))
复制代码

运行结果:

0.5714285714285714
0.5714285714285714
0.5714285714285714
0.5714285714285714
复制代码

总结

在二分类场景时,average参数为"binary"; 在多分类场景时,average参数通常为"micro","macro","weighted"; 在多标签分类场景时,average参数为"samples"。

相关文章
|
8月前
|
存储 机器学习/深度学习 缓存
vLLM 核心技术 PagedAttention 原理详解
本文系统梳理了 vLLM 核心技术 PagedAttention 的设计理念与实现机制。文章从 KV Cache 在推理中的关键作用与内存管理挑战切入,介绍了 vLLM 在请求调度、分布式执行及 GPU kernel 优化等方面的核心改进。PagedAttention 通过分页机制与动态映射,有效提升了显存利用率,使 vLLM 在保持低延迟的同时显著提升了吞吐能力。
4209 19
vLLM 核心技术 PagedAttention 原理详解
|
机器学习/深度学习 算法 数据挖掘
【数据挖掘】SVM原理详解及对iris数据集分类实战(超详细 附源码)
【数据挖掘】SVM原理详解及对iris数据集分类实战(超详细 附源码)
773 1
|
NoSQL Java 数据库连接
SpringBoot-搭建Mybatis项目
通过本文的学习,读者将了解如何使用IntelliJ IDEA快速搭建一个基于SpringBoot和Mybatis的Java Web应用程序,提高开发效率。
812 0
|
机器学习/深度学习 人工智能 文字识别
ultralytics YOLO11 全新发布!(原理介绍+代码详见+结构框图)
本文详细介绍YOLO11,包括其全新特性、代码实现及结构框图,并提供如何使用NEU-DET数据集进行训练的指南。YOLO11在前代基础上引入了新功能和改进,如C3k2、C2PSA模块和更轻量级的分类检测头,显著提升了模型的性能和灵活性。文中还对比了YOLO11与YOLOv8的区别,并展示了训练过程和结果的可视化
21492 0
|
机器学习/深度学习 定位技术 Python
Matplotlib 教程 之 Matplotlib imshow() 方法 6
Matplotlib `imshow()` 方法教程:详解如何使用 `imshow()` 函数显示二维图像,包括灰度图、彩色图及不同插值方法的应用示例。通过调整参数如颜色映射(cmap)、插值方法(interpolation)等,实现图像的不同视觉效果。
327 2
|
Linux
跟着mpg案例学Seaborn之Jointplot
跟着mpg案例学Seaborn之Jointplot
291 1
|
算法 关系型数据库 Java
数据库原理第四章课后题答案(第四版)
数据库原理第四章课后题答案(第四版)
628 0
|
人工智能 弹性计算 定位技术
【云故事探索】NO.4: 千寻位置,时空智能赋能行业数字化转型
千寻位置,成立于2015年,利用北斗卫星系统及全球5000多座增强站,提供厘米级定位服务。该公司借助阿里云的计算能力,为汽车、农业等多个行业提供高精度时空智能解决方案,推动行业转型升级。千寻已完成超130亿元估值的A轮融资,展现了其在时空智能领域的领先地位。通过云上部署,千寻优化服务质量和市场扩展,应对突发流量,计划进一步全球化并应用AI技术。阿里云的支持对于千寻的成功至关重要,双方合作将时空智能服务推向国际。
【云故事探索】NO.4: 千寻位置,时空智能赋能行业数字化转型
|
机器学习/深度学习 算法 数据挖掘
4小时学完!15年技术大牛用247个实战案例剖析的Python教程
今天给小伙伴们分享一份15年技术大牛用247个实战案例剖析的Python教程,这份教程全程彩图讲解,告别枯燥!60秒学会⼀个⼩例⼦,带你系统学习Python,从⼊门到⼤师。 涵盖了Python基础、Python字符串和正则、Python⽂件和⽇期、Python三⼤利器、Python绘图、Python之坑、Python第三⽅包、机器学习和深度学必知算法、Python实战、Pandas数据分析案例实战十大篇幅的精品案例教程
|
Python
使用Python计算有效值函数(RMS值)
使用Python计算有效值函数(RMS值)
1346 0

热门文章

最新文章