2017年10月13日 星期五

機器學習_ML_模型指標_roc_curve

機器學習_ML_模型指標_roc_curve

原文連結
適用性:Classification metrics

各種的數值計算都跟上面這張圖有關。(取自(維基百科))
this implementation is restricted to the binary classification task.
限於二類lable使用(0,1)or(1,-1),或是透過pos_label來設置。
一般我們在選擇分類模型的時候會使用ROC圖來觀察模型的效能,即透過真陽率(TPR)與假陽率(FPR)來做選擇,所以這是一個對P的概率估計。
以完美來說,當然是希望真陽率為1,而假陽為0。
FPR=FP/N
TPR=TP/P
N=(FP+TN)
P=(FN+TP)

IMPORT

from sklearn.metrics import roc_curve

參數

y_true

shape=n_samples
實際的標籤

y_score

shape=n_samples
屬真的機率

pos_label

default None {int str}
當設置了以後,以設置的為真,另一為假。
假如你的label是2,3
而設置了pos_label=3,則表示3為真,而2為假

sample_weight

權重

drop_intermediate

default True

屬性

fpr

假陽率

tpr

真陽率

thresholds

閥值

範例

import numpy as np
from sklearn.metrics import roc_curve
y = np.array([1, 1, 2, 2])
scores = np.array([0.1, 0.4, 0.35, 0.8])
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)
fpr
tpr
thresholds
結果
>>> fpr
array([ 0. ,  0.5,  0.5,  1. ])
>>> tpr
array([ 0.5,  0.5,  1. ,  1. ])
>>> thresholds
array([ 0.8 ,  0.4 ,  0.35,  0.1 ])

範例說明

這邊說明上會有些許的複雜,但是我盡可能的白話文些。
roc的計算,會以真的機率(即score的設置)從大到小排序當做閥值(thresholds)。
此例來看,在計算時的排序會是如下
y score
2 0.8
1 0.4
2 0.35
1 0.1
這時候會發現,此排序與上面屬性排序相同。
接著,從第一個閥值開始,閥值以上即為真(此例為2)
故第一輪的時候為
yt=[2,1,2,1]
yp=[2,1,1,1]  #  閥值以上為真,故僅第一個為真
此時透過混洧矩陣來查看
tn, fp, fn, tp =confusion_matrix(yt,yp).ravel()
>>> tn
2
>>> fp
0
>>> fn
1
>>> tp
1
假陽率:FPR=FP/N = 0/2 = 0
真陽率:TPR=TP/P = 1/2 = 0.5
N=(FP+TN)
P=(FN+TP)
即屬性上tpr與fpr的數值。
依此邏輯計算四個閥值產生的fpr與tpr,
接著,再依序將這些點繪製於圖面上(x:fpr, y:tpr),即為著名的roc曲線!

圖面繪製

為什麼要用roc曲線呢?
因為roc曲線有個特性,當測試資料的真假樣本分佈變化的時候,roc曲線依然不變!
從roc曲線我們可以看的到整個模型效能。
一般來說,也會做一條對角線來做判斷(稱之為隨機機率),只要線落於對角線之外即代表該模型效能不佳。(比隨便亂猜還不如了)
搭配多折(StratifiedKFold)效果更好!
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve
import numpy as np

y = np.array([1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2])
scores = np.linspace(0,0.9,20)  #  產生一個0~0.9的1x20向量
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)
plt.plot(fpr,tpr,lw=1,label='roc')
plt.plot([0,0,1],[0,1,1],label='perfect', linestyle=':')
plt.plot([0,1],[0,1],label='judge', linestyle='--'])
plt.legend()
plt.show()

一般來說,數值愈多所產生的roc曲線圖會愈平滑!
改一下!
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve
import numpy as np

y = np.random.randint(1,3,500)  #  亂數產生500個1跟2
scores = np.linspace(0,0.9,500)  #  產生一個0~0.9的1x500向量
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)
plt.plot(fpr,tpr,lw=1,label='roc')
plt.plot([0,0,1],[0,1,1],label='perfect', linestyle=':')
plt.plot([0,1],[0,1],label='judge', linestyle='--'])
plt.legend()
plt.show()

沒有留言:

張貼留言