【模型评估】ROC(Receiver operating characteristic)与 AUC

news2024/10/7 7:23:31

前面,我们提到了混淆矩阵,以及根据混淆矩阵进一步计算得到的敏感度(召回率)、特异度、精确度、准确度、F1 Score等等。那他们的前提都是要首先确定一个截断阈值。

【模型评估】混淆矩阵(confusion_matrix)之 TP、FP、TN、FN;敏感度、特异度、准确率、精确率

这个截断阈值选取多少比较合适呢?这里就需要引入ROC曲线了,一个衡量模型整体性能的参数。

一、什么是ROC(Receiver Operating Characteristic)

在上一章计算混淆矩阵时候,我们提到:混淆矩阵的绘制严重依赖一个固定的截断阈值,大于这个阈值的是阳性,反之则是阴性。

在确定该阈值的前提下,才能确定混淆矩阵的数值,这种对模型评价方式是片面的,不够全局的,没有从整体上评价一个模型的性能。

此时,迫切需要一中评价方式,能够更加全面的对模型进行评估。既然一个截断阈值的评价是片面的,那么我尽可能的多取一些阈值,综合起来评价,那是不是就可以避免这个问题呢?于是就出现的ROC曲线,如下所示:

1

其中:

  • 横轴:False Positive Rate(假阳率,FPR=1-特异度)
  • 纵轴:True Positive Rate(真阳率,TPR=敏感度)

连接(0,0)和(1,1)绿色曲线上的任意一点,是在该阈值下,对应的混淆矩阵下的假阳性率和真阳性率。例如图中的(0.1,0.8),即该阈值 t 下,假阳性率为0.1,真阳性率为0.8。

连接这条曲线上的任意一个点,就对应着在该截断阈值下的假阳性率和真阳性率。其中

  • 最优的点取在左上角
  • 曲线右下包围的面积,叫做AUC值

二、如何绘制ROC曲线

那后面,我们就针对这样一个思路,开始绘制一个分类任务中的ROC曲线出来。整理下绘制思路:

  1. 获取每一张评估图像的标注类别gt、预测该真实类别的预测置信度score;
  2. 对于某一个类,遍历分数0-1,分1000个截断阈值,分别计算在该阈值下,该类的混淆矩阵,进一步计算得到假阳性率和真阳性率
  3. 横坐标是假阳性率(1-特异度),纵坐标是真阳性率(敏感度),绘制ROC曲线
  4. 计算AUC值

2.1、sklearn绘制简单ROC

思路就是上面这样一个心路历程,但是现在基本上各个库都已经帮你封装好了,只需要准备好对应的数据格式,调用函数即可,无需重复造轮子了。下面就是调用sklear的函数,直接绘制ROC和AUC 值。如下:

import numpy as np
from sklearn.metrics import roc_curve, auc
y      = np.array([1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1])
scores = np.array([0.1, 0.4, 0.35, 0.8, 0.9, 0.7, 0.6, 0.4, 0.2, 0.1, 0.2, 0.9, 0.8, 0.65, 0.85, 0.67, 0.75, 0.74, 0.36, 0.85, 0.48, 0.95, 1, 0.65,
                   0.85, 0.75, 0.95, 0.84, 0.74, 0.58, 0.95])
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=1)
print(fpr)
print(tpr)
print(thresholds)

roc_auc = auc(fpr, tpr)

plt.plot(fpr, tpr, lw=1, label="COVID vs NotCOVID, AUC=%0.3f)" % (roc_auc))

plt.xlim([0.00, 1.0])
plt.ylim([0.00, 1.0])
plt.xlabel("False Positive Rate")
plt.ylabel("True Positive Rate")
plt.title("ROC")
plt.legend(loc="lower right")
plt.savefig(r"./ROC.png")
print("ok")

其实,到这里基本上已经够绘制ROC曲线了,无论是单个类别,还是多个类别。pos_label是哪个,其他的都是negative,依次来绘制ROC曲线即可。

2.2、多分类的ROC曲线绘制到一起

有多个类别的时候,喜欢把不同的类,ROC汇总到一张图里面,这样可以相互对比,下面提供了一张绘制方式留作参考。同时也是鸢尾花项目的训练和测试过程,有所启发。

# 引入必要的库
import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle
from sklearn import svm, datasets
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from scipy import interp
 
# 加载数据
iris = datasets.load_iris()
X = iris.data
y = iris.target
# 将标签二值化
y = label_binarize(y, classes=[0, 1, 2])
# 设置种类
n_classes = y.shape[1]
 
# 训练模型并预测
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
 
# shuffle and split training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.5,random_state=0)
 
# Learn to predict each class against the other
classifier = OneVsRestClassifier(svm.SVC(kernel='linear', probability=True,
                                 random_state=random_state))
y_score = classifier.fit(X_train, y_train).decision_function(X_test)
 
# 计算每一类的ROC
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
    fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i])
    roc_auc[i] = auc(fpr[i], tpr[i])
 
# Compute micro-average ROC curve and ROC area(方法二)
fpr["micro"], tpr["micro"], _ = roc_curve(y_test.ravel(), y_score.ravel())
roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])
 
# Compute macro-average ROC curve and ROC area(方法一)
# First aggregate all false positive rates
all_fpr = np.unique(np.concatenate([fpr[i] for i in range(n_classes)]))
# Then interpolate all ROC curves at this points
mean_tpr = np.zeros_like(all_fpr)
for i in range(n_classes):
    mean_tpr += interp(all_fpr, fpr[i], tpr[i])
# Finally average it and compute AUC
mean_tpr /= n_classes
fpr["macro"] = all_fpr
tpr["macro"] = mean_tpr
roc_auc["macro"] = auc(fpr["macro"], tpr["macro"])
 
# Plot all ROC curves
lw=2
plt.figure()
plt.plot(fpr["micro"], tpr["micro"],
         label='micro-average ROC curve (area = {0:0.2f})'
               ''.format(roc_auc["micro"]),
         color='deeppink', linestyle=':', linewidth=4)
 
plt.plot(fpr["macro"], tpr["macro"],
         label='macro-average ROC curve (area = {0:0.2f})'
               ''.format(roc_auc["macro"]),
         color='navy', linestyle=':', linewidth=4)
 
colors = cycle(['aqua', 'darkorange', 'cornflowerblue'])
for i, color in zip(range(n_classes), colors):
    plt.plot(fpr[i], tpr[i], color=color, lw=lw,
             label='ROC curve of class {0} (area = {1:0.2f})'
             ''.format(i, roc_auc[i]))
 
plt.plot([0, 1], [0, 1], 'k--', lw=lw)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Some extension of Receiver operating characteristic to multi-class')
plt.legend(loc="lower right")
plt.show()

保存的图像,如下:

2

2.3、绘制FROC曲线

当评估检测算法性能时,常用的指标之一是接收者操作特性曲线(Receiver Operating Characteristic Curve,ROC曲线)。ROC曲线以真阳性率(True Positive Rate,TPR)作为纵轴,以假阳性率(False Positive Rate,FPR)作为横轴。它显示了在不同阈值下,算法的敏感性和特异性之间的权衡关系。

而放射学检测任务中,通常关注的是感兴趣区域(Region of Interest,ROI)的检测情况,这些ROI往往是病灶或异常区域。相较于ROC曲线,放射学检测任务更关注的是假阳性检测的数量,因为在医学领域,减少误检率尤为重要。

为了解决放射学检测任务的特殊性,提出了自由响应工作特性曲线(Free-response Receiver Operating Characteristic Curve,FROC曲线),它是一种用于评估医学图像检测算法性能的指标。FROC曲线以敏感性Sensitivity)作为纵轴,以平均假阳性数Average False Positives Per Image,AFPI)作为横轴。

在FROC曲线中,每个点代表了在特定假阳性数下的敏感性。与ROC曲线不同,FROC曲线的纵轴不是真阳性率,而是敏感性。AFPI表示平均每幅图像的假阳性数,它可以帮助评估算法在不同任务中的表现。

通过绘制FROC曲线,可以更准确地评估放射学检测算法在不同假阳性检测水平下的性能。一般来说,FROC曲线上的点越靠近左上角,表示算法在更低的假阳性率下能够获得较高的敏感性,从而被认为是更优秀的算法。

总结而言,FROC曲线是用于评估医学图像检测算法性能的一种指标,它关注在不同假阳性检测水平下的敏感性表现,帮助评估算法在放射学检测任务中的性能。

from sklearn import metrics
import matplotlib.pylab as plt
 
GTlist = [1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
          0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
          0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
 
Problist = [0.99, 0.98, 0.97, 0.93, 0.85, 0.80, 0.79, 0.75, 0.70, 0.65,
            0.64, 0.63, 0.55, 0.54, 0.51, 0.49, 0.30, 0.2, 0.1, 0.09,
            0.1, 0.5, 0.6, 0.7, 0.8, 0.5, 0.2, 0.3, 0.2, 0.5]
 
# num of image
totalNumberOfImages = 2
numberOfDetectedLesions = sum(GTlist)
totalNumberOfCandidates = len(Problist)
 
fpr, tpr, thresholds = metrics.roc_curve(GTlist, Problist, pos_label=1)
 
# FROC
fps = fpr * (totalNumberOfCandidates - numberOfDetectedLesions) / totalNumberOfImages
sens = tpr
 
print(fps)
print(sens)
plt.plot(fps, sens, color='b', lw=2)
plt.legend(loc='lower right')
# plt.plot([0, 1], [0, 1], 'r--')
plt.xlim([fps.min(), fps.max()])
plt.ylim([0, 1.1])
plt.xlabel('Average number of false positives per scan')  # 横坐标是fpr
plt.ylabel('True Positive Rate')  # 纵坐标是tpr
plt.title('FROC performence')
plt.show()

展示结果:
2

2.4、MedCalc统计软件绘制ROC

MedCalc是一款医学专用的统计计算软件,在研究医学领域有较为广泛的应用,软件不大,而功能却很强大,用图形化的界面直观明了的显示所统计的结果,这里就简单介绍下medcalc的统计教程。

官方下载地址:(只有15天试用期。由于不能乱传播,仅用作学习使用。若想获得免费版本,评论备注信息,留下邮箱)。官方地址:Download MedCalc Version 20.106

下面已绘制ROC曲线为例,进行介绍,步骤如图所示:
1

绘制的结果如下:

2

这也是绘制ROC的一种方式,比较快捷。只要准备好需要的数据,既可以直接绘制。注意,这里统计预测分数时候,阈值一定要取的比较低,比如0.01。这样在绘制曲线时候,阈值的选择面才会大。

百度文档对这块进行了详述,更多内容去看这里:MedCalc常用统计教程

2.5、目标检测中,基于Bbox阈值的ROC曲线

1

(这个暂时欠着,在处理中,可以先透露一些步骤):

  1. 读取的是预测的csv文件,包括file name, cls, score, box,预测结果里面多了一个置信度分数score

  2. 以标注gt作为标准,对预测pd的box进行iou的判断,如果大于设定的阈值,即暂时判定该gt的这个box,为tp(为何说暂定,因为这一个gt box,可能会被多个pd box的iou所匹配,所以需要找到iou最大的那个),没有被匹配的gt box判定为fn

  3. 根据置信度分数,进行0-1,分1000个截断阈值进行判断,依次遍历所有的预测框:

    • iou阶段,已经得到了混淆矩阵,tp、fp、tn、fn的
    • 用置信度阈值再过一遍,tp中大于阈值的,还是tp;小于阈值的,就预测为了negative,但是之前是positive的,于是就变成fn
    • fp中大于阈值的,还是fp;小于阈值的,就预测为了negative,之前是negative的,于是就变成tn
    • tn=GT_negative-fp
    • fn=GT_positive-tp
  4. 统计下来,横纵轴坐标,绘制曲线,即可得到ROC曲线;

  5. 计算AUC值(近似为矩形面积累加)

代码正在整理说明,如果你们有好的建议,欢迎评论区讨论。

三、AUC值

AUC 是 ROC 曲线下面的面积,AUC 可以解读为从所有正例中随机选取一个样本 A,再从所有负例中随机选取一个样本 B,分类器将 A 判为正例的概率比将 B 判为正例的概率大的可能性。

也就是:任意取一个正样本和负样本,正样本得分大于负样本的概率。

AUC 反映的是分类器对样本的排序能力。AUC 越大,自然排序能力越好,即分类器将越多的正例排在负例之前。

  • AUC = 1,代表完美分类器
  • 0.5 < AUC < 1,优于随机分类器
  • 0 < AUC < 0.5,差于随机分类器

AUC的公式:
3

问1:数据不平衡,对AUC有影响吗?

答1:数据不平衡对 auc 影响不大(ROC曲线下的面积,ROC的横纵坐标分别是真阳性率和1-真阴性率)。

问2:还有什么指标可以针对不平衡数据进行评估?

答2:还可以使用 PR(Precision-Recall )曲线。

四、总结

ROC(Receiver Operating Characteristic)曲线是一种用于评估二分类模型性能的图形表示方法。它以真阳性率(True Positive Rate,TPR)为纵轴,以假阳性率(False Positive Rate,FPR)为横轴,展示了在不同分类阈值下,模型的敏感性和特异性之间的权衡。

关键概念:

  • 真阳性(True Positive,TP):被模型正确地划分为正类的样本。
  • 假阳性(False Positive,FP):被模型错误地划分为正类的负类样本。
  • 真阴性(True Negative,TN):被模型正确地划分为负类的样本。
  • 假阴性(False Negative,FN):被模型错误地划分为负类的正类样本。

这块参考链接:

绘制ROC曲线的步骤:

  • 使用不同的分类阈值对样本进行预测,并计算出对应的TPR和FPR。
  • 根据不同的分类阈值,将TPR和FPR绘制在坐标轴上。
  • 连接各个点,形成ROC曲线。

ROC曲线的特点:

  • 曲线越靠近左上角,表示模型具有更高的敏感性和更低的特异性,即在较低的假阳性率下能够获得较高的真阳性率,被认为是更优秀的模型。
  • 对角线代表随机猜测的情况,处于对角线上方的曲线表示模型的性能好于随机猜测。
  • ROC曲线下的面积(Area Under the ROC Curve,AUC)是一个综合评估模型性能的指标,AUC越大,模型性能越好。

ROC曲线的应用:

  • 选择最佳分类阈值:根据应用需求,可以选择对应特定TPR和FPR的分类阈值。
  • 比较不同模型:通过比较ROC曲线和AUC值,可以评估不同模型的性能。
  • 模型调优:通过调整模型参数或特征选择,改变ROC曲线形状,提高模型性能。

总而言之,ROC曲线是评估二分类模型性能的一种重要工具,通过展示敏感性和特异性之间的权衡关系,帮助选择最佳分类阈值和比较不同模型的性能。

AP也是常用的一个综合评价工具,那么AP是怎么定义和如何实现的呢?这是下节我们需要讨论的内容,期待。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/635431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

理论粘贴板-背会了避免在大佬面前露馅-常更新

1.OLS说明 最小二乘法。给定序列X(x1,x2…xn),y,估计一个向量A(a0,a1.a2…)令y’a0a1x1a2x2…an*xn, 使得(y’-y)^2最小&#xff0c;计算A。 2.代码如下 来源《python机器学习实践指南》 import patsy import statsmodels.api as sm f ‘Rent ~ Zip Beds’ y, X patsy.dmat…

嘀嗒陪诊完整后台+前端全套小程序代码v1.0.8

就医相关陪护服务升级是未来发展趋势&#xff0c;嘀嗒陪诊是一个可以长期深耕持续运营的项目&#xff0c;并可借此切入拓展衔接养老、护理等领域。 嘀嗒陪诊小程序功能相对简单&#xff0c;后台也简捷&#xff0c;如果只是做个陪诊服务的小程序也基本能满足了&#xff0c;整体…

python基本语法知识(四)——包和模块

模块 例子1&#xff1a;导入某个模块中的具体功能 # 只导入time模块中的sleep方法&#xff0c;可以直接使用sleep调用不用加time. from time import sleep print("hello") sleep(500) print("fine")# 只导入time模块中的sleep方法,并给sleep起别名为sl f…

2023/6/11

BigDecima BigDecima的作用 用于小数的精确计算用来表示很大的小数 创建对象 创建对象时要注意以下细节 BigDecimal的使用和BigInteger类似&#xff0c;唯一要注意的点是&#xff1a;在使用除法时&#xff0c;如果除不尽就要设置精确到几位&#xff0c;否则报错 使用除法时的几…

模拟实现qsort函数(采用冒泡的方式),超详细!!!

函数详解和使用 函数声明 void qsort (void* base, size_t num, size_t size,int (*cmp)(const void* e1,constvoid* e2)); 头文件 stdlib.h 参数 base-- 指向要排序的数组的第一个元素的指针。 num-- 由 base 指向的数组中元素的个数。 size-- 数组中每个元素的大小&a…

高精度电压源的应用场合有哪些

高精度电压源是一种能够提供恒定、稳定电压输出的设备&#xff0c;被广泛应用于各种领域。高精度电压源是现代电力、通信、控制等领域中重要的测试仪器之一&#xff0c;其主要功能是提供稳定可靠的直流或交流电源&#xff0c;并具有高精度和高分辨率的特点。在实际应用中&#…

kotlin 解决构造函数兼容性问题

data class Person(private val head: String,val hand: String ) {} val p Person("head", "hand")Log.d("Alex", "Person $p") 打印结果&#xff1a; 2023-06-11 22:30:54.764 21840-21840 Alex com.example…

智能diy官网小程序至尊版v1.0.73+微信前端

&#x1f388; 限时活动领体验会员&#xff1a;可下载程序网创项目短视频素材 &#x1f388; &#x1f389; 有需要的朋友记得关赞评&#xff0c;文章底部来交流&#xff01;&#xff01;&#xff01; &#x1f389; ✨ 源码介绍 1、h5万*能页增加跳转小程序组件 2、功能链接弹…

智能工具Cursor安装和使用

一、Cursor介绍 Cursor.so是一个软件开发工具&#xff0c;是一个集成了 GPT的直接可以访问的&#xff0c;优秀而强大的智能AI代码生成工具&#xff0c;使用GPT-3.5免费。 它可以快速编写、编辑和聊天关于你的代码。它支持多种编程语言&#xff0c;如Python、Java、JavaScript等…

BootStrap文档

Bootstrap概念 ​ 1. 概念&#xff1a; 一个前端开发的框架&#xff0c;Bootstrap&#xff0c;来自 Twitter&#xff0c;是目前很受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JavaScript 的&#xff0c;它简洁灵活&#xff0c;使得 Web 开发更加快捷。 ​ 框架:一个半成品…

C++教程(06)——变量类型

C 变量类型 变量其实只不过是程序可操作的存储区的名称。C 中每个变量都有指定的类型&#xff0c;类型决定了变量存储的大小和布局&#xff0c;该范围内的值都可以存储在内存中&#xff0c;运算符可应用于变量上。 变量的名称可以由字母、数字和下划线字符组成。它必须以字母…

037_SS_SyncDiffusion: Coherent Montage via Synchronized Joint Diffusions

SyncDiffusion: Coherent Montage via Synchronized Joint Diffusions 1. Motivations & Arguments & Contributions 本文提出了一种即插即用的用Diffusion生成全景图的方法。 Diffusion模型通常只能生成固定大小的图像&#xff0c;为了生成分辨率比较高的全景图。现…

linux shell操作-基本脚本编写

文章目录 变量分支循环函数函数案例 变量 普通变量 声明变量&#xff0c;直接赋值&#xff0c;同python两边不能有空格‘’ 单引号表示纯字符“”双引号表示一个整体反引号表示操作命令末尾没有&#xff1b;号 # 直接赋值&#xff0c; namejack # 纯字符 pyCodeimport os\n…

Android进阶 四大组件的工作过程(一):Activity的工作过程

Android进阶 四大组件的工作过程&#xff08;一&#xff09;&#xff1a;Activity的工作过程 导语 本系列文章主要是来介绍Android中四大组件的工作过程的&#xff0c;参照书籍为Android进阶解密&#xff0c;主要还是会涉及到源码的阅读。关于源码&#xff0c;大家可以到Andro…

Linux - 第25节 - Linux高级IO(三)

目录 1.Reactor模式 1.1.Reactor模式的定义 1.2.Reactor模式的角色构成 1.3.Reactor模式的工作流程 2.epoll ET服务器&#xff08;Reactor模式&#xff09; 2.1.epoll ET服务器源代码 2.2.epoll ET服务器源代码讲解 2.2.1.设计思路 2.2.2.Connection结构 2.2.3.TcpSe…

VMware Fusion网络配置 - 设置Nat静态IP

准备把主力机器从ThinkPad T460P替换到MacMini上, MacOS版本: 10.15.7 当前最新MacOS版本是13 于是面临一个问题, 很多最新的工程软件不支持我这IntelCPU的MacOS陈旧版本, 于是我准备装一个虚拟机, 把工程软件都安装到虚拟机里, 宿主机访问其中的服务, 这样还能继续保持我这…

从定义到实际应用,详解项目管理的基本概念与核心内容

项目管理是项目的管理者&#xff0c;在有限的资源约束下&#xff0c;运用系统的观点、方法和理论&#xff0c;对项目涉及的全部工作进行有效地管理。项目管理的内容包括项目范围管理&#xff0c;是为了实现项目的目标&#xff0c;对项目的工作内容进行控制的管理过程。它包括范…

mysql5安装【含mysql安装包】

mysql5安装【含mysql安装包】 安装包等资源安装流程 安装包等资源 安装包下载地址【CSDN免费】&#xff1a;https://download.csdn.net/download/qq_47168235/87881814 如果上面的个下载不了&#xff0c;就通过百度网盘吧 百度网盘连接&#xff1a;https://pan.baidu.com/s/1G…

碳排放预测模型 | Python实现基于CNN卷积神经网络的碳排放预测模型(预测未来发展趋势)

文章目录 效果一览文章概述研究内容环境准备源码设计学习总结参考资料效果一览 文章概述 碳排放预测模型 | Python实现基于CNN卷积神经网络的碳排放预测模型(预测未来发展趋势) 研究内容 这是数据集的链接:https://github.com/owid/co2-data/blob/master/owid-co2-data.csv …

zabbix之ODBC监控方式

如有错误&#xff0c;敬请谅解&#xff01; 此文章仅为本人学习笔记&#xff0c;仅供参考&#xff0c;如有冒犯&#xff0c;请联系作者删除&#xff01;&#xff01; 15.1 概述 ODBC监控对应于Zabbix前端中的 数据库监视器 监控项类型。 ODBC是C语言编写的中间件API&#xf…