auc的计算方法

方法一

用指示函数表示上式中正样本预测值大于负样本预测值的正负样本对,则得到
在这里插入图片描述
p表示预测得分。

在给出的例子中,包含有2个正样本(A, B)和3个负样本(C, D, E),因此一共有6个(2*3)正负样本对,即公式中分母为6。

接下来计算公式中的分子,即每个正负样本对的指示函数值:

  • 以A为正样本形成的正负样本对为(A, C), (A, D), (A, E),指示函数值分别为1,0.5,0;
  • 以B为正样本形成的正负样本对为(B, C), (B, D), (B, E),指示函数值分别为1,1,1。
    在这里插入图片描述
    这种方法计算AUC的时间复杂度为O(P*N)

方法二

用方法1计算AUC易于理解,但需要对所有样本对计算指示函数值,有没有不需要对所有样本对遍历的方法?

AUC计算的关键是找到所有正样本预测值大于负样本预测值的正负样本对。

  • 如果引入排序,则大小关系就可以确定;
  • 如果有正样本的排序序号,则可以每一个正样本有多少样本的分数比他低(这其中包括正负样本对,也包括正正样本对),若减去正正样本对数量就是AUC计算需要的正负样本对。

在这里插入图片描述
举例来说:
在这里插入图片描述
在上面的例子中出现了正样本A与负样本D得分相等的情况,这时候A排序值由相同得分的排序值算平均值,即(2+3)/2=2.5。

这样,2.5+5 = 7.5(说明一共有7.5个样本对,正样本打分高于其他样本),然后7.5中还包括正正样本对,大小为M(M+1)/2, 则所有正样本中,正样本大于负样本打分的样本对有7.5-2(2+1)/2=4.5。分母不变=2*3

则auc为:
在这里插入图片描述

代码

import numpy as np
from sklearn.metrics import roc_auc_score

# python sklearn包计算auc
def get_auc(y_labels, y_scores):
    auc = roc_auc_score(y_labels, y_scores)
    print('AUC calculated by sklearn tool is {}'.format(auc))
    return auc

# 方法1计算auc
def calculate_auc_func1(y_labels, y_scores):
    pos_sample_ids = [i for i in range(len(y_labels)) if y_labels[i] == 1]
    neg_sample_ids = [i for i in range(len(y_labels)) if y_labels[i] == 0]

    sum_indicator_value = 0
    for i in pos_sample_ids:
        for j in neg_sample_ids:
            if y_scores[i] > y_scores[j]:
                sum_indicator_value += 1
            elif y_scores[i] == y_scores[j]:
                sum_indicator_value += 0.5

    auc = sum_indicator_value/(len(pos_sample_ids) * len(neg_sample_ids))
    print('AUC calculated by function1 is {:.2f}'.format(auc))
    return auc

# 方法2计算auc, 当预测分相同时,未按照定义使用排序值的均值,而是直接使用排序值,当数据量大时,对auc影响小
def calculate_auc_func2(y_labels, y_scores):
    samples = list(zip(y_scores, y_labels))
    rank = [(values2, values1) for values1, values2 in sorted(samples, key=lambda x:x[0])]
    pos_rank = [i+1 for i in range(len(rank)) if rank[i][0] == 1]
    pos_cnt = np.sum(y_labels == 1)
    neg_cnt = np.sum(y_labels == 0)
    auc = (np.sum(pos_rank) - pos_cnt*(pos_cnt+1)/2) / (pos_cnt*neg_cnt)
    print('AUC calculated by function2 is {:.2f}'.format(auc))
    return auc


if __name__ == '__main__':
    y_labels = np.array([1, 1, 0, 0, 0])
    y_scores = np.array([0.4, 0.8, 0.2, 0.4, 0.5])
    get_auc(y_labels, y_scores)
    calculate_auc_func1(y_labels, y_scores)
    calculate_auc_func2(y_labels, y_scores)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值