1. 程式人生 > 其它 >分類評價指標

分類評價指標

1.概念

  • 二分類:一個目標的標籤只有兩種之一(例如:0或1,對應的one-hot標籤為[1,0]或[0,1])。對於這種問題,一般可以採用softmax或者logistic迴歸來完成,分別採用cross-entropy和mse損失函式來進行網路訓練,分別輸出概率分佈和單個的sigmoid預測值(0,1)。
  • 多分類:一個目標的標籤是幾種之一(如:0,1,2…)

2.評價指標

① 準確率(accuracy)和錯誤率(error rate)

accuracy = (TP+TN)/ (P+N)或者accuracy = (TP+TN)/ (T+F)
error rate = (FP+FN) / (P+N)或者(FP+FN) / (T+F)
accuracy = 1 - error rate
可見 :準確率、錯誤率是對分類器在整體資料上的評價指標。

② 精確率(precision)

precision=TP /(TP+FP)
可見 :精確率是對分類器在預測為陽性的資料上的評價指標。

③ 召回率(recall)/真陽率(true positive rate)/靈敏度(sensitivity)

recall = TPR = sensitivity = TP/(TP+FN)
可見 :召回率/真陽率/靈敏度是對分類器在整個陽性資料上的評價指標。

④ F1-measure

F1-measure = 2 * (recall * precision / (recall + precision))
包含兩種:micro和macro(對於多類別分類問題, 注意 區別於多標籤分類問題)

  • micro
    計算出所有類別總的precision和recall,然後計算F1-measure
  • macro
    計算出每一個類的precison和recall後計算F1-measure,最後將F1-measure平均
    可見 :F1-measure是對兩個矛盾指標precision和recall的一種調和。

⑤ 假陽率(false positive rate)

FPR=FP / (FP+TN)
可見 :假陽率是對分類器在整個陰性資料上的評價指標,針對的是假陽。

⑥ 特異度(specificity)

specificity = 1- FPR
可見 :特異度是對分類器在整個陰性資料上的評價指標,針對的是真陰。

⑦ ROC曲線(receiver operation curve)和AUC(area under curve)

作用:靈敏度與特異度的綜合指標
橫座標:FPR/1-specificity
縱座標:TPR/sensitivity/recall
AUC是ROC右下角的面積,越大,表示分類器的效能越好
包含兩種:micro和macro(對於多類別分類問題, 注意 區別於多標籤分類問題)
假設一共有M個樣本,N個類別。預測出來的概率矩陣P(M,N),標籤矩陣L (M,N)

  • micro
    根據P和L中的每一列(對整個資料集而言),計算出各閾值下的TPR和FPR,總共可以得到N組資料,分別畫出N個ROC曲線,最後取平均
  • macro
    將P和L按行展開,然後轉置為兩列,最後畫出一個ROC曲線

⑧ PR曲線(precision recall curve)

橫軸:recall
縱軸:precision

  • 評判:
    • 直觀看,P-R包圍的面積越大越好,P=R的點越大越好;
    • 通過F1-measure來看

比較ROC和P-R : 當樣本中的正、負比例不平衡的時候,ROC曲線基本保持不變,而P-R曲線變化很大,原因如下:
當負樣本的比例增大時,在召回率一定的情況下,那麼表現較差的模型必然會召回更多的負樣本,TP降低,FP迅速增加(對於效能差的分類器而言),precision就會降低,所以P-R曲線包圍的面積會變小。

⑨ 混淆矩陣(confusion matrix)

行表示的是樣本中的一種真類別被預測的結果,列表示的是一種被預測的標籤所對應的真類別。

3. 程式碼

3.程式碼
注意 :以下的程式碼是合在一起寫的,有註釋。

from sklearn import datasets
import numpy as np
from sklearn.preprocessing import label_binarize
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, precision_score, accuracy_score,recall_score, f1_score,roc_auc_score, precision_recall_fscore_support, roc_curve, classification_report
import matplotlib.pyplot as plt

iris = datasets.load_iris()
x, y = iris.data, iris.target
print("label:", y)
n_class = len(set(iris.target))
y_one_hot = label_binarize(y, np.arange(n_class))

# alpha = np.logspace(-2, 2, 20)  #設定超引數範圍
# model = LogisticRegressionCV(Cs = alpha, cv = 3, penalty = 'l2')  #使用L2正則化
model = LogisticRegression()  # 內建了最大迭代次數了,可修改
model.fit(x, y)
y_score = model.predict(x)  # 輸出的是整數標籤
mean_accuracy = model.score(x, y)
print("mean_accuracy: ", mean_accuracy)
print("predict label:", y_score)
print(y_score==y)
print(y_score.shape)
y_score_pro = model.predict_proba(x)  # 輸出概率
print(y_score_pro)
print(y_score_pro.shape)
y_score_one_hot = label_binarize(y_score, np.arange(n_class))  # 這個函式的輸入必須是整數的標籤哦
print(y_score_one_hot.shape)

obj1 = confusion_matrix(y, y_score)  # 注意輸入必須是整數型的,shape=(n_samples, )
print('confusion_matrix\n', obj1)

print(y)
print('accuracy:{}'.format(accuracy_score(y, y_score)))  # 不存在average
print('precision:{}'.format(precision_score(y, y_score,average='micro')))
print('recall:{}'.format(recall_score(y, y_score,average='micro')))
print('f1-score:{}'.format(f1_score(y, y_score,average='micro')))
print('f1-score-for-each-class:{}'.format(precision_recall_fscore_support(y, y_score)))  # for macro
# print('AUC y_pred = one-hot:{}\n'.format(roc_auc_score(y_one_hot, y_score_one_hot,average='micro')))  # 對於multi-class輸入必須是proba,所以這種是錯誤的

# AUC值
auc = roc_auc_score(y_one_hot, y_score_pro,average='micro')  # 使用micro,會計算n_classes個roc曲線,再取平均
print("AUC y_pred = proba:", auc)
# 畫ROC曲線
print("one-hot label ravelled shape:", y_one_hot.ravel().shape)
fpr, tpr, thresholds = roc_curve(y_one_hot.ravel(),y_score_pro.ravel())   # ravel()表示平鋪開來,因為輸入的shape必須是(n_samples,)
print("threshold: ", thresholds)
plt.plot(fpr, tpr, linewidth = 2,label='AUC=%.3f' % auc)
plt.plot([0,1],[0,1], 'k--')  # 畫一條y=x的直線,線條的顏色和型別
plt.axis([0,1.0,0,1.0])  # 限制座標範圍
plt.xlabel('False Postivie Rate')
plt.ylabel('True Positive Rate')
plt.legend()
plt.show()

# p-r曲線針對的是二分類,這裡就不描述了

ans = classification_report(y, y_score,digits=5)  # 小數點後保留5位有效數字
print(ans)
足盡人事,但聽天命。