機器學習中對於分類模型常用混淆矩陣來進行效果評價,混淆矩陣中存在多個評價指標,這些評價指標可以從不同角度來評價分類結果的優劣,以下內容通過簡單的理論概述和案例展示來詳細解釋分類模型中混淆矩陣的評價指標及其用途。
1、混淆矩陣的概念 2、衍生評價指標 3、ROC曲線、AUC指標 4、R&Python中混淆矩陣函數
1、混淆矩陣的基本概念
對於分類模型而言(這裏僅以最簡單的二分類爲例,假設只有0和1兩類),最終的判別結果無非就四種情況: 實際爲0被正確預測爲0,實際爲0被錯誤預測爲1,實際爲1被錯誤誤測爲0,實際爲1被正確預測爲1。
以上四類判別結果展示在混淆矩陣上是一個兩行兩列的交叉矩陣,行分別代表實際的正例和負例,列分別代表預測的正例和負例。
那麼在以上矩陣中:四個象限分別代表四種判別結果:
左上角被稱爲真陽性(True Positive,TP):樣本實際爲正(這裏的正負僅僅是相對意義上我們想要研究的類別)例,且模型預測結果爲正例; 右上角被稱爲假陰性(False Negative,FN):樣本實際爲正例,但模型預測爲負例; 左下角被稱爲假陽性(False Positive,FP):樣本實際類別爲負例,但模型預測爲正例; 右下角被稱爲真陰性(True Negative,TN):樣本實際類別爲負例,且模型預測爲負例。
混淆矩陣的四個象限有明顯的規律,左上角至右下角的對角線上是預測正確(以T開頭),另一條對角線則預測錯誤(以F開頭),左側上下象限是預測爲真的類別(以P結尾),右側上下象限爲預測錯誤的類別(以N結尾)。
這樣真個混淆矩陣看起來就清洗多了,圍繞着混淆矩陣有幾個比較重要的指標需要掌握。
2、評價指標:
2.1 分類準確率(即所有分類中被正確分類的比例,也稱識別率)
(TP + TN)/(TP + TN + FN + FN)
2.2 召回率-Recall(也稱靈敏率、真正例識別率)
召回率的含義是指:正確識別的正例個數在實際爲正例的樣本數中的佔比 Recall = TP/(TP + FN)
2.3 精確率
精確率的含義是指:預測爲真的正樣本佔所有預測爲正樣本的比例。
Precision = TP/(TP + FP)
2.4 F度量(F1分數或者F分數)
F度量是是基於以上度量(精確率和召回率)衍生的計算指標,具體計算公式如下:
F度量 = 2PrecisionRecall/(Precision + Recall)
3、ROC曲線、AUC指標
ROC的全名叫做Receiver Operating Characteristic,主要通過平面座標系上的曲線來衡量分類模型結果好壞——ROC curve。
橫座標是false positive rate(FPR), 縱座標是true positive rate(TPR)。
以上縱座標的TPR即是上述的指標召回率,FPR則指代負樣本中的錯判率(假警報率),FPR = FP/(FP + TN) 。
典型的ROC曲線是一個位於座標點(0,0)和(1,1)對角線上方的曲線,因爲對角線代表着隨機分類器的分類效果。
ROC曲線只能通過圖形來進行視覺判別,取法具體量化分類器的性能,於是AUC便出現了,它用來表示ROC曲線下的三角形面積大小,通常,AUC的值介於0.5到1.0之間,較大的AUC代表了較好的performance。
4、R&Python中的混淆矩陣及指標計算
4.1 R語言中的混淆矩陣
這裏使用iris數據集來實現簡單的knn分類,並使用R中的混淆矩陣來對其進行性能解讀。
library("magrittr") library("dplyr") library("class") library("caret") library("scales") library("gmodels")
爲了方便演示二分類的混淆矩陣結果,這裏我刪掉一類,並將字符型的類別進行數字編碼。
#處理分類編碼 data(iris) iris$Species <- as.character(iris$Species) iris <- iris %>% filter(Species != "setosa") iris$Species <- factor(iris$Species) #特徵標準化 iris_data <- iris iris_data[,1:4] = apply(iris_data[,1:4],2,rescale,to = c(0,1)) #劃分數據集 split1 <- createDataPartition(y=iris_data$Species,p=0.7,list = FALSE) train_data <- iris_data[split1,1:4] train_label<- iris_data[split1,5] test_data <- iris_data[-split1,1:4] test_label <- iris_data[-split1,5] #訓練模型並輸出預測值 test_pre_labels <- knn(train_data,test_data,train_label,k =5,prob=TRUE) #混淆矩陣輸出: confusionMatrix(test_label,test_pre_labels,dnn = c("Prediction","Actutal")) table(test_label,test_pre_labels,dnn = c("Actutal","Prediction"))
caret包中的confusionMatrix函數可以非常快速的輸出分類器分類結果的混淆矩陣。混淆矩陣中除了輸出判別 矩陣之外,還給出了常用的判別指標。
TP = 12 FN = 0 FP = 3 TN = 15 Accuracy = (TN + TP)/(TN+TP+FN+FP) (12+15)/(12+3+0+15) = 0.9 Recall = TP/(TP + FN) #對應混洗矩陣輸出中的Sensitivity指標,也稱靈敏性 12/(12+0) = 1 Precision = TP/(TP + FP) #對應混洗矩陣輸出中的Pos Pred Value 12/(12+3) = 0.8 F1 = 2*Recall*Precision/(Recall + Precisio) 2*1*0.8/(1+0.8) = 0.8888889 library("pROC") 測數據 date_roc <- roc(test_label,ordered(test_pre_labels)) plot(date_roc, print.auc = TRUE, auc.polygon = TRUE, legacy.axes = TRUE, grid = c(0.1, 0.2), grid.col = c("green", "red"), max.auc.polygon = TRUE, auc.polygon.col = "skyblue", print.thres = TRUE, xlab = "特異度", ylab = "靈敏度", main = "ROC曲線")
可以從ROC曲線圖表輸出上看到以上KNN分類結果的AUC值爲0.9
5.2 Python中的混淆矩陣與衍生指標計算
from sklearn.preprocessing import Imputer,LabelEncoder,OneHotEncoder from sklearn import preprocessing from sklearn.model_selection import train_test_split from sklearn.datasets import load_iris from sklearn import neighbors from sklearn import metrics import matplotlib.pyplot as plt import pandas as pd import numpy as np #導入數據 iris = load_iris() data = iris['data'] iris_data = pd.DataFrame( data = data, columns = ['sepal_length','sepal_width','petal_length','petal_width'] ) iris_data["Species"] = iris[ 'target'] iris_data = iris_data.loc[iris_data['Species'] != 0,:] #數據集分割 x,y = iris_data.iloc[:,0:-1],iris_data.iloc[:,-1] train_data,test_data,train_target,test_target = train_test_split(x,y,test_size = 0.3,stratify = y) #特徵標準化 min_max_scaler = preprocessing.MinMaxScaler() #實例化0-1標準化方法 X_train = min_max_scaler.fit_transform(train_data.values) X_test = min_max_scaler.transform(test_data.values) #模型擬合 model_KNN = neighbors.KNeighborsClassifier() model_KNN.fit(X_train,train_target) #預測結果 Pre_label = model_KNN.predict(X_test) #指標計算 1、混淆矩陣輸出 metrics.confusion_matrix(test_target,Pre_label) TP = 14 FN = 1 FP = 2 TN = 13 2、分類準確率計算 metrics.accuracy_score(test_target,Pre_label) Accuracy = (TP + TN)/(TP + TN + FN + FP) (14+13)/(14+1+2+13) = 0.9 3、召回率(Recall、或稱靈敏性-Sensitivity) metrics.recall_score(test_target,Pre_label) Recall = TP/(TP + FN) 14/(14+1) = 0.9333333333333333 4、精確度(Precision) metrics.precision_score(test_target,Pre_label) Precision = TP/(TP + FP) 14/(14 + 2) = 0.875 5、F1度量 metrics.f1_score(test_target,Pre_label) (2*Precision*Recall) / (Precision+Recall) = 0.9032258064516129 6、ROC曲線與AUC值 fpr,tpr,thresholds = metrics.roc_curve(np.array(test_target),Pre_label,pos_label=2) plt.plot(fpr, tpr) plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.0]) plt.title('ROC curve for diabetes classifier') plt.xlabel('False Positive Rate (1 - Specificity)') plt.ylabel('True Positive Rate (Sensitivity)') plt.grid(True) metrics.roc_auc_score(test_target.values -1,Pre_label) 0.9
AUC指標用來評估分類器性能,可以兼顧樣本中類別不平衡的情況,這一點上要比分類準確率更加具有參考價值; 整體而言,混淆矩陣給我們呈現了一個清晰可見的分類模型效果評估工具,而基於混淆矩陣的評估指標可以從不同側面來評價分類器性性能,至於在實際操作中使用什麼樣的評估指標來進行評價,還要視具體的分析目標而定。
比如在文檔檢索方面,如果想要儘可能的提高檢索到的文檔中實際有價值的文檔,就應該着手提高精確度,否則會面臨大量冗餘信息;在右鍵攔截領域,爲了防止誤傷重要右鍵,則需要適當提高召回率(查全率),否則會導致重要信息被遺漏。