AUC值計(jì)算與實(shí)現(xiàn)

AUC(Area under curve)是機(jī)器學(xué)習(xí)常用的二分類評(píng)測手段,直接含義是ROC曲線下的面積。
ROC曲線理解起來更加的復(fù)雜且計(jì)算工程更加麻煩扣典,因此從計(jì)算概率的角度理解AUC
也可以理解為:隨機(jī)抽出一對樣本(一個(gè)正樣本揍鸟,一個(gè)負(fù)樣本),然后用訓(xùn)練得到的分類器來對這兩個(gè)樣本進(jìn)行預(yù)測吴汪,預(yù)測得到正樣本的概率大于負(fù)樣本概率的概率。

那如何實(shí)現(xiàn)這樣的計(jì)算呢蒸眠?
我們從字面上的意思開始理解
一對樣本漾橙,根據(jù)模型預(yù)測的結(jié)果,預(yù)測得到正樣本的概率大于負(fù)樣本概率的概率楞卡。
因此計(jì)算方法即為如下:

在有M個(gè)正樣本,N個(gè)負(fù)樣本的數(shù)據(jù)集里霜运。
一共有 MxN 對樣本(一對樣本即,一個(gè)正樣本與一個(gè)負(fù)樣本)蒋腮。
統(tǒng)計(jì)這 MxN 對樣本里淘捡,正樣本的預(yù)測概率大于負(fù)樣本的預(yù)測概率的個(gè)數(shù)

image.png

舉個(gè)例子:

class label pre
A 0 0.1
B 0 0.4
C 1 0.3
D 1 0.8

假設(shè)有4條樣本池摧。2個(gè)正樣本焦除,2個(gè)負(fù)樣本,那么MxN=4作彤。
即總共有4個(gè)樣本對膘魄。分別是:
(C,A), (C,B), (D,A), (D,B)

在(C,B)樣本對中乌逐,正樣本C預(yù)測的概率小于負(fù)樣本B預(yù)測的概率(也就是C的得分比B低),記為0
在(D,B)樣本對中创葡,正樣本D預(yù)測的概率大于負(fù)樣本B預(yù)測的概率(也就是D的得分比B高)浙踢,記為1
所以最后的AUC結(jié)果即為:
(C,A), (C,B), (D,A), (D,B) =1+0+1+1
總樣本對為MxN=4
所以結(jié)果為:

image.png

如果遇見得分一樣的呢?

class label pre
A 0 0.1
B 0 0.4
C 1 0.4
D 1 0.8

同樣本是4個(gè)樣本對灿渴,對于樣本對(C,B)其I值為0.5洛波。


image.png
from sklearn.metrics import roc_auc_score
def calcAUC(labels, probs):
    N = 0
    P = 0
    neg_prob = []
    pos_prob = []
    for _,i in enumerate(labels):
        if (i == 1):
            P += 1
            pos_prob.append(probs[_])
        else:
            N += 1
            neg_prob.append(probs[_])
    number = 0
    for pos in pos_prob:
        for neg in neg_prob:
            if (pos > neg):
                number += 1
            elif (pos == neg):
                number += 0.5
    return number / (N * P)

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])
print('auc=',calcAUC(y,pred))
print('roc_auc=',roc_auc_score(y,pred))
auc= 0.5666666666666667
roc_auc= 0.5666666666666667

上面的計(jì)算方法用了2個(gè)循環(huán),時(shí)間復(fù)雜度高骚露,因此我們對其進(jìn)行如下優(yōu)化蹬挤。

首先按照預(yù)測的概率從小到高排列:

class label pre
A 0 0.1
C 1 0.3
B 0 0.4
D 1 0.8

顯然比C小的就是A
比D小的就是A,B
C的位置是2 D的位置是4
2+4 =A+C+A+B+C+D -----------(1)
而我們的目標(biāo)是:
1+2=A+A+B -----------(2)
因此需要將(1)式減去 C+C+D
顯然就是將正樣本進(jìn)行排列然后用等差數(shù)列求和公式即:


image.png

所以最后的求解公式為:


image.png

如果出現(xiàn)預(yù)測相同的情況

class label pre rangk
A 0 0.1 1
B 1 0.5 2
C 1 0.5 3
D 0 0.5 4
E 0 0.5 5
F 1 0.8 6
G 1 0.9 7

那就是正負(fù)樣本平分位置即可


image.png

用python實(shí)現(xiàn):

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


def auc_calculate(labels,preds,n_bins=100):
    postive_len = sum(labels)   #正樣本數(shù)量(因?yàn)檎龢颖径际?)
    negative_len = len(labels) - postive_len #負(fù)樣本數(shù)量
    total_case = postive_len * negative_len #正負(fù)樣本對
    pos_histogram = [0 for _ in range(n_bins)] 
    neg_histogram = [0 for _ in range(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_histogram[nth_bin] += 1
        else:
            neg_histogram[nth_bin] += 1
    accumulated_neg = 0
    satisfied_pair = 0
    for i in range(n_bins):
        satisfied_pair += (pos_histogram[i]*accumulated_neg + pos_histogram[i]*neg_histogram[i]*0.5)
        accumulated_neg += neg_histogram[i]
    return satisfied_pair / 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("驗(yàn)證:",auc_calculate(y,pred))

sklearn: 0.5666666666666667
驗(yàn)證: 0.5666666666666667

參考:
AUC計(jì)算的兩種實(shí)現(xiàn)方式以及python代碼
AUC詳解與python實(shí)現(xiàn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荸百,一起剝皮案震驚了整個(gè)濱河市闻伶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌够话,老刑警劉巖蓝翰,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異女嘲,居然都是意外死亡畜份,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門欣尼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爆雹,“玉大人,你說我怎么就攤上這事愕鼓「铺” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵菇晃,是天一觀的道長册倒。 經(jīng)常有香客問我,道長磺送,這世上最難降的妖魔是什么驻子? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮估灿,結(jié)果婚禮上崇呵,老公的妹妹穿的比我還像新娘。我一直安慰自己馅袁,他們只是感情好域慷,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般犹褒。 火紅的嫁衣襯著肌膚如雪兄纺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天化漆,我揣著相機(jī)與錄音,去河邊找鬼钦奋。 笑死座云,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的付材。 我是一名探鬼主播朦拖,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼厌衔!你這毒婦竟也來了璧帝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤富寿,失蹤者是張志新(化名)和其女友劉穎睬隶,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體页徐,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡苏潜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了变勇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恤左。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖搀绣,靈堂內(nèi)的尸體忽然破棺而出飞袋,到底是詐尸還是另有隱情,我是刑警寧澤链患,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布巧鸭,位于F島的核電站,受9級(jí)特大地震影響锣险,放射性物質(zhì)發(fā)生泄漏蹄皱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一芯肤、第九天 我趴在偏房一處隱蔽的房頂上張望巷折。 院中可真熱鬧,春花似錦崖咨、人聲如沸锻拘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽署拟。三九已至婉宰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間推穷,已是汗流浹背心包。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留馒铃,地道東北人蟹腾。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像区宇,于是被迫代替她去往敵國和親娃殖。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容