Loading...
墨滴

algolearn

2021/11/03  阅读:27  主题:默认主题

auc的计算和实现

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

1 三种求解方法

方法 1

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

如果 ,如果 ,否则为0.

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

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

上面AUC可以计算为

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

上面AUC可以计算为

方法 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

以它为例

- 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

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

- 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

方法 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,刷机器学习、深度学习面试题等,共勉~

算法工程师面试那些事儿
算法工程师面试那些事儿

algolearn

2021/11/03  阅读:27  主题:默认主题

作者介绍

algolearn