當我們在進行監督式機器學習 (supervised learning) 的分類 (classification)分析後,我們會透過混淆矩陣 (confusion matrix) 來檢驗這個模型的好壞。
本文除了會教大家在 Python 當中使用套件來產生混淆矩陣以及整個模型預測後的分析報告外,也會透過圖表的方式說明混淆矩陣當中,所有數字的意思,以及他們數值背後所代表的意涵,讓大家在訓練好一個分類模型後,能有所依據來檢驗模型準確度的好壞。
使用 Python 產生混淆矩陣
from sklearn.metrics import confusion_matrix
cm=confusion_matrix(y_test,y_pred)
cm
透過上述的程式碼可以產生該模型預測的混淆矩陣。
- y_test (ground truth) 是資料當中測試資料的目標陣列
- y_pred (model prediction) 是模型根據X_test 去進行預測後的結果
也就是說 y_test 是真實情況的標籤陣列,而y_pred 則是模型預測出來的標籤陣列,而混淆矩陣就是根據這兩者產生的矩陣。
查看y_test當中的標籤個數
y_test.value_counts()
上述程式碼可以看出 y_test 當中 class_0 與class_1 的個數分別為 1692 與 163 個,本例子假設 class_0 為正例,因為其例子較多,class_1 為負例,方便後面進行說明。
將混淆矩陣畫出,加以解釋
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(15,8))
sns.heatmap(cm,square=True,annot=True,fmt='d',linecolor='white',cmap='RdBu',linewidths=1.5,cbar=False)
plt.xlabel('Pred',fontsize=20)
plt.ylabel('True',fontsize=20)
plt.show()
從上述程式碼我們得出這張圖,我們可以清楚的將混淆矩陣表達,先說明本文章使用的例子,其 Y 的結果就是 class_0 (正例) 跟 class_1(負例)兩個分類,真實情況下為 class_0 的資料有 1692 筆 (1684+8), class_1 的資料有 163 筆 (29+134)。
在混淆矩陣當中有四個方格,四個方格代表不同的意思
四個方格
- (1) TP (True Postitive): 真實情況為class_0,預測也為class_0的個數有1684個
- (2) FN (False Negative): 真實情況為class_0,預測為class_1的個數有8個
- (3) FP (False Postitive): 真實情況為class_1,預測為class_0的數有29個
- (4) TN (True Negative): 真實情況為class_1,預測為class_1的個數有134個
- FP (又稱為偽陽性)就是統計學上的型一錯誤 (Type I Error)
- FN (又稱為偽陰性)就是統計學上的型二錯誤 (Type II Error)
- 小技巧: 上面竟然都說是錯誤了,當然都是 F 開頭
常用的指標
- (1) Accuracy(準確率)
- $$\frac{TP+TN}{TP+TN+FP+FN} = \frac{1684 + 134}{1855} = 0.98$$
- 準確率就是當他是 class_0(正例) 且預測為class_0(正例) 或是 class_1(負例) 且預測也為class_1(負例) 這兩種情況下都算是準確,因此根據上述公式即可算出準確率。
- 簡言之,準確率就是所有預測正確 (分子都是以T開頭) 的比例
- (2) Precision(精確率):
- $$\frac{TP}{TP + FP} = \frac{1684}{1684 + 29} = 0.98$$
- 精確率的意思是在預測出是class_0(正例)的情況下,真實情況也為class_0(正例)的比率
- 精確率就是所有預測正例 (分母都是以P結尾) 中,真實也是正例的比率
- (3) Recall(召回率):
- $$\frac{TP}{TP+FN} = \frac{1684}{1684+8} =0.99$$
- 精確率的意思是真實情況為 class_0 (正例) 的情況下,預測是 class_0 (正例) 的比率
- 精確率就是所有正例中,預測也為正例的比率
- (4) F1 Score:
- $$F1=\frac{2}{\frac{1}{Precision} + \frac{1}{Recall}} = \frac{2}{\frac{1}{0.98} + \frac{1}{0.99}} = 0.98$$
直接產出所有數值的報告
from sklearn.metrics import classification_report
print(classification_report(y_test,y_pred))
透過這個方法就可以省去所有的計算也不會怕理解錯誤算錯公式,我們可以看0.0那行的數值跟我們上述算出的一樣,因此也可以證明我們上述的理解是正確的,大家可以試著算出1.0那行的數值,當算那行數值時,則要反過來將class_1視為正例。
後記
說明混淆矩陣的文章很多,但有時候大家會覺得複雜,怎麼每篇解釋的都不太一樣,其問題是每位作者的預測與真實數據的講解表格位置不同,或是大家用的正例與反例不同,因此才會產生每篇都不一樣的錯覺,我覺得如果只是要解釋模型的各項數值,那可以直接用最後一個套件就能一目瞭然,然而如果想要完整了解每個數值的意義,不妨可以試著理解混淆矩陣的內容,謝謝大家,感謝觀閱。