用機器學習去做分類問題的時候,會需要透過一些統計指標去輔助,才能正確地檢驗分類的結果,並快速地修正問題,達到更好的分類結果。近期案子上剛好在處理分類的問題,就順手把一些學過的評估指標做個整理,並搭配網站上的資源記錄成簡短的心得以供未來的自己參考。
1. 二分類模型的評估指標
混淆矩陣 Confusion Matrix
分類的結果可以用以下矩陣來表示,分為四種象限:
1 | 1. True Positive (TP): 實際上是正樣本且被預測為正樣本 |
1, 4點是我們希望的結果,2, 3點則是誤判的結果。
簡單理解:
第一個
True/False
代表預測是否正確第二個
Positive/Negative
則是代表預測的結果(答成哪一類)
準確度(Accuracy)
1 | 準確度(Accuracy) = (TP+TN)/(TP+FP+FN+TN) |
準確度是最常用的指標,但在某些情況下會失效。
例如: 某類數量佔很多的時候,直接把該類分到一邊,準確度就會大幅提高,但其實根本沒分到類,最常見的例子就是信用卡盜刷
準確度背後的意思是指,整體模型表現裡正確分類的比例是多少
精確度(Precision)與召回率(Recall)
從混淆矩陣繼續延伸可以得到以下兩個指標:
1 | 精確度(Precision) = TP/(TP+FP) |
所有被預測為正確的樣本中,有多少比例是實際正確的。
1 | 召回率(Recall) = TP/(TP+FN) |
所有實際正確的樣本中,有多少比例是被預測為正確的。
這兩個指標都只關注在實際的正樣本,不考慮TN的結果,因為通常TN會是答對的Null Hypothesis,白話而言就是無聊的正確結果。
總結,精確度希望模型能夠預測更準,召回率則是希望正確的樣本都能夠被判斷(偵測)出來。
在不同的情境下,precision和recall的使用時機就不同,端看關注的問題是屬於哪一面。
F1-Score
大多數情況下,我們不會偏廢precision或recall,而是希望兩者分配合理的權重,為了綜合考量precision與recall,所以產生了這個F1-Score的指標。
因為F1-Score的公式中,是固定TP,有不同的分母,符合調和數列的型態,所以公式型態也是採用調和平均。整理之後可得F1-Score長這樣:
F1-Score的值落在0~1之間。
而precision與recall之間的權重也可以透過一個beta值來調整,這就是F1 Measure。F1-Score只是F1 Measure的特例。
當beta=1就是F1-Score,代表precision與recall同等重要。
當beta=0就是precision,反之,當beta趨近於無限大,就是Recall
所以如果希望多看一點precision,就把beta調小一點,如果希望多看一點recall,就把beta調大一點。
ROC 曲線
ROC需要三個元素:
- TPR(Sensitivity) = TP/(TP+FN),等同recall
- FPR(Specificity) = FP/(FP+TN),所有負樣本被誤判為正樣比的比例
- 閥值
二分類的模型中,會設定一個閥值(threshold),當預測的結果大於此閥值,就被認定為正樣本,反之為負樣本。
透過不同的閥值、TPR與FPR,就可以畫出ROC曲線圖,底下的面積就是AUC,AUC愈大愈好。
2. 多分類模型的評估指標
跟二元分類一樣會有多元分類的混淆矩陣。
有三種指標可以觀察:
- 整體正確率or錯誤率
- 單一類別的正確率or錯誤率
- Cohen’s kappa coefficient (Kappa)
Cohen’s kappa coefficient (Kappa)
用來平衡類別之間正確性的一種指標,把數量極大的某個類別消除掉的指標。
白話來說,就是避免當單一類別的數量超大的時候,直接把分類的結果分為該類就會達到很高的正確率。
Kappa計算方式:
p0就是百分比混淆矩陣的對角線元素相加。
pc就是把把每類別做加總。(實際第i類別的總和乘上預測第i類別的總和)
舉例來說:
Kappa的值介於-1~1之間,值正的愈大,模型愈好。
3. 總結
4. 程式碼
[Confusion Matrix]
1 | # 基本 |
arr
[[0, 1, 0, 0],
[1, 1, 0, 0],
[0, 0, 1, 1],
[0, 0, 0, 1]]
熱圖:
[Accuracy]
1 | from sklearn.metrics import accuracy_score |
[Precision/Recall/F1-Score]
這裡Precision, Recall, F1-Score在python程式碼中有一個參數average
可以自由調整,有None
,binary
,micro
, macro
, weighted
五種可以選擇,預設是binary
,但是binary
是專屬於二分類使用,而micro
, macro
, weighted
則是適用於多分類。 None
則兩種時機皆可使用,它會回傳每個類別的指標。
在多分類的時候需要特別了解micro
,macro
,weighted
這三種概念才能知道在什麼情境下使用:
micro
: 讓所有類別的每個樣本都具有相同的權重,把所有樣本合在一起來計算指標macro
: 讓每個類別具有相同的權重,用算術平均數去計算每個類別的指標。weighted
: 由各類別的數量去計算加權值,解決macro
可能遇到的label數量不平衡的問題。
舉前一個例子來說,各個ptt版的預測分類可以由混淆矩陣得到下表:
TP | FP | FN | |
---|---|---|---|
0 政黑板 | 0 | 1 | 1 |
1 土木板 | 1 | 1 | 1 |
2 八卦板 | 1 | 0 | 1 |
3 表特板 | 1 | 1 | 0 |
此處以計算Precision為例,先計算各類別的Precision:
Precision = TP/(TP+FP)
P0 = 0/(0+1) = 0
P1 = 1/(1+1) = 0.5
P2 = 1/(1+0) = 1
P3 = 1/(1+1) = 0.5
這其實就是None
會回傳的值。
計算
micro
precision:把所有樣本考慮在一起來計算,所以回頭看 y_true, y_pred 的資料
y_true = [1,1,0,3,2,2]
y_pred = [0,1,1,3,3,2]全部樣本中有答對的有3筆,剩下3筆是沒答對的,所以 micro precision = 3/(3+3) = 0.5
計算
macro
precision:用算術平均數來計算,所以 macro precision = (P0+P1+P2+P3)/4 = 0.5
計算
weighted
precision:先計算每個類別佔所有樣本中的比例,再分別加權計算,所以 weighted precision = (1/6)xP0 + (1/3)xP1 + (1/3)xP2 + (1/6)xP3 = 0.5833
同理,Recall, F1-Score也可以這樣計算
最後,整理一下
micro
,macro
這兩個指標帶給我們的資訊:當各類別數量相差甚大的時候:
- 想要讓weight集中偏向於樣本數量大者,用
micro
- 想要讓weight集中偏向於樣本數量小者,用
macro
同樣地,我們可以透過這兩個指標回頭檢查類別
- 當
micro
<<macro
,回頭檢查樣本數量大的類別 - 當
macro
<<micro
,回頭檢查樣本數量小的類別
- 想要讓weight集中偏向於樣本數量大者,用
以下是程式碼
1 | from sklearn.metrics import precision_score |