auc如何计算 ?附python 代码

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

1 三种求解方法

方法 1

在有 M M M个正样, N N N个负样本的数据集里。一共有 M ∗ N M*N MN对样本(一对样本即,一个正样本与一个负样本)。统计这M*N对样本里,正样本的预测概率大于负样本的预测概率的个数。

∑ I ( P r e d p o s , P r e d n e g ) M ∗ N \frac{\sum {I(Pred_{pos}, Pred_{neg})}}{M * N} MNI(Predpos,Predneg)

如果 P r e d p o s > P r e d n e g Pred_{pos} > Pred_{neg} Predpos>Predneg I ( P r e d p o s , P r e d n e g ) = 1 I(Pred_{pos}, Pred_{neg}) = 1 I(Predpos,Predneg)=1,如果 P r e d p o s = P r e d n e g Pred_{pos} = Pred_{neg} Predpos=Predneg I ( P r e d p o s , P r e d n e g ) = 0.5 I(Pred_{pos}, Pred_{neg}) = 0.5 I(Predpos,Predneg)=0.5,否则为0.

- label score
A 0 0.1
B 0 0.4
C 1 0.35
D 1 0.8

2个正样本,2个负样本, M = N = 2 M=N=2 M=N=2,有下面几个组合,(D,B),(D,A),(C,B),(C,A)。 在(D,B)样本对中,正样本D预测的概率大于负样本B预测的概率(也就是D的得分比B高),记为1。同理,对于(C,B)。正样本C预测的概率小于负样本C预测的概率,记为0.

上面AUC可以计算为 1 + 1 + 1 + 0 2 ∗ 2 = 0.75 \frac{1 + 1 + 1 + 0}{2 * 2} = 0.75 221+1+1+0=0.75

- label score
A 0 0.1
B 0 0.4
C 1 0.4
D 1 0.8

上面AUC可以计算为 1 + 1 + 1 + 0.5 2 ∗ 2 = 0.875 \frac{1 + 1 + 1 + 0.5}{2 * 2} = 0.875 221+1+1+0.5=0.875

方法 2

  • 对预测概率从高到低排序
  • 对每一个概率值设一个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

∑ i ∈ p o s i t i v e − c l a s s r a n k i − M ( 1 + M ) 2 M ∗ N \frac{\sum_{i\in positive-class} {rank_i} - \frac{M(1+M)}{2}}{M * N} MNipositiveclassranki2M(1+M)

以它为例

- label score
A 0 0.1
B 0 0.4
C 1 0.35
D 1 0.8

排序后

- label score rank
D 1 0.8 4
B 0 0.4 3
C 1 0.35 2
A 0 0.1 1

( 4 + 2 ) − 2 ∗ ( 2 + 1 ) 2 2 ∗ 2 = 0.75 \frac{(4 + 2) - \frac{2*(2 + 1)}{2}}{2 * 2} = 0.75 22(4+2)22(2+1)=0.75

如果出现得分一样的情况:

- label score rank
A 1 0.8 7
B 1 0.7 6
C 0 0.5 5
D 0 0.5 4
E 1 0.5 3
F 1 0.5 2
G 0 0.3 1

( 7 + 6 + 5 + 4 + 3 + 2 4 + 5 + 4 + 3 + 2 4 ) − 4 ∗ ( 4 + 1 ) 4 4 ∗ 3 = 0.833 \frac{(7 + 6 + \frac{5 + 4 + 3 + 2}{4} + \frac{5 + 4 + 3 + 2}{4}) - \frac{4*(4 + 1)}{4}}{4 * 3} = 0.833 43(7+6+45+4+3+2+45+4+3+2)44(4+1)=0.833

方法 3

AUC 曲线下的面积

2 python实现

下面code实现了前两种方法

# 方法1
def AUC1(label, pre):
    pos = [i for i in range(len(label)) if label[i] == 1]
    neg = [i for i in range(len(label)) if label[i] == 0]
    auc = 0
    for i in pos:
        for j in neg:
            if pre[i] > pre[j]:
                auc += 1
            elif pre[i] == pre[j]:
                auc += 0.5
    if not pos or not neg:
        return None
    return auc / (len(pos)*len(neg))

# 方法2
def AUC2(label, pre):
    new_data = [[p, l] for p, l in zip(pre, label)]
    new_data.sort(key = lambda x : x[0])
    score_index = {}
    for index, i in enumerate(new_data):
        if i[0] not in score_index:
            score_index[i[0]] = []
        score_index[i[0]].append(index + 1)
    rank_sum = 0.
    for i in new_data:
        if i[1] == 1:
            rank_sum += sum(score_index[i[0]]) / len(score_index[i[0]]) * 1.0
    pos = label.count(1)
    neg = label.count(0)
    if not pos or not neg:
        return None
    return (rank_sum - (pos * (pos + 1) * 0.5)) / (pos * neg)
        
label = [1, 1, 1, 1, 1, 1]
score = [0.1, 0.4, 0.35, 0.8, 0.8, 0.9]

print(AUC1(label, score))
print(AUC2(label, score))

欢迎关注微信公众号(算法工程师面试那些事儿),本公众号聚焦于算法工程师面试,期待和大家一起刷leecode,刷机器学习、深度学习面试题等,共勉~

算法工程师面试那些事儿

おすすめ

転載: blog.csdn.net/qq_40006058/article/details/121132989