第二十三章 解析PR曲线、ROC曲线、AUC、AP(工具)

2023-11-28 02:01

本文主要是介绍第二十三章 解析PR曲线、ROC曲线、AUC、AP(工具),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

混淆矩阵Confusion Matrix

混淆矩阵定义

混淆矩阵是机器学习中总结分类模型预测结果的情形分析表,以矩阵形式将数据集中的记录按照真实的类别与分类模型预测的类别判断两个标准进行汇总。其中矩阵的行表示真实值,矩阵的列表示预测值,下面我们先以二分类为例,看下矩阵表现形式,如下:

预测/真实1(Postive)0(Negative)
1 (Postive)TP(True Postive:真阳)FP (False Postive:假阳)
0(Negative)FN (False Negative:假阴)TN (True Negative:真阴)

img

在讲矩阵之前,我们先复习下之前在讲分类评估指标中定义的一些符号含义,如下:

  1. TP(True Positive):将正类预测为正类数,真实为0,预测也为0
  2. FN(False Negative):将正类预测为负类数,真实为0,预测为1
  3. FP(False Positive):将负类预测为正类数, 真实为1,预测为0
  4. TN(True Negative):将负类预测为负类数,真实为1,预测也为1

刚才分析的是二分类问题,那么对于多分类问题,混淆矩阵表示的含义也基本相同,这里我们以三类问题为例,看看如何根据混淆矩阵计算各指标值。

img

与二分类混淆矩阵一样,矩阵行数据相加是真实值类别数,列数据相加是分类后的类别数,那么相应的就有以下计算公式;

  1. 精确率_类别1=a/(a+d+g)
  2. 召回率_类别1=a/(a+b+c)

python 实现混淆矩阵

混淆矩阵(Confusion Matrix),是一种在深度学习中常用的辅助工具,可以让你直观地了解你的模型在哪一类样本里面表现得不是很好。

示例代码一如下:

在这里插入图片描述

import seaborn as sns
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt# 使用 seaborn 风格设置
sns.set()# 创建混淆矩阵
C2 = confusion_matrix([0, 1, 2, 0, 1, 2, 0, 2, 2, 0, 1, 1], [0, 1, 1, 2, 1, 0, 0, 2, 2, 0, 1, 1])# 创建子图
f, ax = plt.subplots()# 打印混淆矩阵
print(C2)# 绘制热力图
sns.heatmap(C2, annot=True, ax=ax)# 设置标题和轴标签
ax.set_title('Confusion Matrix')  # 标题
ax.set_xlabel('Predicted')  # x轴
ax.set_ylabel('True')  # y轴# 显示图像
plt.show()

示例代码二如下:

在这里插入图片描述

import matplotlib.pyplot as plt
import numpy as npdef plot_Matrix(cm, classes, title=None, cmap=plt.cm.Blues):plt.rc('font', family='Times New Roman', size='8')  # 设置字体样式、大小# 按行进行归一化cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]print("Normalized confusion matrix")str_cm = cm.astype(np.str).tolist()for row in str_cm:print('\t'.join(row))# 占比1%以下的单元格,设为0,防止在最后的颜色中体现出来for i in range(cm.shape[0]):for j in range(cm.shape[1]):if int(cm[i, j] * 100 + 0.5) == 0:cm[i, j] = 0fig, ax = plt.subplots()im = ax.imshow(cm, interpolation='nearest', cmap=cmap)# ax.figure.colorbar(im, ax=ax) # 侧边的颜色条带ax.set(xticks=np.arange(cm.shape[1]),yticks=np.arange(cm.shape[0]),xticklabels=classes, yticklabels=classes,title=title,ylabel='Actual',xlabel='Predicted')# 通过绘制格网,模拟每个单元格的边框ax.set_xticks(np.arange(cm.shape[1] + 1) - .5, minor=True)ax.set_yticks(np.arange(cm.shape[0] + 1) - .5, minor=True)ax.grid(which="minor", color="gray", linestyle='-', linewidth=0.2)ax.tick_params(which="minor", bottom=False, left=False)# 将x轴上的lables旋转45度plt.setp(ax.get_xticklabels(), rotation=45, ha="right",rotation_mode="anchor")# 标注百分比信息fmt = 'd'thresh = cm.max() / 2.for i in range(cm.shape[0]):for j in range(cm.shape[1]):if int(cm[i, j] * 100 + 0.5) > 0:ax.text(j, i, format(int(cm[i, j] * 100 + 0.5), fmt) + '%',ha="center", va="center",color="white" if cm[i, j] > thresh else "black")fig.tight_layout()plt.savefig('cm.jpg', dpi=300)plt.show()# 构造一个混淆矩阵
cm = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
classes = ['class1', 'class2', 'class3']# 调用函数绘制混淆矩阵
plot_Matrix(cm, classes, title='Confusion Matrix')

PR曲线 & AP

Recall召回率(查全率):

R e c a l l = T P T P + F N Recall=\frac{TP}{TP+FN} Recall=TP+FNTP

含义:TP除以第一列,即预测为1实际为1的样本在所有真实为1类别中的占比。

Presession精准率(查准率):

P r e s e s s i o n = T P T P + F P Presession=\frac{TP}{TP+FP} Presession=TP+FPTP

含义:FP除以第一行,即预测为1实际为1的样本在所有预测为1类别中的占比。

PR曲线:

同理ROC曲线。在模型预测的时候,我们输出的预测结果是一堆[0,1]之间的数值,怎么把数值变成二分类?设置一个阈值,大于这个阈值的值分类为1,小于这个阈值的值分类为0。ROC曲线就是我们从[0,1]设置一堆阈值,每个阈值得到一个(Presession,Recall)对,纵轴为Presession,横轴为Recall,把所有的(Presession,Recall)对对连起来就得到了PR曲线。

img

AP(PR曲线下的面积):

跟TPR和FPR不一样的是,在PR关系中,是一个此消彼长的关系,但往往我们希望二者都是越高越好,所以PR曲线是右上凸效果越好(也有例外,有比如在风险场景当预测为1实际为0时需要赔付时,大致会要求Recall接近100%,可以损失Precision)。所以除了特殊情况,通常情况都会使用Precision-recall曲线,来寻找分类器在Precision与Recall之间的权衡。

AP就是Precision-recall 曲线下面的面积,通常来说一个越好的分类器,AP值越高。

还有一个mAP的概念,mAP是多个类别AP的平均值。这个mean的意思是对每个类的AP再求平均,得到的就是mAP的值,mAP的大小一定在[0,1]区间,越大越好。该指标是目标检测算法中最重要的一个。

精准率和召回率是相互制约的,如果想要精准率提高,召回率则会下降,如果要召回率提高,精准率则会下降,我们需要找到二者之间的一个平衡。

P-R曲线的生成方法:根据学习器的预测结果对样本进行排序,排在前面的是学习器认为最可能是正例的样本,排在最后的是最不可能是正例的样本,按此顺序逐个将样本作为正例预测,则每次可以计算出当前的查全率、查准率,以查全率为横轴、查准率为纵轴做图,得到的查准率-查全率曲线即为P-R曲线。也就是说对每个样本预测其为正例的概率,然后将所有样本按预测的概率进行排序,然后依次将排序后的样本做为正例进行预测,从而得到每次预测的查全率与查准率。这个依次将样本做为正例的过程实际上就是逐步降低样本为正例的概率的域值,通过降低域值,更多的样本会被预测为正例,从而会提高查全率,相对的查准率可能降低,而随着后面负样本的增加,查全率提高缓慢甚至没有提升,精度降低会更快。

img

代码实现如下:

import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve
import numpy as npplt.figure('P-R Curve')
plt.title('Precision/Recall Curve')
plt.xlabel('Recall')
plt.ylabel('Precision')#y_true为样本实际的类别,y_scores为样本为正例的概率
y_true = np.array([1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0])
y_scores = np.array([0.9, 0.75, 0.86, 0.47, 0.55, 0.56, 0.74, 0.62, 0.5, 0.86, 0.8, 0.47, 0.44, 0.67, 0.43, 0.4, 0.52, 0.4, 0.35, 0.1])
precision, recall, thresholds = precision_recall_curve(y_true, y_scores)plt.plot(recall,precision)
plt.show()

ROC曲线 & AUC

真阳率:

T P R = T P T P + F N = F P P TPR=\frac{TP}{TP+FN}=\frac{FP}{P} TPR=TP+FNTP=PFP

含义:TP除以第一列,即预测为1实际为1的样本在所有真实1类别中的占比。

假阳率:

F P R = F P F P + T N = F P N FPR=\frac{FP}{FP+TN}=\frac{FP}{N} FPR=FP+TNFP=NFP

含义:FP除以第二列,即预测为1实际为0的样本在所有真实0类别中的占比。

ROC曲线:

在模型预测的时候,我们输出的预测结果是一堆[0,1]之间的数值,怎么把数值变成二分类?设置一个阈值,大于这个阈值的值分类为1,小于这个阈值的值分类为0。ROC曲线就是我们从[0,1]设置一堆阈值,每个阈值得到一个(TPR,FPR)对,纵轴为TPR,横轴为FPR,把所有的(TPR,FPR)对连起来就得到了ROC曲线。

img

代码实现:

import matplotlib
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve, roc_curveplt.figure()
plt.title('PR Curve')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.grid()# 只是理解两种曲线的含义,所以数据简单的构造
confidence_scores = np.array([0.9, 0.46, 0.78, 0.37, 0.6, 0.4, 0.2, 0.16])
confidence_scores = sorted(confidence_scores, reverse=True)  # 置信度从大到小排列
print(confidence_scores)data_labels = np.array([1, 1, 0, 1, 0, 0, 1, 1])  # 置信度所对应的标签# 精确率,召回率,阈值
precision, recall, thresholds = precision_recall_curve(data_labels, confidence_scores)
print(precision)
print(recall)
print(thresholds)
plt.plot(recall, precision)
plt.show()# 真正率,假正率
fpr, tpr, thresholds = roc_curve(data_labels, confidence_scores)
# print(fpr)
# print(tpr)
plt.figure()
plt.grid()
plt.title('Roc Curve')
plt.xlabel('FPR')
plt.ylabel('TPR')from sklearn.metrics import aucauc = auc(fpr, tpr)  # AUC计算
plt.plot(fpr, tpr, label='roc_curve(AUC=%0.2f)' % auc)
plt.legend()
plt.show()

AUC(area under the curve):

(1)计算方法一

AUC即ROC曲线下的面积。曲线越靠近左上角,意味着TPR>FPR,模型的整体表现也就越好。所以我们可以断言,ROC曲线下的面积越大,模型效果越好。

最坏的情况是,总是有TPR=FPR,如下图,表示对于不论真实类别是1还是0的样本,分类器预测为1的概率是相等的。换句话说,分类器对于正例和负例毫无区分能力。如果AUC小于0.5,那么只要把预测类别取反,便得到了一个AUC大于0.5的分类器。

img

(2)计算方法二

AUC还有一种解释就是任取一对正负样本,正样本的预测值大于负样本的预测值的概率。 显然可以写出计算AUC伪代码为:

1.统计所有正样本个数P,负样本个数N;

2.遍历所有正负样本对,统计正样本预测值大于负样本预测值的样本总个数number

3. A U C = n u m b e r / ( P ∗ N ) AUC = number / (P * N) AUC=number/(PN) 一些计算细节是当正负样本预测值刚好相等时,该样本记为0.5个。

PS: 在实际代码实现过程中其实可以和第一种方法一样进一步优化,可以先对正负样本排序,利用dp的思想迭代计算个数,可以将复杂度从 O ( N 2 ) O(N^2) O(N2)降低为 O ( N l o g N ) O(NlogN) O(NlogN)

类别不平衡问题中如何选择PR与ROC

这里特指负样本数量远大于正样本时,在这类问题中,我们往往更关注正样本是否被正确分类,即TP的值。PR曲线更适合度量类别不平衡问题中:

  1. 因为在PR曲线中TPR和FPR的计算都会关注TP,PR曲线对正样本更敏感。
  2. 而ROC曲线正样本和负样本一视同仁,在类别不平衡时ROC曲线往往会给出一个乐观的结果。

理解的动态图:

https://zhuanlan.zhihu.com/p/92218196

这篇关于第二十三章 解析PR曲线、ROC曲线、AUC、AP(工具)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/428889

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

超强的截图工具:PixPin

你是否还在为寻找一款功能强大、操作简便的截图工具而烦恼?市面上那么多工具,常常让人无从选择。今天,想给大家安利一款神器——PixPin,一款真正解放双手的截图工具。 想象一下,你只需要按下快捷键就能轻松完成多种截图任务,还能快速编辑、标注甚至保存多种格式的图片。这款工具能满足这些需求吗? PixPin不仅支持全屏、窗口、区域截图等基础功能,它还可以进行延时截图,让你捕捉到每个关键画面。不仅如此

多线程解析报表

假如有这样一个需求,当我们需要解析一个Excel里多个sheet的数据时,可以考虑使用多线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完之后,程序需要提示解析完成。 Way1 join import java.time.LocalTime;public class Main {public static void main(String[] args) thro