首页 > 其他分享 >小白也能看懂的 AUC 曲线详解

小白也能看懂的 AUC 曲线详解

时间:2023-11-01 14:55:19浏览次数:59  
标签:index auc text AUC score 能看懂 true 详解

小白也能看懂的 AUC 曲线详解

简介

上篇文章 小白也能看懂的 ROC 曲线详解 介绍了 ROC 曲线。本文介绍 AUC。AUC 的全名为Area Under the ROC Curve,即 ROC 曲线下的面积,最大为 1。

根据 ROC 和 AUC 的关系,我们可以得到如下结论

  • ROC 曲线接近左上角 ---> AUC 接近 1:模型预测准确率很高
  • ROC 曲线略高于基准线 ---> AUC 略大于 0.5:模型预测准确率一般
  • ROC 低于基准线 ---> AUC 小于 0.5:模型未达到最低标准,无法使用

二分类 AUC

由 AUC 名称可知,可以先计算 ROC 曲线,得到 TPR 和 FPR 的坐标后再分段计算面积即可得到 AUC

下面是对应的 Python 代码

def auc_from_roc(fpr, tpr):
    """
    计算ROC面积
    fpr: 从小到大排序的fpr坐标
    tpr: 从小到大排序的tpr坐标
    """
    area = 0
    for i in range(len(fpr) - 1):
        area += trapezoid_area(fpr[i], fpr[i + 1], tpr[i], tpr[i + 1])
    return area
    
def trapezoid_area(x1, x2, y1, y2):
    """
    计算梯形面积
    x1, x2: 横坐标 (x1 <= x2)
    y1, y2: 纵坐标 (y1 <= y2)
    """
    base = x2 - x1
    height_avg = (y1 + y2) / 2
    return base * height_avg

也可以直接从真实标签和模型预测分数中计算 ROC,算法的时间复杂度为\(O(n\log n)\),参考文献 1 中的算法 2

# import numpy as np
def auc_binary(y_true, y_score, pos_label):
    """
    y_true:真实标签
    y_score:模型预测分数
    pos_label:正样本标签,如“1”
    """
    num_positive_examples = (y_true == pos_label).sum()
    num_negtive_examples = len(y_true) - num_positive_examples

    tp, fp, tp_prev, fp_prev, area = 0, 0, 0, 0, 0
    score = -np.inf

    for i in np.flip(np.argsort(y_score)):
        if y_score[i] != score:
            area += trapezoid_area(fp_prev, fp, tp_prev, tp)
            score = y_score[i]
            fp_prev = fp
            tp_prev = tp

        if y_true[i] == pos_label:
            tp += 1
        else:
            fp += 1

    area += trapezoid_area(fp_prev, fp, tp_prev, tp)
    area /= num_positive_examples * num_negtive_examples

    return area

多分类 AUC

现在考虑多分类的情况,假设类别数为\(C\)。

一种想法是将某一类别设为正样本类别,其余类别设为负样本类别,然后计算二分类下的 AUC。这种方法叫做一对多,即 One-Vs-Rest (OVR)。可以得到\(C\)个二分类的 AUC,然后计算平均数得到多分类的 AUC。

另一种想法是将某一类别设为正样本类别,另外一个类别(非自身)设为负样本类别计算二分类的 AUC。这种方法叫做一对一,即 One-Vs-One (OVO)。可以得到\(C(C-1)\)个二分类的 AUC,然后计算平均数。

当计算平均数时,可以考虑算数平均数(称为 macro),或者加权平均数(称为 weighted)。其中,加权为各类别的样本所占比例。因此,两两组合可以的得到四种计算多分类 AUC 的方法。值得一提的是,知名机器学习库 scikit-learn 的 roc_auc_score 函数 包含了上述四种方法。

  1. 一对多 + 算数平均数(OVR + macro)
  2. 一对多 + 加权平均数(OVR + weighted)
  3. 一对一 + 算数平均数(OVO + macro)
  4. 一对一 + 加权平均数(OVO + weighted)

一对多 + 算数平均数

多分类 AUC 的计算公式为

\[\text{AUC}_\text{total}=\frac{1}{C}\sum_{c_i\in C}\text{AUC}(c_i) \]

其中\(\text{AUC}(c_i)\)是将类别\(c_i\)作为正样本类别(剩余作为负样本类别),计算的二分类 AUC。

# sklearn.metrics.roc_auc_score(y_true, y_score, average='macro', multi_class='ovr')
def auc_ovr_macro(y_true, y_score):
    auc = 0
    C = max(y_true) + 1

    for i in range(C):
        auc += auc_binary(y_true, y_score[:, i], pos_label=i)

    return auc / C

一对多 + 加权平均数

多分类 AUC 的计算公式为

\[\text{AUC}_\text{total}=\sum_{c_i\in C}\text{AUC}(c_i)p(c_i) \]

其中,权重\(p(c_i)=\frac{\sum\mathbb{I}\{y=c_i\}}{n}\),即标签为\(c_i\)的样本所占比例,权重之和为 1。

# sklearn.metrics.roc_auc_score(y_true, y_score, average='weighted', multi_class='ovr')
def auc_ovr_weighted(y_true, y_score):
    auc = 0
    C = max(y_true) + 1
    n = len(y_true)

    for i in range(C):
        p = sum(y_true == i) / n
        auc += auc_binary(y_true, y_score[:, i], pos_label=i) * p

    return auc

一对一 + 算数平均数

多分类 AUC 的计算公式为

\[\text{AUC}_\text{total}=\frac{2}{C(C-1)}\sum_{\{c_i,c_j\}\in C,\ c_i<c_j}\text{AUC}(c_i,c_j) \]

其中,\(\text{AUC}(c_i,c_j)=\frac{\text{AUC}(c_i|c_j)+\text{AUC}(c_j|c_i )}{2}\)。即将\(c_i\)作为正样本类别、\(c_j\)作为负样本类别计算二分类\(\text{AUC}(c_i|c_j)\);然后将\(c_j\)作为正样本类别、\(c_i\)作为负样本类别计算二分类\(\text{AUC}(c_j|c_i)\)。\(\text{AUC}(c_i,c_j)\)为其计算的算数平均值。由于将\(c_i\)和\(c_j\)组合计算,共得到\(C(C-1)/2\) 个二分类 AUC。

# sklearn.metrics.roc_auc_score(y_true, y_score, average='macro', multi_class='ovo')
def auc_ovo_macro(y_true, y_score):
    auc = 0
    C = max(y_true) + 1

    for i in range(C - 1):
        i_index = np.where(y_true == i)[0]
        for j in range(i + 1, C):
            j_index = np.where(y_true == j)[0]
            index = np.concatenate((i_index, j_index))

            auc_i_j = auc_binary(y_true[index], y_score[index, i], pos_label=i)
            auc_j_i = auc_binary(y_true[index], y_score[index, j], pos_label=j)
            auc += (auc_i_j + auc_j_i) / 2

    return auc * 2 / (C * (C - 1))

一对一 + 加权平均数

多分类 AUC 的计算公式为

\[\text{AUC}_\text{total}=\sum_{\{c_i,c_j\}\in C,\ c_i<c_j}\text{AUC}(c_i,c_j)p(c_i,c_j) \]

其中,权重\(p(c_i,c_j)=\frac{\sum\mathbb{I}\{y=c_i\}+\sum\mathbb{I}\{y=c_j\}}{(C-1)n}\),即标签为\(c_i\)和\(c_j\)的样本所占比例,分母中的系数\(C-1\)使得权重之和为 1。

# sklearn.metrics.roc_auc_score(y_true, y_score, average='weighted', multi_class='ovo')
def auc_ovo_weighted(y_true, y_score):
    auc = 0
    C = max(y_true) + 1
    n = len(y_true)

    for i in range(C - 1):
        i_index = np.where(y_true == i)[0]
        for j in range(i + 1, C):
            j_index = np.where(y_true == j)[0]
            index = np.concatenate((i_index, j_index))

            p = len(index) / n / (C - 1)
            auc_i_j = auc_binary(y_true[index], y_score[index, i], pos_label=i)
            auc_j_i = auc_binary(y_true[index], y_score[index, j], pos_label=j)
            auc += (auc_i_j + auc_j_i) / 2 * p

    return auc

参考文献

  1. Fawcett, Tom. "An introduction to ROC analysis." Pattern recognition letters 27, no. 8 (2006): 861-874. https://www.researchgate.net/profile/Tom-Fawcett/publication/222511520_Introduction_to_ROC_analysis/links/5ac7844ca6fdcc8bfc7fa47e/Introduction-to-ROC-analysis.pdf
  2. Hand, David J., and Robert J. Till. "A simple generalisation of the area under the ROC curve for multiple class classification problems." Machine learning 45 (2001): 171-186. https://link.springer.com/content/pdf/10.1023/A:1010920819831.pdf

作者:PrimiHub-Kevin

标签:index,auc,text,AUC,score,能看懂,true,详解
From: https://www.cnblogs.com/primihub/p/17803113.html

相关文章

  • SAP Fiori Elements 应用里的 ui5.yaml 文件详解试读版
    本教程第4篇文章,我们介绍了本地启动SAPFioriElements应用的三种模式。4.SAPFioriElements本地应用启动的三种模式辨析以默认方式即命令行yarnstart启动之后,项目文件夹里的ui5.yaml文件会默认被加载并解析。ui5.yaml这个文件,在本地开发FreestyleUI5时也会遇到,笔......
  • Linux 挂载磁盘详解及实操步骤
    转自:https://www.jb51.net/server/288639rwu.htm步骤如下:一、磁盘分区在Linux中,磁盘是通过分区来使用的。分区是将一个硬盘划分成几个逻辑部分来使用,在每个分区中可以存储不同的文件系统。因此,在挂载磁盘之前,我们需要先对磁盘进行分区。磁盘分区的过程可以通过命令行工具或图形......
  • 详解Java ArrayList
    ArrayList简介ArrayList是List接口的实现类,底层基于数组实现,容量可根据需要动态增加,相当于动态数组。ArrayList继承于AbstractList,并且还实现了Cloneable、Serializable、RandomAccess接口。List:表明是列表数据结构,可以通过下标对元素进行添加删除或查找。Serializable:表示可......
  • c#享元模式详解
    基本介绍:  享元模式的定义:运用共享技术有效地支持大量细粒度的对象重复使用。适用于大量小粒度的对象造成的运行效率和内存使用效率低下的情况。  “享元”顾名思义,“享”共享的意思,“元”单元,最小对象,零部件的意思。  即从字面意思不难看出,该模式旨在共享一些零部件供其......
  • 什么是威廉姆斯的三维结构?澳福详解作用
    从心理学视角出发,威廉姆斯将市场视为一个三维结构,包含了时间、价格与交易者的心理三大组成部分。他提出的成功交易策略是“随波逐流,乘风破浪,随波逐流”。为了培养这种思维方式,交易者应学会如何将自身的观念、观点和信念暂时搁置一旁,避免受恐惧心理与他人观点的影响而分散注意力。在......
  • 神经网络基础篇:详解逻辑回归 & m个样本梯度下降
    逻辑回归中的梯度下降本篇讲解怎样通过计算偏导数来实现逻辑回归的梯度下降算法。它的关键点是几个重要公式,其作用是用来实现逻辑回归中梯度下降算法。但是在本博客中,将使用计算图对梯度下降算法进行计算。必须要承认的是,使用计算图来计算逻辑回归的梯度下降算法有点大材小用了。......
  • k8s pvc详解
    一、概述PVC的全称是:PersistentVolumeClaim(持久化卷声明),PVC是用户存储的一种声明,PVC和Pod比较类似,Pod消耗的是节点,PVC消耗的是PV资源,Pod可以请求CPU和内存,而PVC可以请求特定的存储空间和访问模式。对于真正使用存储的用户不需要关心底层的存储实现细节,只需要直接使......
  • BFD的参数详解
    ver:BFD协议版本号,目前为1diag:诊断字,标明本地BFD系统最近一次会话状态发生的原因p:参数发生变化时,发送方再BFD报文中置该标志,接收方必须立即响应该报文F:响应p标志置位的回应报文中必须将F标志置位C:转发/控制分离标志,一旦置位,控制平面的变化不影响BFD检查A:认证标识,置1代表会话需要进行......
  • 软件测试|Python对JSON的解析和创建详解
    简介JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,已经成为当今互联网应用中广泛使用的数据格式之一。Python提供了内置的模块来解析和创建JSON数据,使得在Python中处理JSON变得非常简单。本文将详细介绍Python对JSON的解析和创建过程,并提供示例代码来帮助大家更好......
  • 软件测试|MySQL唯一约束详解
    简介MySQL唯一约束(UniqueKey)是指所有记录中字段的值不能重复出现。MySQL中的唯一约束是一种用于确保表中某列或多列的取值唯一的数据库约束。唯一约束的作用是防止表中出现重复的值,确保数据的完整性和一致性。在本文中,我们将详细介绍MySQL中唯一约束的定义、用法以及其在数据......