sklearn的roc curve 函式分析

2021-08-15 18:03:01 字數 4303 閱讀 8929

在用sklearn的roc_curve()函式的時候,發現返回的結果和想象中不太一樣,理論上threshold應該取遍所有的y_score(即模型**值)。但是roc_curve()的結果只輸出了一部分的threhold。從原始碼找到了原因。

初始資料:

y_true = [0, 0, 1, 0, 0, 1, 0, 1, 0, 0]

y_score = [0.31689620142873609, 0.32367439192936548, 0.42600526758001989, 0.38769987193780364, 0.3667541015524296, 0.39760831479768338, 0.42017521636505745, 0.41936155918127238, 0.33803961944475219, 0.33998332945141224]

通過sklearn的roc_curve函式計算false positive rate和true positive rate以及對應的threshold:

fpr_skl, tpr_skl, thresholds_skl = roc_curve(y_true, y_score, drop_intermediate=false)
計算得到的值如下:

fpr_skl

[ 0.

0.14285714

0.14285714

0.14285714

0.28571429

0.42857143

0.57142857

0.71428571

0.85714286

1. ]

tpr_skl

[ 0.

0.14285714

0.14285714

0.14285714

0.28571429

0.42857143

0.57142857

0.71428571

0.85714286

1. ]

thresholds_skl

[ 0.42600527

0.42017522

0.41936156

0.39760831

0.38769987

0.3667541

0.33998333

0.33803962

0.32367439

0.3168962 ]

分析一下roc_curve()**,看看這三個值都是怎麼算出來的,其實就是常規auc的計算過程。

首先是_binary_clf_curve()函式:

fps, tps, thresholds = _binary_clf_curve(

y_true, y_score, pos_label=pos_label, sample_weight=sample_weight)

fps和tps就是混淆矩陣中的fp和tp的值;thresholds就是y_score逆序排列後的結果(由於保留的小數字數不同,所以表面上看上去不一樣,其實是一樣的)。在這個例子中,其值如下:

fps = [0, 1, 1, 1, 2, 3, 4, 5, 6, 7]

tps = [1, 1, 2, 3, 3, 3, 3, 3, 3, 3]

thresholds = [0.42600526758001989, 0.42017521636505745, 0.41936155918127238, 0.39760831479768338, 0.38769987193780364, 0.3667541015524296, 0.33998332945141224, 0.33803961944475219, 0.32367439192936548, 0.31689620142873609]

為了便於理解,這裡用更直觀的方式實現了fps和tps的計算:

for threshold in thresholds:

# 大於等於閾值為1, 否則為0

y_prob = [1

if i>=threshold else

0for i in y_score]

# 結果是否正確

result = [i==j for i,j in zip(y_true, y_prob)]

# 是否**為正類

positive = [i==1

for i in y_prob]

tp = [i and j for i,j in zip(result, positive)] # **為正類且**正確

fp = [(not i) and j for i,j in zip(result, positive)] # **為正類且**錯誤

print(tp.count(true), fp.count(true))

# 輸出01

1112

1323

3343

5363

73

通過fps和tps,就可以計算出相應的fpr和tpr,其中-1就是閾值取最小,也就是所有樣本都判斷為positive,相應地,fps[-1]就是負樣本總和,tpr[-1]就是正樣本總和。原始碼相應的計算**簡化後如下:

fpr = [i/fps[-1] for i in fps] # fps / fps[-1]

tpr = [i/tps[-1] for i in tps] # tps / tps[-1]

roc_curve()函式有drop_intermediate引數,相應的原始碼為:

if drop_intermediate and len(fps) > 2:

optimal_idxs = np.where(np.r_[true,

np.logical_or(np.diff(fps, 2),

np.diff(tps, 2)),

true])[0]

fps = fps[optimal_idxs]

tps = tps[optimal_idxs]

thresholds = thresholds[optimal_idxs]

在這個例子中,相應變數的值為:

# 取兩階差值

np.diff(fps, 2)

[-1010

0000]

np.diff(tps, 2)

[ 10 -100

000]# 取或

np.logical_or(np.diff(fps, 2), np.diff(tps, 2))

[ true, false, true, false, false, false, false, false]

# 在頭尾各加上乙個true

np.r_[true, np.logical_or(np.diff(fps, 2), np.diff(tps, 2)), true]

[ true, true, false, true, false, false, false, false, false, true]

# true所在的陣列下標

np.where(np.r_[true, np.logical_or(np.diff(fps, 2), np.diff(tps, 2)), true])[0]

[0, 1, 3, 9]

optimal_idxs實際上就是roc影象的拐點,對於畫圖而言,只需要拐點即可。將fps和tps想象為乙個人在圖上的位移,則一階差值即為「移動速度」,二階差值即為「加速度」。

「roc影象」如下:

因此,drop_intermediate引數實際上是對roc計算過程的優化,不影響roc影象。

sklearn學習 sklearn學習的相關資料

0 scikit learn官網 1 使用sklearn進行整合學習 理論 2 使用sklearn進行整合學習 實踐 3 sklearn學習筆記之開始 4 誰動了我的特徵?sklearn特徵轉換行為全記錄 5 使用sklearn優雅地進行資料探勘 備註 作者是個大神 6 sklearn多個例項 7 ...

sklearn的predict proba使用說明

發現個很有用的方法 predict proba 今天在做資料 的時候用到了,感覺很不錯,所以記錄分享一下,以後可能會經常用到。我的理解 predict proba不同於predict,它返回的 值為,獲得所有結果的概率。有多少個分類結果,每行就有多少個概率,以至於它對每個結果都有乙個可能,如0 1就...

sklearn初探(一) sklearn安裝

scikit learn 要求 警告 scikit learn 0.20是支援python 2.7和python 3.4的最後乙個版本。scikit learn現在需要python 3.5或更新版本。如果你已經有乙個合適的 numpy 和 scipy版本,安裝 scikit learn 最簡單的方法...