AUC曲线计算方法及代码实现

本文介绍了计算AUC(Area Under Curve)的三种方法:直接计算面积、概率统计和秩和方法,并提供了Python代码实现。通过排序样本得分,计算正负样本对中正样本得分大于负样本得分的概率,从而求得AUC值。同时,文章讨论了处理得分相等情况的策略,确保计算的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AUC计算  

1. 根据定义Aera Under Curve,计算面积。样本有限,所以得到的AUC曲线一般是个阶梯状,所以计算这些阶梯的面积即可。先按score排个序,然后从头遍历一遍,把每个score作为划分阈值,可以得到对应的TPR和FPR,计算出底下的面积。更直观的计算方法,参考《百面机器学习》:

这种直接计算面积的方法比较麻烦,一般使用下面的等价方法进行计算。

2. AUC等价于:测试任意给一个正类样本和一个负类样本,正类样本的score有多大的概率大于负类样本的score。所以可以计算这个概率。具体来说就是统计一下所有的 M×N(M为正类样本的数目,N为负类样本的数目)个正负样本对中,有多少个组中的正样本的score大于负样本的score。当二元组中正负样本的 score相等的时候,按照0.5计算。然后除以MN。实现这个方法的复杂度为O(n^2)。n为样本数(即n=M+N)
3.  第三种方法实际上和上述第二种方法是一样的,但是复杂度减小了。它也是首先对score从大到小排序,然后令最大score对应的sample 的rank为n,第二大score对应sample的rank为n-1,以此类推。然后把所有的正类样本的rank相加,再减去M-1种两个正样本组合的情况。得到的就是所有的样本中有多少对正类样本的score大于负类样本的score。然后再除以M×N。即 

 公式解释:

        1、为了求的组合中正样本的score值大于负样本,如果所有的正样本score值都是大于负样本的,那么第一位与任意的进行组合score值都要大,我们取它的rank值为n,但是n-1中有M-1是正样例和正样例的组合这种是不在统计范围内的(为计算方便我们取n组,相应的不符合的有M个),所以要减掉,那么同理排在第二位的n-1,会有M-1个是不满足的,依次类推,故得到后面的公式M*(M+1)/2,我们可以验证在正样本score都大于负样本的假设下,AUC的值为1

      2、根据上面的解释,不难得出,rank的值代表的是能够产生score前大后小的这样的组合数,但是这里包含了(正,正)的情况,所以要减去这样的组(即排在它后面正例的个数),即可得到上面的公式

      另外,特别需要注意的是,在存在score相等的情况时,对相等score的样本,需要 赋予相同的rank(无论这个相等的score是出现在同类样本还是不同类的样本之间,都需要这样处理)。具体操作就是再把所有这些score相等的样本 的rank取平均。然后再使用上述公式。(以下代码中未对rank求平均,但结果与sklearn中的auc计算基本一致)

详细解释如下:(暂时不考虑样本score 相等的情况)

n -- 正负样本之和

随机抽取一个样本, 对应每一潜在可能值X都对应有一个判定位正样本的概率P。

对一批已知正负的样本集合进行分类,

按score从高到矮排个降序, 对于正样本中概率最高的,排序为rank_1 = n, 比它概率小的有M-1个正样本(M为正样本个数),

(rank_1 - (M-1)- 1) =  (rank_1 - M)   个负样本 ------ 即 当前正样本score 大于负样本 score 的正负样本对个数为  (rank_1 - M)

正样本概率第二高的, 排序为rank_2, 比它概率小的有M-2个正样本,(rank_2 - (M - 2) - 1) = (rank_2 - M + 1) 个 负样本。

以此类推

正样本中概率最小的, 排序为rank_M,比它概率小的有0个正样本,(rank_M - (0) - 1) = rank_M - 1 个负样本。

总共有MxN个正负样本对(N为负样本个数)。把所有比较中 正样本概率大于负样本概率 的例子都算上, 得到公式((rank_1 - M) + (rank_2 - M + 1 ).... +( rank_M - 1)) / (MxN) 就是正样本概率大于负样本概率的可能性了。 化简后(因为后面是个等差数列)得:

{ rank_1 + rank_2  + rank_3 .... + rank_M - (M + (M - 1) + (M - 2) +  ......  +1)} /  (M x N)

import numpy as np
from sklearn.metrics import roc_auc_score
 
 
def calc_auc(y_labels, y_scores):
    f = list(zip(y_scores, y_labels))
    rank = [values2 for values1, values2 in sorted(f, key=lambda x:x[0])]
    rankList = [i+1 for i in range(len(rank)) if rank[i] == 1]
    pos_cnt = np.sum(y_labels == 1)
    neg_cnt = np.sum(y_labels == 0)
    auc = (np.sum(rankList) - pos_cnt*(pos_cnt+1)/2) / (pos_cnt*neg_cnt)
    print(auc)
 
 
def get_score():
    # 随机生成100组label和score
    y_labels = np.zeros(100)
    y_scores = np.zeros(100)
    for i in range(100):
        y_labels[i] = np.random.choice([0, 1])
        y_scores[i] = np.random.random()
    return y_labels, y_scores
 
 
if __name__ == '__main__':
    y_labels, y_scores = get_score()
    # 调用sklearn中的方法计算AUC,与后面自己写的方法作对比
    print('sklearn AUC:', roc_auc_score(y_labels, y_scores))
    calc_auc(y_labels, y_scores)


 
 
 

<think>好的,用户想查找关于AUC代码实现示例。我需要先回忆一下AUC的基本概念和计算方法,确保提供的代码准确。 AUC通常是通过计算ROC曲线下的面积来得到。根据引用[2]和[3],AUC实现方法有两种:一种是基于概率预测值排序,计算正样本排在负样本前面的概率;另一种是通过梯形法则近似积分ROC曲线下的面积。 用户可能需要具体的Python代码示例,所以我要选择常用的实现方式。根据引用[3],方法二更常用,即按照正负样本对的比较来计算。但考虑到计算效率,当数据量大时,可能需要更优化的方法,比如使用sklearn的roc_auc_score函数,如引用[4]提到的。 我应该提供两种实现:一种是手动实现的示例,另一种是调用sklearn库的方法。这样用户既能理解原理,又能快速应用到实际中。手动实现部分,需要先对预测概率排序,然后统计正样本的排名,计算有多少负样本排在其前面。这个方法的时间复杂度是O(n log n),主要来自排序步骤。 另外,需要解释代码的关键步骤,比如排序、计算正样本的排名和数量,以及如何应用公式。同时提醒用户注意数据输入的格式,比如y_true的二元标签和y_score的概率值。 还要考虑正负样本的处理,比如当数据中没有负样本或正样本时,代码是否健壮。可能需要添加异常处理,但为了示例简洁,可以省略,但给出注意事项。 最后,引用相关参考资料,如引用[3]中的分组计算GAUC的情况,但用户主要关注AUC,所以可能不需要展开。确保代码示例正确,并测试过。</think>以下为AUC指标的代码实现示例及原理说明: ### 一、AUC指标实现原理 AUC的计算主要基于正负样本对的比较关系,核心公式为: $$AUC = \frac{\sum_{正样本} rank_{正样本} - \frac{M(M+1)}{2}}{M \times N}$$ 其中$M$为正样本数,$N$为负样本数,$rank$为样本预测概率的排序值[^3] ### 二、Python代码实现 #### 方法1:手动实现 ```python import numpy as np def calculate_auc(y_true, y_score): # 将正负样本分离 pos_scores = [y_score[i] for i in range(len(y_true)) if y_true[i] == 1] neg_scores = [y_score[i] for i in range(len(y_true)) if y_true[i] == 0] # 创建联合排序序列 combined = sorted(zip(y_score, y_true), key=lambda x: x[0], reverse=True) rank_sum = 0 for idx, (score, label) in enumerate(combined): if label == 1: rank_sum += idx + 1 # 排名从1开始计算 M = len(pos_scores) N = len(neg_scores) auc = (rank_sum - M*(M+1)/2) / (M*N) return auc ``` #### 方法2:使用sklearn库 ```python from sklearn.metrics import roc_auc_score # 示例数据 y_true = [1, 0, 1, 1, 0] y_score = [0.9, 0.8, 0.7, 0.6, 0.5] # 计算AUC auc = roc_auc_score(y_true, y_score) print(f"AUC值为: {auc:.4f}") ``` ### 三、代码说明 1. **输入要求**:`y_true`为二元标签(0/1),`y_score`为预测概率值 2. **排序原理**:将样本按预测概率从高到低排序,正样本的排名决定AUC值[^2] 3. **异常处理**:当数据全为同一类别时,AUC无法计算,需添加异常检测
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值