假設如今有一個二分類問題,先引入兩個概念:post
再假設樣本數爲6,如今有一個分類器1,它對樣本的分類結果以下表(按預測值從大到小排序)性能
標籤 | 預測值 |
---|---|
1 | 0.9 |
1 | 0.8 |
1 | 0.7 |
0 | 0.3 |
0 | 0.2 |
0 | 0.1 |
ROC曲線的橫軸爲假正例率,縱軸爲真正例率,範圍都是[0,1],如今咱們開始畫圖——根據從大到小遍歷預測值,把當前的預測值當作閾值,計算FPR和TPR。spa
step1:選擇閾值最大,即爲1,正例中和反例中都沒有預測值大於等於1的,因此FPR=TPR=0。code
step2:根據上表,選擇閾值爲0.9,正例中有1個樣本的預測值大於等於1,反例中有0個,因此,TPR=1/3,FPR=0。排序
step3:根據上表,選擇閾值爲0.8,正例中有2個樣本的預測值大於等於1,反例中有0個,因此,TPR=2/3,FPR=0。rem
step4:根據上表,選擇閾值爲0.7,正例中有3個樣本的預測值大於等於1,反例中有0個,因此,TPR=1,FPR=0。數學
step5:根據上表,選擇閾值爲0.3,正例中有3個樣本的預測值大於等於1,反例中有1個,因此,TPR=1,FPR=1/3。it
step6:根據上表,選擇閾值爲0.2,正例中有3個樣本的預測值大於等於1,反例中有2個,因此,TPR=1,FPR=2/3。table
step7:根據上表,選擇閾值爲0.1,正例中有3個樣本的預測值大於等於1,反例中有3個,因此,TPR=1,FPR=1。class
綜上,咱們獲得下表
FPR | TPR |
---|---|
0 | 1/3 |
0 | 2/3 |
0 | 1 |
1/3 | 1 |
2/3 | 1 |
1 | 1 |
描點連線,畫出的圖是下面這樣什兒的
能夠看出這個分類器仍是很理想的。
假設如今又有一個分類器2,對一樣一組樣本,分類結果以下
標籤 | 預測值 |
---|---|
1 | 0.9 |
1 | 0.8 |
0 | 0.75 |
1 | 0.7 |
0 | 0.2 |
0 | 0.1 |
根據上面描述的方法,畫出ROC曲線以下
發現這個曲線的左上角比以前往右下角凹了一點。
emmmm,如今又來了一個分類器3,對一樣一組樣本,分類結果以下
標籤 | 預測值 |
---|---|
1 | 0.9 |
0 | 0.8 |
0 | 0.78 |
1 | 0.75 |
1 | 0.2 |
0 | 0.1 |
很少說,直接畫圖——
哎?這個曲線比以前更「凹」了。
實際上,不用畫出曲線,只是根據這3個分類器的分類結果,咱們也能大概能分析出它們的性能:分類器1>分類器2>分類器3。
對分類器1的預測結果來講,全部的正例的預測值都在1這一側,全部反例的預測值都在0那一側,只要閾值取得合適,即閾值落在(0.3,0.7)內均可以。
再看分類器2的預測結果,出現了對反例的預測值(0.75)大於對正例的預測值了(0.7),因此不能選擇一個合適的閾值把這兩類徹底分開,因此反映在圖上就是左上角凹了一點,但對大部分樣本仍是能夠正確分類的。
再看分類器3的預測結果,這種不穩定性就更明顯了,因此相比前兩個的ROC曲線,凹得就更多了。
從這個角度,也就不可貴出,ROC下面的面積越大,分類器越好的結論了。固然還有嚴格的數學角度的分析,感興趣的,瞭解一下。
下面附上畫圖用的matlab代碼
clear; clc; % 分類器1 % label = [1,1,1,0,0,0]; % predict = [0.9,0.8,0.7,0.3,0.2,0.1]; % 分類器2 % label = [1,1,0,1,0,0]; % predict = [0.9,0.8,0.75,0.7,0.2,0.1]; % 分類器3 label = [1,0,0,1,1,0]; predict = [0.9,0.8,0.78,0.75,0.2,0.1]; TPR=[]; FPR=[]; numPositive = size(find(label==1),2); numNegative = size(find(label==0),2); postive = predict(find(label==1)); negative = predict(find(label==0)); for i=1:size(label,2)+1 if i==1 cur = 1; else cur = predict(i-1); end TPR(i) = size(find(postive>=cur),2)/numPositive; FPR(i) = size(find(negative>=cur),2)/numNegative; end plot(FPR,TPR,'k*-') axis([0 1 0 1]); xlabel('FPR') ylabel('TPR')