首页 > 其他分享 >关于AUC

关于AUC

时间:2024-03-02 21:35:20浏览次数:22  
标签:AUC ROC 阈值 样本 关于 FPR TPR

分类阈值->混淆矩阵

在做二分类任务时,模型一般会对每个样本输出一个分值s(有时这个分值也表示样本是正例的概率)。
在这个分值区间里,设置一个阈值t,就可以把在阈值之上的预测为正例,阈值之下的预测为负例。
根据样本真实的标签和预测的结果,可以分为四种情况,统计四种情况的样本个数,就可以得到一个混淆矩阵(confusion matrix):

正样本 负样本
预测为正 TP(真正例) FP(假正例)
预测为负 FN(假负例) TN(真负例)

比如下图,正样本和负样本在分值区间上是两个正态分布,阈值t会把这两个分布切分成四块。

image

左右调整阈值t的大小,这四个值也会随之变化。于是,每个阈值t都会得到一个混淆矩阵。

假如我们要比较N个模型,每个模型设置K个阈值,那么就有N*K个混淆矩阵。用这么多混淆矩阵来比较这些模型的效果显然不现实,更何况阈值的选取还可以有无限多个。

混淆矩阵->TPR/FPR

所以接下来,我们根据混淆矩阵里的四个值,定义两个指标
True Positive Rate (TPR,真正例率) = \(\frac{TP}{TP+FN}\)
False Positive Rate (FPR,假正例率) = \(\frac{FP}{TN+FP}\)
对于真正例率TPR,分子是得分>t里面正样本的数目,分母是总的正样本数目。
对于假正例率FPR,分子是得分>t里面负样本的数目,分母是总的负样本数目。
一个好的模型,肯定是TPR越大越好,FPR越小越好。

分类阈值->TPR/FPR->ROC

那么调整阈值t时,因为混淆矩阵里四个值的变化,这两个指标也会随之变化。
比如,当t变小时,因为FN变小,TPR会变大;因为TN变小,FPR也会变大。反之,当t变大时,TPR和FPR都会变小。
那么如果我们取各种不同的阈值t,并以TPR和FPR作为坐标轴,画出各个t值对应的点,就可以得到这么一个图:

image

因为好的模型肯定是TPR大而FPR小,所以这些点都在左上的部分。又因为t变大时,TPR和FPR都会变小,所以这些点分布的形状是上凸的。
连接这些点,可以得到一个上凸的曲线,称为ROC曲线。
当t很小时,TN和FN是0,那么TPR和FPR都是1。当t很大时,TP和FP都是0,那么TPR和FPR都是0。所以曲线是从右上角的(1,1)直到左下角的(0,0)。

随机模型的ROC曲线

随机的模型不区分正负样本,所以在得分>t的样本里,正负样本的比例应该与总体正负样本的比例相同。
即\(\frac{TP}{FP}=\frac{P}{N}=\frac{TP+FN}{TN+FP}\)。因此\(\frac{TP}{TP+FN}=\frac{FP}{TN+FP}\),即TPR=FPR。
所以随机模型的ROC曲线是一条连接(0,0)和(1,1)的直线。
image

我们也可以画出正负例在随机模型的分值上的分布,如下图的两种情况,正负例在所有分值上均匀分布,或者正负例在分值上的分布相同,TPR和FPR都是随着t的变化始终相等。

image

ROC->AUC

有了ROC曲线,比较多个模型的效果,就是比较多条ROC曲线。
曲线越凸,模型效果越好。
但二维的曲线比较起来也还是不方便。

所以接下来我们定义ROC曲线下的面积为AUROC(Area Under the ROC Curve),大部分时候简写为AUC。
如果现在有两个模型,一个A模型始终比另一个模型B好,也就是在所有阈值t下,A的TPR都更高,FPR都更小。
那么A的ROC曲线就比B的更凸,A的曲线下面积,即AUC就更大。

随机模型的AUC是对角线下的面积,即0.5。所以任何合理的模型的AUC都应该大于0.5。

AUC的另一种解释

AUC还可以解释为,随机选取一个正样本和一个负样本,模型给正样本的分值高于负样本分值的概率。

这个解释与以上用ROC曲线面积来做的定义之间的关系,见StackExchange

AUC的计算

根据以上对AUC的解释,可以实现一种最简单的\(O(n^2)\)复杂度的计算方法。

点击查看代码
import numpy as np

y    = np.array([1,   0,   0,   0,   1,    0,   1,    0,    0,   1  ])
pred = np.array([0.9, 0.4, 0.3, 0.9, 0.35, 0.6, 0.65, 0.32, 0.8, 0.7])

def auc():
    pos = pred[y==1]
    neg = pred[y==0]
    correct = 0
    for i in pos:
      for j in neg:
        if i > j:
          correct += 1
        elif i == j:
          correct += 0.5
    return correct / (len(pos) * len(neg))
print(auc())

from sklearn import metrics
fpr, tpr, thresholds = metrics.roc_curve(y, pred, pos_label=1)
print(metrics.auc(fpr, tpr))

AUC的适用与不适用

适用

  • 仅关心相对序,不考虑分值大小时
  • 与阈值无关时
  • 要求对正负样本比例不敏感时,如对负样本下采样

不适用

  • 关心分值大小时
  • 某类正样本或负样本更重要时,如email spam classification

参考

https://stats.stackexchange.com/questions/132777/what-does-auc-stand-for-and-what-is-it/133435#133435
https://developers.google.com/machine-learning/crash-course/classification/roc-and-auc
https://www.dataschool.io/roc-curves-and-auc-explained/
https://tracholar.github.io/machine-learning/2018/01/26/auc.html
https://stats.stackexchange.com/questions/190216/why-is-roc-auc-equivalent-to-the-probability-that-two-randomly-selected-samples
https://ccrma.stanford.edu/workshops/mir2009/references/ROCintro.pdf
https://zhuanlan.zhihu.com/p/411010918
https://medium.com/@penggongting/understanding-roc-auc-pros-and-cons-why-is-bier-score-a-great-supplement-c7a0c976b679
https://stats.stackexchange.com/questions/105501/understanding-roc-curve
https://en.wikipedia.org/wiki/Receiver_operating_characteristic

标签:AUC,ROC,阈值,样本,关于,FPR,TPR
From: https://www.cnblogs.com/maxuewei2/p/18045872

相关文章

  • 关于STM32Fx部分引脚不可以正常输出高低电平的解决办法(不可以正常使用)
    一、概述在一次电路版测试中,发现stm32的部分引脚不可以正常的输出高低电平,刚开始以为是板子没有焊接好所以导致的经过多次的测试,发现电路版没问题。当时就想不清楚了,后面就问学长,还有实验室的学长一起测试。刚开始我们经过测试,认为是SCL的问题,认为在某个地方该引脚被......
  • 关于函数形参里使用const型引用
    刷leetcode的时候,在sort函数里自己实现了一个比较算法:sort(points.begin(),points.end(),[](constvector<int>u,constvector<int>v){returnu[0]<v[0]||(u[0]==v[0]&&u[1]<v[1]);});但令人遗憾的是他在某个包含几百个输入的样例中超时了,但只要稍加改动:sort(points.begin(......
  • 软件开发与创新第一周实验——关于“打怪小游戏”的试玩体验与修改
    一.“打怪小游戏”代码来源http://blog.csdn.net/zjx120307/article/details/126221342?spm=1001.2014.3001.5506二.运行环境及运行结果1.运行环境:Windows11操作系统,C++运行环境2.运行截图:(1)功能6演示(2)功能1演示(3)功能2演示(4)功能3演示(5)功能4演示原代码:点击查看代......
  • 关于C语言结构体
    1.C语言的结构体struct是一个数据类型,这样理解和int,char,float等一样都是数据类型,不过这个数据类型比较特殊,它是由好几种不同的数据类型组成;如:struct{inta,charb,floatc,}Name;解释一下,结构体是数据类型,所以就要先定义在使用,这里定义了一个名为Name的结构体里面有三个数据......
  • 关于SpringMVC中@RequestMapping的params参数
    @RequestMapping注解的params参数同一个url,只要params不同,springmvc也是会区分匹配的。@PostMapping("/reduceProductStock")publicStringreduceProductStock(@RequestParamLongproductId,@RequestParamIntegerquantity){productService.reduceProductStock(pr......
  • 关于KMP模式匹配的一些思考
    算法简介模式匹配给定主串text和模式串pattern,在主串中查找,如果找到了模式串,返回模式串在主串中的起始位置,从1开始计数。暴力求解求解模式匹配算法的核心思想是:蛮力法。即使用两个指针i和j,其中i指针用来遍历text,j指针用来遍历pattern。当text[i]==text[j]的时候,继续比较;如果不......
  • 关于标注软件
    毕设课题:基于交互式分割的工业产品缺陷自动标注系统设计与实现具体分类:机器学习》深度学习》计算机视觉》图像分割》标注前景:市面上的标注服务和标注软件:图像标注公司:京东众智,百度众测,figure-eight图像标注工具:https://zhuanlan.zhihu.com/p/481126342进展:1.......
  • 关于pacemaker-集群-token-网络心跳检测时间的修改
    在笔者操作系统Redhat8.8中,pacemaker默认的token时间为3000毫秒,也可以理解成心跳检测时间这样根据默认的规则,consensus有时间如果没有特别指定的话,将是token*1.2,即3600毫秒[root@azdb01qq-5201351]#corosync-cmapctl|grep'totem.token\|consensus'runtime.config.tote......
  • 关于import cvxopt :ImportError: DLL load failed: 找不到指定的模块。
    前提:前天再写python代码时遇到需要使用到cvxopt包求解QP问题,但是之前却没有安装过这个包,所以对其进行安装。报错:在pipinstallcvxopt后直接使用,出现报错。之后在网上查各种解决办法的方案,但在运行后均出现不同报错情况。我所需要解决的问题主要是numpy、scipy和cvxopt之间不兼容......
  • C#的Winform程序关于单击和双击的区别 - 开源研究系列文章
          前些天编码的时候有个关于应用程序的托盘图标的鼠标MouseDown里的单击和双击的问题,只是想单击的时候显示主窗体,双击的时候显示操作窗体。但是编码并调试的时候发现Windows的鼠标双击的事件先执行的单击事件然后才执行双击事件,于是就找了度娘,并且在园子的博问里发布......