AUC的全称是Area under the Curve of ROC,也就是ROC曲线下方的面积,另外一种重要的表达形式是:分别随机从正负样本集中抽取一个正样本,一个负样本,正样本的预测值大于负样本的概率。

auc计算公式(AUC计算方式及代码实现)

ROC曲线该怎么理解呢?首先,需要指出的是,ROC分析的是二元分类模型,也就是输出结果只有两种类别的模型,比如:(阳性/阴性)(有病/没病)(垃圾邮件/非垃圾邮件)。在二分类问题中,数据的标签通常用(0/1)来表示,在模型训练完成后进行测试时,会对测试集的每个样本计算一个介于0~1之间的概率,表征模型认为该样本为阳性的概率,我们可以选定一个阈值,将模型计算出的概率进行二值化,比如选定阈值=0.5,那么当模型输出的值大于等于0.5时,我们就认为模型将该样本预测为阳性,也就是标签为1,反之亦然。选定的阈值不同,模型预测的结果也会相应地改变。二元分类模型的单个样本预测有四种结果:

  • 真阳性(TP):判断为阳性,实际也是阳性。
  • 伪阳性(FP):判断为阴性,实际却是阳性。
  • 真阴性(TN):判断为阴性,实际也是阴性。
  • 伪阴性(FN):判断为阴性,实际却是阳性。

这四种结果可以画成2 × 2的混淆矩阵:

auc计算公式(AUC计算方式及代码实现)

有了混淆矩阵,就可以定义ROC曲线了。ROC曲线将假阳性率(FPR)定义为 X 轴,真阳性率(TPR)定义为 Y 轴。其中:

  • TPR:在所有实际为阳性的样本中,被正确地判断为阳性的样本比率。
  • FPR:在所有实际为阴性的样本中,被错误地判断为阳性的样本比率。
  • TPR = TP / (TP + FN)
  • FPR = FP / (FP + TN)

auc计算公式(AUC计算方式及代码实现)

代码

# AUC的计算
import numpy as np
import matplotlib.pyplot as plt

pred= list(np.random.uniform(low=0, high=1, size=1000))
labels = [int(prob>0.5) for prob in list(np.random.uniform(low=0,high=1, size=1000))]

#方法一:求roc面积
def cal_auc1(pred, labels):
    num = len(labels)
    auc = 0

    roc_point = []
    for i in range(num):
        pos = pred[i]
        TP = 0
        FP = 0
        FPR = 0
        TPR = 0
        pos_num = 0

        for inx, prob in enumerate(pred):
            if prob > pos:
                pos_num +=1
            if prob > pos and labels[inx] == 1:
                TP +=1
            if prob > pos and labels[inx] == 0:
                FP +=1

        if pos_num > 0:
            TPR = TP / sum(labels)
            FPR = FP / (num - sum(labels))
        roc_point.append([FPR,TPR])

    roc_point.sort(key=lambda x: x[0])
    lastx = 0
    for x,y in roc_point:
        auc += (x-lastx)*y  # 底乘高
        lastx = x
    return auc


# 方法二 定义
def cal_auc2(pred,labels):
    num = 0
    pos_pred = []
    neg_pred = []
    for prob, label in  zip(pred,labels):
        if label == 1:
            pos_pred.append(prob)
        else:
            neg_pred.append(prob)

    for i in pos_pred:
        for j in neg_pred:
            if i > j :
                num +=1
    auc = num/(len(pos_pred)*len(neg_pred))
    return auc

if __name__ == \'__main__\':
    print(cal_auc1(pred,labels))
    print(cal_auc2(pred,labels))

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。