可能是最全的機器學習模型評估指標總結

目錄:

符號定義:

yy:真實值,y^\hat{y}:預測值,nn:樣本數

指示函數:
1(x)={1x=true0x=false1(x)= \begin{cases} 1& \text{x=true}\\ 0& \text{x=false} \end{cases}

一、分類模型的度量

分類問題按照標籤的屬性不同一般可以分爲三種:

  1. binary classification 二分類:標籤只有兩個類別,如正類和負類。每個樣本有一個標籤。
  2. multiclass classification 多分類:標籤有多個類別,如小貓,小狗,小兔子。每個樣本有一個標籤。
  3. multilabel classification 多標籤分類:每個樣本有一個或多個標籤。

1.accuracy(準確率)

預測正確的樣本佔全部樣本的比例。公式爲:
accuracy(y,y^)=1ni=1n1(y^i=yi) \texttt{accuracy}(y, \hat{y}) = \frac{1}{n} \sum_{i=1}^{n} 1(\hat{y}_i = y_i)

簡單示例:

>>> from sklearn.metrics import accuracy_score
>>> y_true = [0, 0, 0, 0, 0, 0, 0, 1]
>>> y_pred = [0, 0, 0, 0, 0, 0, 1, 0]
>>> accuracy_score(y_true, y_pred)
0.75

2.balanced_accuracy (均衡準確率)

在實際場景中有時候數據集會不均衡,例如罕見疾病的預測。假設有一個包含 10000 個樣本的訓練集,其中正類的樣本有 9900 個,負類的樣本只有 100 個,如果用常規的 accuracy 度量模型的表現,可能會給出誇大的評估,表現爲模型在訓練集上正類負類的 accuracy 都很高,但是拿到測試集上做預測時,只有正類的 accuracy 很高,而負類的 accuracy 很低。所以引入 balanced_accuracy,它定義爲每個類別中預測正確的比例的算術平均值。公式爲:
balanced-accuracy(y,y^)=1ki=1kj=1mi1(yij^=yij) \texttt{balanced-accuracy}(y, \hat{y}) = \frac{1}{k} \sum_{i=1}^{k} \sum_{j=1}^{m_i}1(\hat{y_{ij}} = y_{ij})
其中kk爲類別數,mm爲每個類別中的樣本數。當數據集是均衡的時候,balanced_accuracy 和 accuracc 等價,計算的結果相同。

簡單示例:

>>> from sklearn.metrics import balanced_accuracy_score
>>> y_true = [0, 0, 0, 0, 0, 0, 0, 1]
>>> y_pred = [0, 0, 0, 0, 0, 0, 1, 0]
>>> balanced_accuracy_score(y_true, y_pred)
0.42857142857142855

3.brier_score (brier 分數,僅用於二分類任務)

衡量模型預測的類別的概率與真實值之間的誤差,它要求模型預測的結果是概率值,如 logistic 迴歸模型。如果把正類記作 1(也可以記作其它數值),負類記作 0,則預測的概率值介於 0 和 1 之間,越大則越可能爲正類,越小則越可能爲負類。brier 分數的公式爲:
brier-score(y,p)=1ni=1n(piyi)2 \texttt{brier-score}(y,p) = \frac{1}{n} \sum_{i=1}^{n}(p_i - y_i)^2
其中 pp 爲模型預測的概率值。

簡單示例:

>>> import numpy as np
>>> from sklearn.metrics import brier_score_loss
>>> y_true = np.array([0, 1, 1, 0])
>>> y_pred_prob = np.array([0.1, 0.9, 0.8, 0.4])
>>> brier_score_loss(y_true, y_pred_prob)
0.055
>>> # 將正類記作 0,結果是一樣的
>>> brier_score_loss(y_true, 1 - y_pred_prob, pos_label = 0)
0.055

4.0-1 loss (0-1 損失)

表示預測值與真實值不一致的個數,公式爲:
L01(y,y^)=1ni=1n1(y^iyi) L_{0-1}(y, \hat{y}) = \frac{1}{n} \sum_{i=1}^{n}1(\hat{y}_i \not= y_i)

L01(y,y^)=i=1n1(y^iyi) L_{0-1}(y, \hat{y}) = \sum_{i=1}^{n}1(\hat{y}_i \not= y_i)
簡單示例:

>>> from sklearn.metrics import zero_one_loss
>>> y_true = [2, 2, 3, 4]
>>> y_pred = [1, 2, 3, 4]
>>> zero_one_loss(y_true, y_pred)
0.25
>>> zero_one_loss(y_true, y_pred, normalize=False)
1

5.Hamming loss(漢明損失)

用於多標籤分類問題的模型評估。公式爲:
Hamming-loss(y,y^)=1ni=1n(1mj=1mi1(yij^yij)) \texttt{Hamming-loss}(y, \hat{y}) = \frac{1}{n} \sum_{i=1}^{n} (\frac{1}{m} \sum_{j=1}^{m_i}1(\hat{y_{ij}} \not= y_{ij}))
其中,m 爲每個樣本的標籤個數。漢明距離也可以用於常規的單標籤問題,即 m=1m=1 。這時候等價於 0-1 損失。

簡單示例:

>>> from sklearn.metrics import hamming_loss
>>> import numpy as np

>>> # 多標籤
>>> y_true = np.array([[1, 1], [1, 1]])
>>> y_pred = np.array([[0, 1], [1, 1]])
>>> hamming_loss(y_true, y_pred)
0.25

>>> # 單標籤
>>> y_true = [2, 2, 3, 4]
>>> y_pred = [1, 2, 3, 4]
>>> hamming_loss(y_true, y_pred)
0.25

6.Confusion matrix (混淆矩陣)

每個類別預測正確和錯誤的情況。

簡單示例:

>>> from sklearn.metrics import confusion_matrix
>>> y_true = [2, 0, 2, 2, 0, 1]
>>> y_pred = [0, 0, 2, 2, 0, 2]
>>> confusion_matrix(y_true, y_pred)
array([[2, 0, 0],
       [0, 0, 1],
       [1, 0, 2]])


如圖所示,真實值爲 0,預測值爲 0 的有 2 個;真實值爲 0,預測值爲 1 的有 0 個;真實值爲 0,預測值爲 2 的有 0 個,所以第一行依次爲 2,0,0。第二、三行同理。

如果是二分類問題,有一種特定的記法:

  • TP(true positive):將正類預測爲正類的樣本數
  • FN(false negative):將正類預測爲負類的樣本數
  • FP(false positive):將負類預測爲正類的樣本數
  • TN(true negative):將負類預測爲負類的樣本數

混淆矩陣爲:

7.precision(精確率、查準率)和 recall(召回率、查全率)

  • 精確率被預測爲某一類的樣本中有多少真實值也是這一類(查準)
  • 召回率是所有真實值是某一類的樣本中有多少被預測爲這一類(查全)

在二分類問題中,一般特指正類,即:精確率是所有被預測爲正類的樣本中,真實值也是正類的比例,即 TPTP+FP\frac{TP}{TP+FP}。召回率是所有真實值是正類的樣本中,被預測爲正類的比例,即 TPTP+FN\frac{TP}{TP+FN}

簡單示例:

>>> from sklearn.metrics import accuracy_score, recall_score
>>> # 設1爲正類
>>> y_true = [1, 1, 0, 1, 1]
>>> y_pred = [1, 0, 1, 1, 0]
>>> precision_score(y_true, y_pred)
0.6666666666666666
>>> recall_score(y_true,y_pred)
0.5

分析:TP=2,FP=1,FN=2,所以 precision=22+1=0.6667precision = \frac{2}{2+1}=0.6667recall=22+2=0.5recall = \frac{2}{2+2}=0.5

爲了擴展到多分類問題,可以使用 macro(宏平均)和 micro(微平均)。

宏平均:先對每個類別分別計算 precision 和 recall,然後對每個類別的 precision 和 recall 求算術平均,得到 macro precision 和 macro recall。

微平均:首先定義記號 T0 爲 “真0”(預測值和真實值都是“0”),F0 爲 “假0”(預測值是“0”但真實值不是“0”),T1 爲 “真1”(預測值和真實值都是“1”),以此類推。然後對全部 Tn 求算術平均得到 T ,全部 Fn 求算術平均得到 F。最後用 T 和 F 求總體的 precision 和 recall。micro precision 和 micro recall 相等,都是 TT+F\frac{T}{T+F}

簡單示例:

>>> from sklearn.metrics import precision_score, recall_score

>>> y_true = [1, 1, 2, 0, 2]
>>> y_pred = [1, 0, 1, 2, 1]

>>> precision_score(y_true, y_pred, average='macro')
0.1111111111111111
>>> recall_score(y_true, y_pred, average='macro')
0.16666666666666666
>>> precision_score(y_true, y_pred, average='micro')
0.2
>>> recall_score(y_true, y_pred, average='micro')
0.2

分析:
宏平均:被預測爲 “0” 的樣本有 1 個,其中 0 個真實值是 “0”,所以 “0” 的 precision 爲 0,同理可算出 “1” 的 precision 爲 1/3,“2” 的 precision 爲 0,它們的算術平均爲 1/9=0.11111,所以 macro precision 爲 0.11111。macro recall 計算方式類似,結果爲 0.166666。

微平均:
T0=0,F0=1,T1=1,F1=2,T2=0,F2=1,則 T=1/3,F=4/3,所以 micro precision 和 micro recall 爲 0.2。

8.F1_score(F1 分數)

通常 precision 和 recall 不能兼得,查準率高了查全率可能會偏低,查全率高了查準率可能會偏低,使用 F1 分數可以綜合考慮它們二者,F1 分數是 precision 和 recall 的調和平均數(倒數平均數),將它們看成同等重要。
F1=21precision+1recall=2×precision×recallprecision+recall F_1=\frac{2}{\frac{1}{precision}+\frac{1}{recall}}=\frac{2 \times precision \times recall}{precision+recall}
簡單示例:

>>> from sklearn.metrics import recall_score, precision_score,f1_score
>>> # 設1爲正類
>>> y_true = [1, 1, 0, 1, 1]
>>> y_pred = [1, 0, 1, 1, 0
>>> precision_score(y_true, y_pred)
0.6666666666666666
>>> recall_score(y_true, y_pred)
0.5
>>> f1_score(y_true,y_pred)
0.5714285714285715

macro F1 score:使用 macro precision 和 macro recall 計算得到的 F1。
micro F1 score:使用 micro precision 和 micro recall 計算得到的 F1。

簡單示例:

>>> from sklearn.metrics import f1_score
>>> # 設1爲正類
>>> y_true = [1, 1, 0, 1, 1]
>>> y_pred = [1, 0, 1, 1, 0]
>>> f1_score(y_true, y_pred, average='macro')
0.28571428571428575
>>> f1_score(y_true, y_pred, average='micro')
0.4000000000000001

9.Fβ_\beta_score(Fβ_\beta 分數)

有時候 precision 和 recall 的重要程度是不同的,例如在廣告推薦中,爲了儘可能少打擾用戶,更希望推薦內容是用戶感興趣的,此時查準率更重要;而在逃犯追捕中,更希望少遺漏,此時查全率更重要。FβF_\betaF1F_1 的一般形式:
Fβ=(1+β2)×precision×recall(β2×precision)+recall F_\beta=\frac{(1+\beta^2)\times precision \times recall}{(\beta^2\times precision) + recall}
其中,β>0\beta>0 是一個自定義的參數,表示查全率對查準率的相對重要性,β=1\beta=1 時退化爲標準的 F1F_1 分數,β>1\beta>1 時查全率更重要,β<1\beta<1 時查準率更重要。

簡單示例:

>>> from sklearn.metrics import fbeta_score
>>> # 設1爲正類
>>> y_true = [1, 1, 0, 1, 1]
>>> y_pred = [1, 0, 1, 1, 0]

>>> fbeta_score(y_true,y_pred,beta=2)
0.5263157894736842
>>> fbeta_score(y_true,y_pred,beta=1)
0.5714285714285715
>>> fbeta_score(y_true,y_pred,beta=0.5)
0.625

macro FβF_\beta score:使用 macro precision 和 macro recall 計算得到的 FβF_\beta
micro FβF_\beta score:使用 micro precision 和 micro recall 計算得到的 FβF_\beta

簡單示例:

>>> from sklearn.metrics import fbeta_score
>>> # 設1爲正類
>>> y_true = [1, 1, 0, 1, 1]
>>> y_pred = [1, 0, 1, 1, 0]
>>> fbeta_score(y_true, y_pred, beta=2, average='macro')
0.2631578947368421
>>> fbeta_score(y_true, y_pred, beta=2, average='micro')
0.4

10.receiver_operating_characteristic_curve(ROC 曲線,僅用於二分類任務)

有些模型預測的結果是概率值,如 logistic 迴歸模型。將預測值與一個分類閾值比較,大於閾值則分爲正類,否則爲負類,這個概率預測結果的好壞決定了模型的泛化能力。根據這個概率預測結果將樣本排序,最可能是正類的排在最前面,最不可能是正類的排在最後面,這樣分類過程就相當於在這個排序中以某個截斷點將樣本分爲兩部分,前一部分是正類,後一部分是負類。可以根據不同的任務採用不同的截斷點,如果更注重查準率,可以選擇比較靠前的位置截斷;如果更注重查全率,可以選擇比較靠後的位置截斷。

把“真正類的比例”(true positive rate,記作 TPR)作爲縱座標,“假正類的比例”(false positive rate,記作 FPR)作爲橫座標作圖,就得到了 ROC 曲線。
TPR=TPTP+FNFPR=FPTN+FP TPR=\frac{TP}{TP+FN},FPR=\frac{FP}{TN+FP}

圖中黃色曲線爲 ROC 曲線,曲線下方的藍色區域的面積表示了模型的分類能力,面積越大分類能力越強,這個面積叫作 Area Under ROC Curve,即 AUC

11.precision_recall_curve(PR 曲線,僅用於二分類任務)

和 ROC 曲線類似,先根據預測的概率結果對樣本排序,最可能是正類的樣本在前,最不可能是正類的樣本在後,然後按順序逐個把樣本作爲正類進行預測,每次預測後可以計算出當前已預測的樣本的查全率和查準率,以查準率作爲縱座標,以查全率作爲橫座標作圖,就得到了 PR 曲線。越往後,查的越全,查的越不準。

12.cross-entropy loss(交叉熵損失)

也叫 logistic regression loss,log loss,是一個概率估計的定義。通常用於 logistic 迴歸、神經網絡和一些基於期望最大化的模型,可以用來評估預測值爲概率值的模型的性能。

對於二分類問題,真實值 y{0,1}y \in \{0,1\},預測值 p=P(y=1)p = \operatorname{P}(y = 1),單個樣本的交叉熵損失爲 p 對 y 的條件概率的負對數。

Lcross_entropy(y,p)=logPr(yp)=(ylog(p)+(1y)log(1p)) L_{cross\_entropy}(y, p) = -\log \operatorname{Pr}(y|p) = -(y \log (p) + (1 - y) \log (1 - p))

對於多分類(類別總數爲 k)問題,將樣本標籤編碼爲 k 維向量(one-hot)Y,模型預測樣本屬於每個類別的概率,組成一個概率估計矩陣 P,則公式爲:
Llog(Y,P)=logPr(YP)=1Ni=0N1k=0K1yi,klogpi,k L_{\log}(Y, P) = -\log \operatorname{Pr}(Y|P) = - \frac{1}{N} \sum_{i=0}^{N-1} \sum_{k=0}^{K-1} y_{i,k} \log p_{i,k}

簡單示例:

>>> from sklearn.metrics import log_loss
>>> y_true = [0, 0, 1, 1]
>>> y_pred = [[.9, .1], [.8, .2], [.3, .7], [.01, .99]]
>>> log_loss(y_true, y_pred)
0.1738...

分析:y_pred 中的第一項 [.9, .1] 表示第一個樣本是 “0” 的概率是 0.9,是 “1” 的概率是 0.1。

13.Hinge loss(鉸鏈損失)

用於最大間隔分類器,如 SVM。樣本真實值y{+1,1}y \in \{+1,-1\},模型輸入爲 ww,則鉸鏈損失爲:
LHinge(y,w)=max{1wy,0}=1wy+L_\text{Hinge}(y, w) = \max\left\{1 - wy, 0\right\} = \left|1 - wy\right|_+

簡單示例:

>>> from sklearn import svm
>>> from sklearn.metrics import hinge_loss
>>> X = np.array([[0], [1], [2], [3]])
>>> Y = np.array([0, 1, 2, 3])
>>> labels = np.array([0, 1, 2, 3])
>>> est = svm.LinearSVC()
>>> est.fit(X, Y)
LinearSVC()
>>> pred_decision = est.decision_function([[-1], [2], [3]])
>>> y_true = [0, 2, 3]
>>> hinge_loss(y_true, pred_decision, labels)
0.56...

14.Matthews correlation coefficient(馬修斯相關係數,僅用於二分類任務)

考慮了 TP,FP,FN,TN,是一種比較平衡的度量,在數據集標籤類別特別不均衡時也能使用。

二分類問題的公式爲:
MCC=tp×tnfp×fn(tp+fp)(tp+fn)(tn+fp)(tn+fn).MCC = \frac{tp \times tn - fp \times fn}{\sqrt{(tp + fp)(tp + fn)(tn + fp)(tn + fn)}}.

對於多分類問題,首先定義:

  • tk=iKCikt_k=\sum_{i}^{K} C_{ik}
  • pk=iKCkip_k=\sum_{i}^{K} C_{ki}
  • c=kKCkkc=\sum_{k}^{K} C_{kk}
  • s=iKjKCijs=\sum_{i}^{K} \sum_{j}^{K} C_{ij}

則公式爲:
MCC=c×skKpk×tk(s2kKpk2)×(s2kKtk2)MCC = \frac{ c \times s - \sum_{k}^{K} p_k \times t_k } {\sqrt{ (s^2 - \sum_{k}^{K} p_k^2) \times (s^2 - \sum_{k}^{K} t_k^2) }}

簡單示例:

>>> from sklearn.metrics import matthews_corrcoef
>>> y_true = [+1, +1, +1, -1]
>>> y_pred = [+1, -1, +1, +1]
>>> matthews_corrcoef(y_true, y_pred)
-0.33...

15.Jaccard similarity coefficients(Jaccard 相似係數)

本身用於二分類問題,可以通過宏平均和微平均擴展到多分類問題。

公式爲:
J(yi,y^i)=yiy^iyiy^i.J(y_i, \hat{y}_i) = \frac{|y_i \cap \hat{y}_i|}{|y_i \cup \hat{y}_i|}.

簡單示例:

>>> import numpy as np
>>> from sklearn.metrics import jaccard_score
>>> y_true = np.array([[0, 1, 1],
...                    [1, 1, 0]])
>>> y_pred = np.array([[1, 1, 1],
...                    [1, 0, 0]])
>>> jaccard_score(y_true[0], y_pred[0])
0.6666...

二、迴歸模型的度量

1.explained_variance(可解釋方差)

公式爲:
explained_variance(y,y^)=1Var{yy^}Var{y}explained\_{}variance(y, \hat{y}) = 1 - \frac{Var\{ y - \hat{y}\}}{Var\{y\}}

簡單示例:

>>> from sklearn.metrics import explained_variance_score
>>> y_true = [3, -0.5, 2, 7]
>>> y_pred = [2.5, 0.0, 2, 8]
>>> explained_variance_score(y_true, y_pred)
0.957...
>>> y_true = [[0.5, 1], [-1, 1], [7, -6]]
>>> y_pred = [[0, 2], [-1, 2], [8, -5]]
>>> explained_variance_score(y_true, y_pred, multioutput='raw_values')
array([0.967..., 1.        ])
>>> explained_variance_score(y_true, y_pred, multioutput=[0.3, 0.7])
0.990...

2.max_error(最大誤差)

公式爲:
Max Error(y,y^)=max(yiy^i)\text{Max Error}(y, \hat{y}) = max(| y_i - \hat{y}_i |)

簡單示例:

>>> from sklearn.metrics import max_error
>>> y_true = [3, 2, 7, 1]
>>> y_pred = [9, 2, 7, 1]
>>> max_error(y_true, y_pred)
6

3.mean_absolute_error(平均絕對值誤差,l1正則損失)

公式爲:
MAE(y,y^)=1ni=0n1yiy^i.\text{MAE}(y, \hat{y}) = \frac{1}{n} \sum_{i=0}^{n-1} \left| y_i - \hat{y}_i \right|.

簡單示例:

>>> from sklearn.metrics import mean_absolute_error
>>> y_true = [3, -0.5, 2, 7]
>>> y_pred = [2.5, 0.0, 2, 8]
>>> mean_absolute_error(y_true, y_pred)
0.5
>>> y_true = [[0.5, 1], [-1, 1], [7, -6]]
>>> y_pred = [[0, 2], [-1, 2], [8, -5]]
>>> mean_absolute_error(y_true, y_pred)
0.75
>>> mean_absolute_error(y_true, y_pred, multioutput='raw_values')
array([0.5, 1. ])
>>> mean_absolute_error(y_true, y_pred, multioutput=[0.3, 0.7])
0.85...

4.mean_squared_error(均方誤差)

公式爲:
MSE(y,y^)=1ni=0n1(yiy^i)2.\text{MSE}(y, \hat{y}) = \frac{1}{n} \sum_{i=0}^{n - 1} (y_i - \hat{y}_i)^2.

簡單示例:

>>> from sklearn.metrics import mean_squared_error
>>> y_true = [3, -0.5, 2, 7]
>>> y_pred = [2.5, 0.0, 2, 8]
>>> mean_squared_error(y_true, y_pred)
0.375
>>> y_true = [[0.5, 1], [-1, 1], [7, -6]]
>>> y_pred = [[0, 2], [-1, 2], [8, -5]]
>>> mean_squared_error(y_true, y_pred)
0.7083...

5.mean_squared_log_error(均方對數誤差)

公式爲:
MSLE(y,y^)=1ni=0n1(loge(1+yi)loge(1+y^i))2.\text{MSLE}(y, \hat{y}) = \frac{1}{n} \sum_{i=0}^{n - 1} (\log_e (1 + y_i) - \log_e (1 + \hat{y}_i) )^2.

簡單示例:

>>> from sklearn.metrics import mean_squared_log_error
>>> y_true = [3, 5, 2.5, 7]
>>> y_pred = [2.5, 5, 4, 8]
>>> mean_squared_log_error(y_true, y_pred)
0.039...
>>> y_true = [[0.5, 1], [1, 2], [7, 6]]
>>> y_pred = [[0.5, 2], [1, 2.5], [8, 8]]
>>> mean_squared_log_error(y_true, y_pred)
0.044...

6.median_absolute_error(中位絕對誤差)

魯棒性更強,因爲使用中位數。公式爲:
MedAE(y,y^)=median(y1y^1,,yny^n).\text{MedAE}(y, \hat{y}) = \text{median}(\mid y_1 - \hat{y}_1 \mid, \ldots, \mid y_n - \hat{y}_n \mid).

簡單示例:

>>> from sklearn.metrics import median_absolute_error
>>> y_true = [3, -0.5, 2, 7]
>>> y_pred = [2.5, 0.0, 2, 8]
>>> median_absolute_error(y_true, y_pred)
0.5

7.R2(可決係數)

公式爲:
R2(y,y^)=1i=1n(yiy^i)2i=1n(yiyˉ)2R^2(y, \hat{y}) = 1 - \frac{\sum_{i=1}^{n} (y_i - \hat{y}_i)^2}{\sum_{i=1}^{n} (y_i - \bar{y})^2}
其中 yˉ=1ni=1nyi\bar{y} = \frac{1}{n} \sum_{i=1}^{n} y_ii=1n(yiy^i)2=i=1nϵi2\sum_{i=1}^{n} (y_i - \hat{y}_i)^2 = \sum_{i=1}^{n} \epsilon_i^2

簡單示例:

>>> from sklearn.metrics import r2_score
>>> y_true = [3, -0.5, 2, 7]
>>> y_pred = [2.5, 0.0, 2, 8]
>>> r2_score(y_true, y_pred)
0.948...
>>> y_true = [[0.5, 1], [-1, 1], [7, -6]]
>>> y_pred = [[0, 2], [-1, 2], [8, -5]]
>>> r2_score(y_true, y_pred, multioutput='variance_weighted')
0.938...
>>> y_true = [[0.5, 1], [-1, 1], [7, -6]]
>>> y_pred = [[0, 2], [-1, 2], [8, -5]]
>>> r2_score(y_true, y_pred, multioutput='uniform_average')
0.936...
>>> r2_score(y_true, y_pred, multioutput='raw_values')
array([0.965..., 0.908...])
>>> r2_score(y_true, y_pred, multioutput=[0.3, 0.7])
0.925...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章