zoukankan      html  css  js  c++  java
  • AUC两种计算方式

    1.通过ROC曲线面积计算AUC

    AUC(Area Under Curve)被定义为ROC曲线下的面积。

    ROC 曲线横坐标:假正率=FPR=FP/N:  预测为负 and 实际为正 / 实际为负

    ROC 曲线纵坐标:真正率=TPR= TP/P :预测为正 and 实际为正 / 实际为正

     注意:有相同预估值时,需要等当前预估值作为阈值的所有 tp,fp 算完,再更新最终 auc

    def calcAUC_byRocArea(label,pred):
        P = 0.0
        N = 0.0
        TP = 0.0
        FP = 0.0
        TPR = 0.0
        FPR = 0.0
        LAST_TRP = 0.0
        LAST_FPR = 0.0
        auc = 0.0
        for l in label:
            if l == 0:
                N+=1
            else:
                P+=1
        sample = zip(label,pred)
        sample_sorted = sorted(sample,key=lambda x: -x[1])
    
    
        for i,info in enumerate(sample_sorted):
            l,p = info
            if l == 1:
                TP+=1
            else:
                FP+=1
         
            if i !=0 and  i+1 < len(sample) and p == sample_sorted[i+1][1]:
                continue
            
            TPR = TP/P
            FPR = FP/N
            auc+=0.5*(TPR+LAST_TRP)*(FPR-LAST_FPR)
            LAST_FPR=FPR
            LAST_TRP=TPR
    
        return auc
    

      

    2.通过计算概率计算AUC

    AUC还有一种解释就是任取一对正负样本,正样本的预测值大于负样本的预测值的概率。

    2.1 暴力 时间复杂度 o(n2)

    (1)遍历 label, 选出正样本、负样本。

    (2)遍历正负样本 pair,记录正样本 pred> 负样本 pred 的个数为 cnt

    (3) auc = cnt / 正样本个数* 负样本个数。

     1 from sklearn.metrics import roc_auc_score
     2 import numpy as np
     3 
     4 def calcAUC_byProb(label,pred):
     5     pos_porb = []
     6     neg_prob = []
     7     for i in range(len(label)):
     8         if label[i] == 1:
     9             pos_porb.append(pred[i])
    10         elif label[i] == 0:
    11             neg_prob.append(pred[i])
    12     cnt = 0.0
    13     for p in pos_porb:
    14         for n in neg_prob:
    15             if (p>n):
    16                 cnt+=1
    17             elif(p == n):
    18                 cnt+=0.5
    19     return cnt / float(len(pos_porb)*len(neg_prob))
    20 
    21 y = np.array([1, 1, 1, 0,0])
    22 pred = np.array([0.6,0.3, 0.5 ,0.2,0.4])
    23 print("sklearn auc:",roc_auc_score(y, pred))
    24 #print("my auc calc by area:", calcAUC_byRocArea(y, pred))
    25 print("my auc calc by prob:", calcAUC_byProb(y, pred))

    2.2 动态规划,时间复杂度0(nlogn)

    (1)按照预估值降序,组成 pair。

    (2)遍历pair, 如果 label==1,记录正样本个数 pos,

    如果 label==0, 对于当前样本来说,前面所有的正样本个数pos就是 当前样本与所有正样本预估值大于当前负样本预估值的个数。

    (3)auc = pos / (pos *n-pos)

     1 def calcAUC_byProb(label,pred):
     2     sample = zip(label,pred)
     3     sample_sorted = sorted(sample,key=lambda x: -x[1])
     4     pos = 0
     5     cnt = 0
     6     last_pred = 0
     7     print(sample_sorted)
     8     for i in range(len(sample_sorted)):
     9         l,p = sample_sorted[i]
    10         if l == 1:
    11             pos+=1
    12         elif l == 0:
    13             cnt += pos
    14             if (i!=0 and last_pred ==p):
    15                 cnt-=0.5
    16         last_pred = p
    17     negs = len(label) - pos
    18     print (cnt,pos,negs)
    19     return float(cnt) / float(pos*negs)
  • 相关阅读:
    算法总结之 两个链表生成相加链表
    算法总结之 复制含有随机指针节点的链表
    算法总结之 将单向链表按某值划分成左边小、中间相等、右边大的形式
    在PHP5.3以上版本运行ecshop和ecmall出现的问题及解决方案
    windows下配置nginx+php环境
    ecmall程序结构图与数据库表分析
    ecmall数据字典
    Ecmall二次开发-增删改查操作
    PHP7:10件事情你需要知道的
    PHP命名空间规则解析及高级功能3
  • 原文地址:https://www.cnblogs.com/zle1992/p/15227396.html
Copyright © 2011-2022 走看看