【火爐煉AI】機器學習011-分類模型的評估:準確率,精確率,召回率,F1值

【火爐煉AI】機器學習011-分類模型的評估:準確率,精確率,召回率,F1值

(本文所使用的Python庫和版本號: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )git

在前面的(【火爐煉AI】機器學習004-嶺迴歸器的構建和模型評估)中,講解了迴歸模型的評估方法,主要有均方偏差MSE, 解釋方差分,R方得分等指標。github

一樣的,對於分類模型,也有不少評估指標來判斷該分類模型是否達到咱們的要求,這幾個評估指標主要是指:準確率(accuracy),精確率(precision),召回率(recall),F1值(F1 measure)。算法


1. 指標的基本概念和計算方法

1.1 準確率(Accuracy)

準確率的定義是:對於給定的測試集,分類模型正確分類的樣本數與總樣本數之比。舉個例子來說,有一個簡單的二分類模型(暫時叫作Classifier_A),專門用於分類蘋果和梨,在某個測試集中,有30個蘋果+70個梨,這個二分類模型在對這個測試集進行分類的時候,得出該數據集有40個蘋果(包括正確分類的25個蘋果和錯誤分類的15個梨)和60個梨(包括正確分類的55個梨和錯誤分類的5個蘋果)。畫成矩陣圖爲:dom

從圖中能夠看出,行表示該測試集中實際的類別,好比蘋果類一共有25+5=30個,梨類有15+55=70個。其中被分類模型正確分類的是該表格的對角線所在的數字。在sklearn中,這樣一個表格被命名爲混淆矩陣(Confusion Matrix),因此,按照準確率的定義,能夠計算出該分類模型在測試集上的準確率爲:機器學習

即,該分類模型在測試集上的準確率爲80%。函數

可是,準確率指標並不老是可以評估一個模型的好壞,好比對於下面的狀況,假若有一個數據集,含有98個蘋果,2個梨,而分類器(暫時叫作Classifier_B)是一個不好勁的分類器,它把數據集的全部樣本都劃分爲蘋果,也就是無論輸入什麼樣的樣本,該模型都認爲該樣本是蘋果。那麼這個表格會是什麼樣的了?post

則該模型的準確率爲98%,由於它正確地識別出來了測試集中的98個蘋果,只是錯誤的把2個梨也當作蘋果,因此按照準確率的計算公式,該模型有高達98%的準確率。性能

但是,這樣的模型有意義嗎?一個把全部樣本都預測爲蘋果的模型,反而獲得了很是高的準確率,那麼問題出在哪兒了?只能說準確率不可信。特別是對於這種樣品數量誤差比較大的問題,準確率的「準確度」會極大的降低。因此,這時就須要引入其餘評估指標評價模型的好壞了。學習

1.2 精確率(Precision)

精確率的定義是:對於給定測試集的某一個類別,分類模型預測正確的比例,或者說:分類模型預測的正樣本中有多少是真正的正樣本,其計算公式是:測試

因此,根據定義,精確率要區分不一樣的類別,好比上面咱們討論有兩個類別,因此要分類來計算各自的精確率。對於上面提到的Classifier_A和Classifier_B分類模型,咱們能夠分別計算出其精確率:

在不少文章中,都講到把某一個類別當作正類(Positive),把其餘類別當作負類(Negative),而後只關注正類的精確率。可是,有的時候咱們不知道哪個類做爲正類更合適,好比此處的二分類問題,咱們能夠把蘋果當作正類,也能夠把梨當作正類,二者計算出來的精確率明顯是不同的。

1.3 召回率(Recall)

召回率的定義爲:對於給定測試集的某一個類別,樣本中的正類有多少被分類模型預測正確,其計算公式爲:

一樣的,召回率也要考慮某一個類別,好比,下面咱們將蘋果做爲正類,在Classifier_A模型下獲得的表格爲:

若是咱們將梨做爲正類,在Classifier_A模型下獲得的表格爲:

一樣的,能夠計算出上面兩個模型對給定測試集的召回率,以下表所示:

1.4 F1值(F1-Measure)

在理想狀況下,咱們但願模型的精確率越高越好,同時召回率也越高越高,可是,現實狀況每每事與願違,在現實狀況下,精確率和召回率像是坐在蹺蹺板上同樣,每每出現一個值升高,另外一個值下降,那麼,有沒有一個指標來綜合考慮精確率和召回率了,這個指標就是F值。F值的計算公式爲:

式中:P: Precision, R: Recall, a:權重因子。

當a=1時,F值即是F1值,表明精確率和召回率的權重是同樣的,是最經常使用的一種評價指標。F1的計算公式爲:

因此根據上面的精確率和召回率,能夠輕鬆的計算出這兩個模型的F1值:


2. 用sklearn計算精確率,召回率,F1值

上面第一部分,咱們都是手動計算出每種分類模型的各類評價指標,可是上帝告訴咱們,他已經幫咱們造好了輪子,咱們只須要直接調用便可。廢話少說,直接把計算這些評價指標的代碼貼過來:

2.1 用sklearn計算分類結果的混淆矩陣

# 假若有一個模型在測試集上獲得的預測結果爲:
y_true = [1, 0, 0, 2, 1, 0, 3, 3, 3] # 實際的類別
y_pred = [1, 1, 0, 2, 1, 0, 1, 3, 3] # 模型預測的類別

# 使用sklearn 模塊計算混淆矩陣
from sklearn.metrics import confusion_matrix
confusion_mat = confusion_matrix(y_true, y_pred)
print(confusion_mat) #看看混淆矩陣長啥樣
複製代碼

-------------------------------------輸---------出--------------------------------

[[2 1 0 0] [0 2 0 0] [0 0 1 0] [0 1 0 2]]

--------------------------------------------完-------------------------------------

其實這個矩陣的產生過程很簡單,好比實際類別是3(y_true=3)一共有三個樣本,其中兩個預測正確,一個預測錯誤成1,結果如表格所示:

2.2 混淆矩陣可視化

上面雖然把混淆矩陣打印出來了,可是結果很難直接觀察對比,下面將混淆矩陣可視化爲圖表,便於觀察。

def plot_confusion_matrix(confusion_mat):
    '''將混淆矩陣畫圖並顯示出來'''
    plt.imshow(confusion_mat, interpolation='nearest', cmap=plt.cm.gray)
    plt.title('Confusion matrix')
    plt.colorbar()
    tick_marks = np.arange(confusion_mat.shape[0])
    plt.xticks(tick_marks, tick_marks)
    plt.yticks(tick_marks, tick_marks)
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.show()

plot_confusion_matrix(confusion_mat)
複製代碼

混淆矩陣結果圖

2.3 打印模型的性能報告

Sklearn模塊中已經有成熟的對於模型評估的性能報告,裏面已經集成了分類模型的精確率,召回率和F1值信息,能夠說,是咱們分析模型的必備良器。

# 打印該模型的性能報告
# 直接使用sklearn打印精度,召回率和F1值
from sklearn.metrics import classification_report
target_names = ['Class-0', 'Class-1', 'Class-2', 'Class-3']
print(classification_report(y_true, y_pred, target_names=target_names))
複製代碼

-------------------------------------輸---------出--------------------------------

precision recall f1-score support

Class-0 1.00 0.67 0.80 3 Class-1 0.50 1.00 0.67 2 Class-2 1.00 1.00 1.00 1 Class-3 1.00 0.67 0.80 3 avg / total 0.89 0.78 0.79 9

--------------------------------------------完-------------------------------------

這個性能報告表中的評估指標的計算方法如前面第一節講述的,好比對於Precision,對於Class_1, Precision=TP/(TP+FP)=2/(2+1+0+1)=0.50,而對於Class_2: Precision=1/(1+0+0+0)=1.0.

對於Recall的計算方法,好比,對於Class_0=TP/(TP+FN)=2/(2+1+0+0)=0.67.因此能夠看出,Precision的算法是在混淆矩陣的縱向上運算,而Recall的算法是在混淆矩陣的橫向上運算。

F1-score的計算即是直接套用公式便可。後面的support是真實的各個類別的樣本數量。

########################小**********結###############################

1,sklearn中已經有成熟的方法能夠直接計算混淆矩陣和打印性能報告,這些函數對於模型的評估很是有幫助。

2,精確率,召回率,F1值的計算其實很簡單,只要弄明白各自對應的公式,弄明白公式所表明的具體含義便可。

#################################################################


3. 評估樸素貝葉斯多分類模型

在文章【火爐煉AI】機器學習010-用樸素貝葉斯分類器解決多分類問題中咱們使用了高斯樸素貝葉斯分類器構建了一個多分類模型,將該數據集成功分紅了四個類別,貌似結果很不錯,但是該文章沒有提升用能夠量化的性能指標來評估該分類模型的好壞。此處咱們能夠用上面講到的各類評價指標來評估該分類模型。

3.1 用交叉驗證檢驗模型的準確性

先加載數據集,而後劃分爲train set 和testset。構建樸素貝葉斯分類模型,用trainset進行訓練,而後用sklearn中的cross_val_score來輸出該分類模型在test set上的總體表現,代碼以下:

# 評估樸素貝葉斯多分類模型
# 1, 準備數據集
data_path='D:\PyProjects\DataSet/NaiveBayers/data_multivar.txt'
df=pd.read_csv(data_path,header=None)
dataset_X,dataset_y=df.iloc[:,:-1],df.iloc[:,-1]
dataset_X=dataset_X.values
dataset_y=dataset_y.values
# 將整個數據集劃分爲train set和test set
from sklearn.cross_validation import train_test_split
train_X, test_X, train_y, test_y=train_test_split(dataset_X,dataset_y,test_size=0.25,random_state=42)

# 構建樸素貝葉斯分類模型
from sklearn.naive_bayes import GaussianNB
gaussianNB_new=GaussianNB()
gaussianNB_new.fit(train_X,train_y)

# 2 用交叉驗證來檢驗模型的準確性,只是在test set上驗證準確性
from sklearn.cross_validation import cross_val_score
num_validations=5
accuracy=cross_val_score(gaussianNB_new,test_X,test_y,
                         scoring='accuracy',cv=num_validations)
print('準確率:{:.2f}%'.format(accuracy.mean()*100))
precision=cross_val_score(gaussianNB_new,test_X,test_y,
                         scoring='precision_weighted',cv=num_validations)
print('精確度:{:.2f}%'.format(precision.mean()*100))
recall=cross_val_score(gaussianNB_new,test_X,test_y,
                         scoring='recall_weighted',cv=num_validations)
print('召回率:{:.2f}%'.format(recall.mean()*100))
f1=cross_val_score(gaussianNB_new,test_X,test_y,
                         scoring='f1_weighted',cv=num_validations)
print('F1 值:{:.2f}%'.format(f1.mean()*100))
複製代碼

-------------------------------------輸---------出--------------------------------

準確率:99.00% 精確度:99.17% 召回率:99.00% F1 值:98.97%

--------------------------------------------完-------------------------------------

3.2 查看該模型在測試集上的混淆矩陣和性能報告

直接上代碼,沒什麼好講的。

# 使用sklearn 模塊計算混淆矩陣
y_pred=gaussianNB_new.predict(test_X)
confusion_mat = confusion_matrix(test_y, y_pred)
print(confusion_mat) #看看混淆矩陣長啥樣

print('*'*50)
# 打印該模型的性能報告
# 直接使用sklearn打印精度,召回率和F1值
target_names = ['Class-0', 'Class-1', 'Class-2', 'Class-3']
print(classification_report(test_y, y_pred, target_names=target_names))
複製代碼

-------------------------------------輸---------出--------------------------------

[[27 0 0 0] [ 0 18 0 0] [ 0 0 33 0] [ 0 0 0 22]]

precision recall f1-score support

Class-0 1.00 1.00 1.00 27 Class-1 1.00 1.00 1.00 18 Class-2 1.00 1.00 1.00 33 Class-3 1.00 1.00 1.00 22

avg / total 1.00 1.00 1.00 100

--------------------------------------------完-------------------------------------

########################小**********結###############################

1,對於樸素貝葉斯解決這裏的多分類問題,從模型檢測結果能夠看出,該分類器能夠很好地將這個數據集的四個類別區分開來,獲得的準確率,精確率,召回率,F1值等都比較好。

2,該分類器在測試集上的混淆矩陣都只有TP,沒有FP或FN,代表該分類器能夠100%的將這測試集中的四個類別區分開來。

3,在交叉驗證時,獲得的結果並非100%,而是99%以上,緣由頗有多是交叉驗證是採用多步驗證來計算這些指標,評估獲得的結果可能更可靠一些。

#################################################################


注:本部分代碼已經所有上傳到(個人github)上,歡迎下載。

參考資料:

1, Python機器學習經典實例,Prateek Joshi著,陶俊傑,陳小莉譯

相關文章
相關標籤/搜索