ACU个人详解的理解及代码实现

ACU详解及代码实现

ROC曲线

理解AUC需要首先理解ROC曲线,AUC是ROC曲线的面积。
详细参考这个博士AUC详解

AUC计算

方法一:

有M个正样本,N个负样本,一共有M*N个样本对,也就是说从M和N中分别取样,然后组成一个样本对,然后计算对正样本对预测概率大于对负样本预测的概率。
∑ I ( P p o s , P n e c ) M × N \frac{\sum I(P_{pos},P_{nec})}{M \times N} M×NI(Ppos,Pnec)
举个例子:

DLablepre
A00.1
B00.4
C10.35
D10.8

这里假设有4个样本,2个正样本和两个负样本。我们所指的概率就是pre,需需要注意的是pre是软概率,也就是越接近1就是正,越接近0就是负,而不是分别针对正负分别预测的,这个很关键,开始我就理解错了。
这里我就是直观的希望对正样本的预测概率大于正样本的。
具体的,这里有四个样本对(C,A),(C,B),(D,A) 和(D,B),这里只有(C,B)是不满足的,应该为零,其他的是1.
那么auc:
1 + 1 + 1 + 0 2 ∗ 2 = 0.75 \frac{1+1+1+0}{2 * 2} = 0.75 221+1+1+0=0.75
如果两个概率相等,那么 I = 0.5 I=0.5 I=0.5

方法二:

这个方法本质和方法一是一样的,只不过这里用数学规律进行了计算。

  • 首先将模型预测出来的概率从高到底进行排序(其中正样本M,负样本N个)
  • 每个样本设置了一个rank,概率最高的rank是n,其次是n-1。
  • 这里的rank实际上就是每一个样本的概率大于多少的样本数量。
    基于上面的条件,我们可以发现:
    如果我们想要得到的就是每个正样本的概率大于负样本的概率的数量,然后求和。那么,如果概率最大的样本(rank为n)他一定大于剩余的n-1个样本,n-1个样本中有这个正样本M-1个,这M-1个其实并不是我们需要的,所以我们减去,那么就是我们把所有正样本的rank相加,再减去每次多余的正样本就可以了。
    举个例子:
样本ABCDEF
pre0.80.70.60.50.40.3
labelPNPNPN
rank654321

A的rank是6,那么代表他是大于等于6个节点的,很明显是包括自己以及其他的正样本,这些实际上应该被扣除,因为(A,正样本)是没有意义d的。也就是说:
A: 6 - M
C:4 - (M - 1)
E:2 - (M - 2)
减去的部分,实际上就是 M,M-1, … ,1, 0,这可以用公式 M ∗ M ( M + 1 ) / 2 M*M(M+1)/2 MM(M+1)/2,因此AUC表示为:
A U C = ∑ i ∈ p o s r a n k i − M ( 1 + M ) 2 M ∗ N AUC=\frac{\sum_{i \in posrank_i - \frac{M(1+M)}{2}}}{M * N} AUC=MNiposranki2M(1+M)
如果概率相同,则求rank的平均值。

import numpy as np
from sklearn.metrics import auc
from sklearn.metrics import roc_curve

def auc_calculate(labels, preds, n_bins=100):
    postive_len = sum(labels)
    negative_len = len(labels) - postive_len
    total_case = postive_len * negative_len
    pos_hist = [0] * n_bins  # 直方图长度就是100,因为概率是0-1,乘以100,就是0-100
    neg_hist = [0] * n_bins
    bin_width = 1.0 / n_bins
    for i in range(len(labels)):
        nth_bin = int(preds[i] / bin_width)
        if labels[i] == 1:
            pos_hist[nth_bin] += 1
        else:
            neg_hist[nth_bin] += 1
    accumulated = 0  # 用于累加比pos_hist[i]概率小的负样本的个数
    satisfied = 0

    for i in range(n_bins):
        satisfied += (pos_hist[i] * accumulated + pos_hist[i] * neg_hist[i] * 0.5)  # *0.5是为了计算两个样本概率相等的情况
        accumulated += neg_hist[i]

    return satisfied / float(total_case)

if __name__ == '__main__':
    y = np.array([1, 0, 0, 0, 1, 0, 1, 0, ])
    pred = np.array([0.9, 0.8, 0.3, 0.1, 0.4, 0.9, 0.66, 0.7])

    fpr, tpr, thresholds = roc_curve(y, pred, pos_label=1)
    print("-----sklearn:", auc(fpr, tpr))
    print("-----py脚本:", auc_calculate(y, pred))

结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请叫我哈士奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值