python手写auc

文字版来源→原链接

AUC理解

随机抽出一对样本(一个正样本,一个负样本),然后用训练得到的分类器来对这两个样本进行预测,预测得到正样本的概率大于负样本概率的概率。

AUC计算

方法一:

在有M个正样本,N个负样本的数据集里。一共有M*N对样本(一对样本即,一个正样本与一个负样本)。 统计这些样本对里,正样本的预测概率大于负样本的预测概率的个数。
在这里插入图片描述

举个例子:
在这里插入图片描述

假设有4条样本。2个正样本,2个负样本,那么M*N=4。
即总共有4个样本对。分别是:(D,B),(D,A),(C,B),(C,A)。
在(D,B)样本对中,正样本D预测的概率大于负样本B预测的概率(也就是D的得分比B高),记为1;
同理,对于(C,B),正样本C预测的概率小于负样本C预测的概率,记为0。

那么auc如下:
在这里插入图片描述
假如出现得分一致的时候:
在这里插入图片描述

同样本是4个样本对,对于样本对(C,B)其I值为0.5。
在这里插入图片描述

方法二:

利公式:
● 对预测概率从高到低排序
● 对每一个概率值设一个rank值(最高的概率的rank为n,第二高的为n-1)
● rank实际上代表了该score(预测概率)超过的样本的数目
为了求的组合中正样本的score值大于负样本,如果所有的正样本score值都是大于负样本的,那么第一位与任意的进行组合score值都要大,我们取它的rank值为n,但是n-1中有M-1是正样例和正样例的组合这种是不在统计范围内的(为计算方便我们取n组,相应的不符合的有M个),所以要减掉,那么同理排在第二位的n-1,会有M-1个是不满足的,依次类推,故得到后面的公式M*(M+1)/2,我们可以验证在正样本score都大于负样本的假设下,AUC的值为1
● 除以M*N
在这里插入图片描述

举例说明:
在这里插入图片描述

排序。按概率排序后得到:
按照上面的公式,只把正样本的序号加起来也就是只把样本C,D的rank值加起来后减去一个常数项:
在这里插入图片描述
得到:
在这里插入图片描述
如果出现得分一样的情况:
在这里插入图片描述

假如有4个取值概率为0.5,而且既有正样本也有负样本的情况。计算的时候,其实原则就是相等得分的rank取平均值。具体来说如下:
先排序:
在这里插入图片描述

这里需要注意的是:相等概率得分的样本,无论正负,谁在前,谁在后无所谓。
由于只考虑正样本的rank值:
对于正样本A,其rank值为7
对于正样本B,其rank值为6
对于正样本E,其rank值为(5+4+3+2)/4
对于正样本F,其rank值为(5+4+3+2)/4

在这里插入图片描述

手动实现

import numpy as np
from sklearn import metrics
def calculate_auc_test(labels, preds):
    positive_num = sum(labels)
    negative_num = len(labels) - positive_num
    total_case = positive_num * negative_num
    sorted_indices = np.argsort(preds)  # 输出从小到大排序的索引,preds[i] = preds[sorted_indices[i]]
    sorted_indices_rank = np.argsort(sorted_indices) #对索引进行sort,输出rank值
    sorted_indices_rank += 1  # rank从1开始
    sum_rank = 0  
    for i in range(len(preds)):
        if labels[i] == 1:
            same_rank_index = np.argwhere(preds==preds[i]) # 找到所有相同概率值的索引
            same_rank = np.sum(sorted_indices_rank[same_rank_index])/float(len(same_rank_index)) #概率相同取均值
            sum_rank += same_rank
            
    satisfied_pair = sum_rank - positive_num*(positive_num+1)*0.5       
    return satisfied_pair / float(total_case)
    
            


# y_true = np.array([0,0,1,1])
# y_pred = np.array([0.1, 0.4, 0.35, 1.0])
y_true = np.array([1,1,0,0,1,1,0])
y_pred = np.array([0.8,0.3,0.5,0.4,0.1,0.5,0.7])
auc = calculate_auc_test(y_true, y_pred)
print('auc:', auc)

'''
调用函数库
'''
fpr, tpr, thresholds = metrics.roc_curve(y_true, y_pred)
score = metrics.auc(fpr, tpr)
print('auc_auto:', score)

输出:

auc: 0.375
auc_auto: 0.375
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值