3.3 指標和評分:量化預測的質量?
3個不同的API可供評估模型預測質量:
評估器評分方法:評估器有一個score方法,它給計劃解決的問題提供一個初始評估標準。這部分內容不在這里討論,但會出現在每一個評估器的文件中。 評分參數:使用交叉驗證(cross-validation)的模型評估方法(例如:[model_selection.cross_val_score和model_selection.GridSearchCV)基于一個內部評分策略。這部分內容將會在評分參數:定義模型評估規則。 指標函數:metrics模塊執行的功能是評估特定目的的誤差。這些指標在分類指標, 多標簽排序指標, 回歸指標和聚類指標部分會詳細介紹。
最后,Dummy評估器(Dummy 評估器)可用于獲取隨機預測的這些指標基準值。
還可參見:對于“成對”指標,樣本之間而不是評估器或者預測值之間,詳見成對度量、親和力和核函數部分。
3.3.1 評分參數:定義模型評估準則
模型選擇和評估使用的工具,如model_selection, GridSearchCV和model_selection.cross_val_score,使用scoring參數控制對評估器的估計量應用的指標。
3.3.1.1 常見場景:預定義值
在最常見的例子中,可以給scoring參數指定評分對像;下面的表格列出所有可能取值。所有記分對象遵從的慣例是:高返回值好于低返回值。因此,如metrics.mean_squared_error,衡量模型與數據間差距的指標可用neg_mean_squared_error,它返回一個負值。
示例:
>>> from sklearn import svm, datasets
>>> from sklearn.model_selection import cross_val_score
>>> X, y = datasets.load_iris(return_X_y=True)
>>> clf = svm.SVC(random_state=0)
>>> cross_val_score(clf, X, y, cv=5, scoring='recall_macro')
array([0.96..., 0.96..., 0.96..., 0.93..., 1. ])
>>> model = svm.SVC()
>>> cross_val_score(model, X, y, cv=5, scoring='wrong_choice')
Traceback (most recent call last):
ValueError: 'wrong_choice' is not a valid scoring value. Use sorted(sklearn.metrics.SCORERS.keys()) to get va
注意: ValueError列出的異常值對應于以下各節中說明的測量預測準確性函數。這些函數中的評分對象以字典形式存儲在sklearn.metrics.SCORES中。
3.3.1.2 根據metric函數定義評分策略
sklearn.metrics模塊公開一組簡單函數,該函數可應用于測量給定真實值和預測值的預測誤差:
以_score為結尾的函數,返回一個最大值,該值越大越好。 以_error或_loss為結尾的函數,返回一個最小值,該值越小越好。當使用make_scorer把它轉變為評分對象時,設置greater_is_better參數為False(初始值是True;詳見下面的函數描述)。
各類機器學習任務的可用指標會在下文詳細介紹。
許多指標沒有給定名稱就作為scoring的參數值,有時是因為它們需要額外的參數,例如fbeta_score。使用make_scorer是生成可調用對象進行評分的最簡單方法,該函數將指標轉換為可用于模型評估的可調用對象。
一個典型的例子是從庫中包含一個非默認參數值中,包裝現有指標函數,例如fbeta_score函數用來定義beta參數:
>>> from sklearn.metrics import fbeta_score, make_scorer
>>> ftwo_scorer = make_scorer(fbeta_score, beta=2)
>>> from sklearn.model_selection import GridSearchCV
>>> from sklearn.svm import LinearSVC
>>> grid = GridSearchCV(LinearSVC(), param_grid={'C': [1, 10]},
... scoring=ftwo_scorer, cv=5)
第二個例子是在簡單python函數中使用make_scorer,以構建完全自定義評分對像,它可以接受幾個參數:
可以使用的python函數(下例中使用my_custom_loss_func) 是否python函數返回一個分數(初始值為greater_is_better=True)或者一個損失(分數)(greater_is_better=False)。如果一個損失函數,python函數的返回值是負值的評分對象,符合交叉驗證的傳統,評分越高,模型越好。 僅對于分類的指標:是否python函數要求提供連續決定確定性(needs_threshold=True)。初始值是False。 任何其它參數,如f1_score中的beta或labels。
如下示例展示構建傳統評分器,使用greater_is_better參數:
>>> import numpy as np
>>> def my_custom_loss_func(y_true, y_pred):
... diff = np.abs(y_true - y_pred).max()
... return np.log1p(diff)
...
>>> # score will negate the return value of my_custom_loss_func,
>>> # which will be np.log(2), 0.693, given the values for X
>>> # and y defined below.
>>> score = make_scorer(my_custom_loss_func, greater_is_better=False)
>>> X = [[1], [1]]
>>> y = [0, 1]
>>> from sklearn.dummy import DummyClassifier
>>> clf = DummyClassifier(strategy='most_frequent', random_state=0)
>>> clf = clf.fit(X, y)
>>> my_custom_loss_func(clf.predict(X), y)
0.69...
>>> score(clf, X, y)
-0.69...
3.3.1.3 執行自定義評分對象
無需使用make_scorer “制造廠”,就可以通過從頭構建自定義評分對象,生成更加靈活的模型評分器。對于一個可調用的評分器,需要滿足如下兩個規定協議:
可以調用參數(estimator, X, y),estimator是需要被評估的模型,X是驗證數據,y是X標簽(應用于有監督的案例中)的真實值或者None(應用于非監督的案例中)。 它返回一個浮點型數值,該數值量化estimator對X關于y的預測質量。再強調一遍,越高的得分模型越好,所以如果得分是損失函數的返回值,那么該值應為負。
注意:當n_jobs>1時,函數中對傳統評分器的使用
雖然在調用函數的旁邊定義自定義評分函數應使用默認joblib backend(loky),但從另一個模塊中導入時將會是更健壯的方法,并且獨立于joblib backend(loky)。
例如,下例中將n_jobs設置為大于1,custom_scoring_function保存在user_created模塊(custom_scorer_module.py)中并導入:
>>> from custom_scorer_module import custom_scoring_function
>>> cross_val_score(model,
... X_train,
... y_train,
... scoring=make_scorer(custom_scoring_function, greater_is_better=False),
... cv=5,
... n_jobs=-1)
3.3.1.4 使用多指標評估
Scikit-learn也允許在GridSearchCV,RandomizedSearchCV和cross_validate中評估多指標。
有兩種方式可以指定scoring參數的多評分指標:
可迭代字符串指標::
>>> scoring = ['accuracy', 'precision']
以字典形式將評分器名稱映射給評分函數::
>>> from sklearn.metrics import accuracy_score
>>> from sklearn.metrics import make_scorer
>>> scoring = {'accuracy': make_scorer(accuracy_score),
... 'prec': 'precision'}
需要注意的是:字典的值或者是評分器函數,或者是預定義指標字符串的一個。
目前,只有返回單值的評分函數才能使用字典傳遞。 評分函數返回多個值是不被允許的,并且要求封裝從而返回單個指標值。
>>> from sklearn.model_selection import cross_validate
>>> from sklearn.metrics import confusion_matrix
>>> # A sample toy binary classification dataset
>>> X, y = datasets.make_classification(n_classes=2, random_state=0)
>>> svm = LinearSVC(random_state=0)
>>> def tn(y_true, y_pred): return confusion_matrix(y_true, y_pred)[0, 0]
>>> def fp(y_true, y_pred): return confusion_matrix(y_true, y_pred)[0, 1]
>>> def fn(y_true, y_pred): return confusion_matrix(y_true, y_pred)[1, 0]
>>> def tp(y_true, y_pred): return confusion_matrix(y_true, y_pred)[1, 1]
>>> scoring = {'tp': make_scorer(tp), 'tn': make_scorer(tn),
... 'fp': make_scorer(fp), 'fn': make_scorer(fn)}
>>> cv_results = cross_validate(svm.fit(X, y), X, y, cv=5, scoring=scoring)
>>> # Getting the test set true positive scores
>>> print(cv_results['test_tp'])
[10 9 8 7 8]
>>> # Getting the test set false negative scores
>>> print(cv_results['test_fn'])
[0 1 2 3 2]
3.3.2 分類指標
sklearn.metrics模塊執行各種損失函數,評分,及調用函數測量分類模型的表現。一些指標可能要求正類別的可能性(probability)估計,置信度值,或者二分類決策值。大多數執行允許計算每一個樣本對評分的權重貢獻,通過sample_weight參數實現。
其中一些只適用于二分類的案例中:
參數 | 說明 |
---|---|
precision_recall_curve(y_true, probs_pred, *) | 根據不同的可能性閾值計算精確率-召回率 |
roc_curv(y_true, y_score, *[, pos_label, ...]) | 計算Receiver operating characteristic(ROC) |
其它也可用于多分類的參數例子:
參數 | 說明 |
---|---|
balanced_accuracy_score(y_true, y_pred, *) | 計算balanced準確率 |
cohen_kappa_score(y1, y2, *[, labels, ...]) | Cohen's kappa:衡量注一致程度的統計 |
confusion_matrix(y_true, y_pred, *[, ...]) | 計算混淆矩陣來評估分類模型的準確率 |
hinge_loss(y_true, pred_decision, *[, ...]) | 平均hinge損失(非正規 non-regularized) |
matthews_corrcoef(y_true, y_pred, *[, ...]) | 計算曼哈頓相關系數(MCC) |
roc_auc_score(y_true, y_score, *[, ...] | 從預測分數中,計算ROC曲線的面積(ROC AUC) |
一些也可以用于多分類例子中的參數:
參數 | 說明 |
---|---|
accuracy_score(y_true, y_pred, *[, ...]) | 分類模型的準確率得分 |
classification_report(y_true, y_pred, *[, ...]) | 主要分類模型指標的文本報告 |
f1_score(y_true, y_pred, *[, labels, ...]) | 計算F1評分,也被稱為balanced F-score或者F-measure |
fbeta_score(y_true, y_pred, *, beta[, ...]) | 計算F-beta評分 |
hamming_loss(y_true, y_pred, *[, sample_weight]) | 計算平均Hamming損失 |
jaccard_score(y_true, y_pred, *[, labels, ...]) | Jaccard相似性系數得分 |
log_loss(y_true, y_pred, *[, eps, ...]) | 對數損失,aka logistic損失或者交叉熵損失 |
multilabel_confusion_matrix(y_true, y_pred, *) | 為每一個類或樣本計算混淆矩陣 |
precision_recall_fscore_support(y_true, ...) | 計算精確率,召回率,F-measure并且支持每一個類 |
precision_score(y_true, y_pred, *[, ...]) | 計算精確率 |
recall_score(y_true, y_pred, *[, labels, ...]) | 計算召回率 |
roc_auc_score(y_true, y_score, *[, ...]) | 從預測分數中計算ROC曲線的面積 |
zero_one_loss(y_true, y_pred, *[, ...]) | 0-1分類損失 |
可以處理二分類和多標簽(不是多分類)的問題:
參數 | 說明 |
---|---|
average_precision_score(y_true, y_score, *) | 從預測評分中計算平均精確率(AP) |
在隨后的各子部分中,將會描述每一個上述函數,使用常用的API和指數定義。
3.3.2.1 從二分類到多分類和多標簽
一些指標本質上是定義給二分類模型的(例如:f1_score)。在這些例子中,模型的默認值是只有正標簽會被評估,假設正樣本類的標簽為1是初始值(盡管標簽可以通過pos_label參數進行修改)。
由二分類指標延伸到多類或者多標簽問題,數據被當作是二分類問題的集合,每個類都有一個。有一系列的方法可用于計算類集合的平均二分類指標,每個二分類指標可以應用于某些領域中。如果需要,可以使用average參數進行定義。
"weighted" (權重)處理類的不均衡問題。按其在真實數據中的加權計算每個類的分數,并計算各二分類指標的平均值。 "micro" (微)對于所有二分類指標(除非已分配樣本權重)指定給每個樣本類匹配相等的貢獻。除了匯總每個類的指標,還要匯總除數和被除數,將每個類的各指標匯總成一個整體商(總被除數/總除數得出評估模型整體水平的商)。 微-平均方法更適合多標簽分類中,包括多類別分類問題,但多數類會被忽略。 "samples" (樣本)僅應用于多標簽問題。它不對子類進行計算,而是計算評估數據中每個樣本真實類別和預測類別的指標。 最后返回它們的(sample_weight - weighted)均值。 設置參數 average = None 會返回每個類得分的數組。
當多分類數據作為類標簽數組提供給指標時,如二分類標簽,多標簽數據就會被指定為一個指標矩陣。 如元素(一個列表形式)[i, j],如果樣本i被標記為j,則其值為1,否則為0。
3.3.2.2 準確率評分
accuracy_score函數計算accuracy(準確率),或者是個分數(初始值)或者是正確預測個數的計數(normalize=False)。
在多標簽分類中,函數返回各子集的準確率。如果整個集合中每一個樣本的預測標簽嚴格匹配集合中的標簽真實值,子集的準確率是1.0;否則是0.0。
如果是第i個樣本的預測值與真實值相一致,對個樣本正確預測的分數值是:
其中*l(x)*是指標函數(indicator function)。
>>> import numpy as np
>>> from sklearn.metrics import accuracy_score
>>> y_pred = [0, 2, 1, 3]
>>> y_true = [0, 1, 2, 3]
>>> accuracy_score(y_true, y_pred)
0.5
>>> accuracy_score(y_true, y_pred, normalize=False)
2
在帶有二分類標簽指標的多標簽例子中:
>>> accuracy_score(np.array([[0, 1], [1, 1]]), np.ones((2, 2)))
0.5
例如:
詳見 用排列檢驗分類分數的顯著性 是一個排序數據集的準確率評分。
3.3.2.3 平衡的準確率評分(Balanced accuracy score)
balanced_accuracy_score函數計算balanced accuracy,避免了對不平衡數據集進行夸大的性能估計。每個類別召回率的宏平均,或者等同于每個樣本根據真實類別的比率(inverse prevalence)的權重,而計算的原始準確率。因此,對于平衡樣本,平衡的準確率評分(Balanced accuracy score)與準確率相同。
在二分類的例子中,平衡的準確率與靈敏度(sensitivity)相同(真正率)和特異性(specificity)(真負率),或者ROC曲線的面積(二分類預測值而不是分數):
如果分類器在每個類的表現都很好,則該函數會退化為傳統的準確率(例如:正確預測的個數除以總預測樣本數)。
與之相對比,如果傳統的準確率高于樣本比例,僅因為分類器利用的是不均衡測試集,而對于平衡的準確率,會下降為。
分數范圍為0-1,或者當參數adjusted=True時,范圍變為到1,包括邊界的,隨機得分表現為0。
如果是第i個樣本的真實值,是對應的樣本權重,從而調整的樣本權重為:
其中,l(x)是指標函數。根據樣本i的預測值,平衡的準確率被定義如下:
設置adjusted=True,平衡的準確率報告的是比相對高的值。在二分類的例子中,也被稱為*Youden's J statistic*或者informedness。
**注意:**多分類的定義看起來是用于二分類指標的合理延伸,盡管在文獻中未達成共識。
我們的定義:[Mosley2013], [Kelleher2015]和[Guyon2015], 其中[Guyon2015]適合調整的版本,以確保隨機預測值為0,好的預測值為1.. 類的均衡準確率在[Mosley2013]中描述:每個類別中精確率和召回率的最小值會被計算。將計算出的這些值進行平均,從而得到均衡的準確率。 均衡的準確率在[Urbanowicz2015]中被描述:每一個類別的靈敏度和特異性的均值會被計算,隨后計算總的均值。
參考:
Guyon2015(1,2) I. Guyon, K. Bennett, G. Cawley, H.J. Escalante, S. Escalera, T.K. Ho, N. Macià, B. Ray, M. Saeed, A.R. Statnikov, E. Viegas, Design of the 2015 ChaLearn AutoML Challenge, IJCNN 2015.
Mosley2013(1,2) L. Mosley, A balanced approach to the multi-class imbalance problem, IJCV 2010.
Kelleher2015 John. D. Kelleher, Brian Mac Namee, Aoife D’Arcy, Fundamentals of Machine Learning for Predictive Data Analytics: Algorithms, Worked Examples, and Case Studies, 2015.
Urbanowicz2015Urbanowicz R.J., Moore, J.H. ExSTraCS 2.0: description and evaluation of a scalable learning classifier system, Evol. Intel. (2015) 8: 89.
3.3.2.4 Cohen's kappa
cohen_kappa_score函數計算Cohen's kappa統計值。此度量旨在比較不同標注的標簽,而分類器和真實數據的比較。
Kappa score(參見文檔字符串)是一個數值,介于-1和1之間。分數大于0.8會被認為是好的協議;小于0說明沒有協議(等同于隨機標簽)。
Kappa score可被用于計算二分類或者多分類的問題,但不適用于多標簽的問題(除手動計算每一個標簽分數)和多于兩個以上注釋器的問題。
>>> from sklearn.metrics import cohen_kappa_score
>>> y_true = [2, 0, 2, 2, 0, 1]
>>> y_pred = [0, 0, 2, 2, 0, 2]
>>> cohen_kappa_score(y_true, y_pred)
0.4285714285714286
3.3.2.5 混淆矩陣
confusion_matrix函數評估分類模型準確率,通過計算每一行相對應真實類別(維基百科或者其它資料可能使用不同的軸向)的混淆矩陣(confusion matrix)。
根據定義, 混淆矩陣中的條目i,j是實際為i,但是預測為j的觀測個數。
如下示例:
>>> 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]])
plot_confusion_matrix可被用于展示混淆矩陣的可視化,在混淆矩陣的例子中,如下圖所示:
參數normalize允許報告比例而不僅是計數。混淆矩陣可以通過3種方式被規范化:"pred", "true", 和"all",這些參數將計算方式區分為按列求和,按行求和,或者整個矩陣求和。
>>> y_true = [0, 0, 0, 1, 1, 1, 1, 1]
>>> y_pred = [0, 1, 0, 1, 0, 1, 0, 1]
>>> confusion_matrix(y_true, y_pred, normalize='all')
array([[0.25 , 0.125],
[0.25 , 0.375]])
對于二分類問題,可以得到真負值計數,假正值計數,假負值計數和真正值計數,詳見如下代碼:
>>> y_true = [0, 0, 0, 1, 1, 1, 1, 1]
>>> y_pred = [0, 1, 0, 1, 0, 1, 0, 1]
>>> tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
>>> tn, fp, fn, tp
(2, 1, 2, 3)
例如:
詳見混淆矩陣,是一個用混淆矩陣評估分類器產出質量的例子。 詳見識別手寫數字,是一個使用混淆矩陣區分手寫數字的例子。 詳見基于稀疏特征的文本文檔分類, 是一個使用混淆矩陣區分文本文檔的例子。
3.3.2.6 分類模型報告
classification_report函數輸出一個文本報告,顯示主要分類模型的評估指標。如下是一個自定義target_names和推斷標簽的例子:
>>> from sklearn.metrics import classification_report
>>> y_true = [0, 1, 2, 2, 0]
>>> y_pred = [0, 0, 2, 1, 0]
>>> target_names = ['class 0', 'class 1', 'class 2']
>>> print(classification_report(y_true, y_pred, target_names=target_names))
precision recall f1-score support
class 0 0.67 1.00 0.80 2
class 1 0.00 0.00 0.00 1
class 2 1.00 0.50 0.67 2
accuracy 0.60 5
macro avg 0.56 0.50 0.49 5
weighted avg 0.67 0.60 0.59 5
例如:
詳見 識別手寫數字,是一個使用手寫數字數據集的分類模型報告。 詳見 基于稀疏特征的文本文檔分類,是一個文本文檔數據集的分類模型報告。 詳見 使用帶有交叉驗證的網格搜索進行參數估計,是一個使用內置交叉驗證的網格搜索的分類模型報告。
3.3.2.7 Hamming損失函數
Hamming_loss 計算平均的Hamming loss或者Hamming distance在兩個樣本的集合中。
如果是某個樣本第j個標簽的預測值,是其對應的真實值,是類別或者標簽個是,Hamming損失函數介于兩個樣本之間:
其中,*l(x)*是指標函數(indicator function)。
>>> from sklearn.metrics import hamming_loss
>>> y_pred = [1, 2, 3, 4]
>>> y_true = [2, 2, 3, 4]
>>> hamming_loss(y_true, y_pred)
0.25
在二分類標簽指標的多分類標簽中:
>>> hamming_loss(np.array([[0, 1], [1, 1]]), np.zeros((2, 2)))
0.75
**注意:**在多分類的分類模型中,y_true和y_pred的Hamming損失函數與Hamming距離相一致,Hamming損失函數與零一損失函數(Zero one loss)相類似。但是零-一損失函數懲罰預測集合,預測集不與真實值集直接匹配,Hamming損失函數懲罰單個標簽。因次,Hamming損失函數的上限是零一損失函數,它介于零和一之間,包括邊界;預測真實標簽合適的子集或者超子集會使Hamming損失函數界于零和一之間,不包括邊界。
3.3.2.8 精確率,召回率和F-measures
直觀地說,精確率(precision)是模型區分的能力,而不是將樣本為負的標簽標記為正,而召回率(recall)是找到正樣本的能力。
F-measure(和測量)可被解釋為精確率和召回率的權重調和平均數。測量值最高為1,最差為0。當時,和是相等的,并且召回率和精確率是同等重要的。
precision_recall_curve從真實標簽和評分(不同閾值設定下,分類器的評分)計算一個精確率-召回率曲線.
average_precision_score函數從預測分數中計算平均精確率(average precision(AP))。該值介于0和1之間,且越高越好。AP的定義如下:
其中,和是在第n個閾值下的精確率和召回率,AP是正樣本的分數。
參考[Manning2008]和[Everingham2010]展現AP的替代變體,它差值計算精確率-召回率曲線。 目前,average_precision_score并不能執行各種差值的變體。參考[Davis2006]和[Flach2015]描述了為何精確率-召回率曲線上點的線性插值產生的結果是過于樂觀的分類器表現測量。線性插值被用于計算帶有梯形法則的ROC曲線面積,即auc。
以下函數提供對精確率,召回率和F-measure評分的解釋:
參數 | 解釋 |
---|---|
average_precision_score(y_true, y_score,*) | 從預測評分中計算平均精確率 |
f1_score(y_true, y_pred, *[labels, ...]) | 計算F1評分,也被稱為均衡的F-score或F-measure |
fbeta_score(y_true, y_pred, *, beta[, ...]) | 計算F-beta評分 |
precision_recall_curve(y_true, probas_pred, *) | 計算在不同的閾值下精確率-召回率組合 |
precision_recall_fscore_support(y_true, ...) | 計算精確率,召回率,F-measure,且支持對每一類的計算 |
precision_score(y_true, y_pred, *[, ...]) | 計算精確率 |
recall_score(y_true, y_pred, *[, labels, ...]) | 計算召回率 |
需要注意的是:precision_recall_curve函數只能用于二分類的例子中。average_precision_score函數可以用于二分類的分類模型和多標簽形式。plot_precision_recall_curve函數畫出精確率召回率關系圖,如下所示。
例如:
參見 基于稀疏特征的文本文檔分類,使用f1_score對文本文檔的分類進行評估。 參見 使用帶有交叉驗證的網格搜索進行參數估計,使用內置交叉驗證的網格搜索估計參數,用precision_score和recall_score評估。 參見 精確度-召回曲線用來評估分類質量。
參考:
[Manning2008] C.D. Manning, P.Raghavan, H. Schütze, Introduction to Information Retrieval, 2008.
[Everingham2010] M. Everingham, L.Van Gool, C.K.I. Williams, J. Winn, A. Zisserman, The Pascal Visual Object Classes (VOC) Challenge, IJCV 2010.
[Davis2006] J. Davis, M. Goadrich, The Relationship Between Precision-Recall and ROC Curves, ICML 2006.
[Flach2015] P.A. Flach, M. Kull, Precision-Recall-Gain Curves: PR Analysis Done Right, NIPS 2015.
3.3.2.8.1 二分類分類模型
在二分類分類模型中,分類預測中的“正”和“負”,“真”和“假”指的是預測值是否與外部評判(也作“觀測值”)相一致。基于這些定義,可以總結一下表格:
實際類別(觀測值) | 實際類別(觀測值) | |
---|---|---|
預測類別(期望) | tp(真正)正確的結果 | fp(假正)意料外的結果 |
預測類別(期望) | fn(假負)錯誤的結果 | tn(真負)正確未出現的結果 |
基于上文,可以定義精確率,召回率和F-measure的概念:
如下是二分類分類模型代碼示例:
>>> from sklearn import metrics
>>> y_pred = [0, 1, 0, 0]
>>> y_true = [0, 1, 0, 1]
>>> metrics.precision_score(y_true, y_pred)
1.0
>>> metrics.recall_score(y_true, y_pred)
0.5
>>> metrics.f1_score(y_true, y_pred)
0.66...
>>> metrics.fbeta_score(y_true, y_pred, beta=0.5)
0.83...
>>> metrics.fbeta_score(y_true, y_pred, beta=1)
0.66...
>>> metrics.fbeta_score(y_true, y_pred, beta=2)
0.55...
>>> metrics.precision_recall_fscore_support(y_true, y_pred, beta=0.5)
(array([0.66..., 1. ]), array([1. , 0.5]), array([0.71..., 0.83...]), array([2, 2]))
>>> import numpy as np
>>> from sklearn.metrics import precision_recall_curve
>>> from sklearn.metrics import average_precision_score
>>> y_true = np.array([0, 0, 1, 1])
>>> y_scores = np.array([0.1, 0.4, 0.35, 0.8])
>>> precision, recall, threshold = precision_recall_curve(y_true, y_scores)
>>> precision
array([0.66..., 0.5 , 1. , 1. ])
>>> recall
array([1. , 0.5, 0.5, 0. ])
>>> threshold
array([0.35, 0.4 , 0.8 ])
>>> average_precision_score(y_true, y_scores)
0.83...
3.3.2.8.2 多分類和多標簽分類模型
在多分類和多標簽分類任務中,精確率,召回率,和F-measures的定義可以應用于每一個獨立的標簽。有很多方法可以將各標簽的結果進行組合,可用average參數分別在average_precision_score(僅用于多標簽),f1_score,fbeta_score,precision_recall_support,precision_score和recall_score函數中傳遞,已在以上描述(above)。需要注意的是:如果所有的標簽啊都包括在內,那么“micro”-averaging(“微”-平均)在多分類中的設置將產生精確率,召回率和F與準確率的結果相等。也要注意"權重"平均可能產生不介于精確率和召回率之間的F-score。
為了更清晰的了解,請考慮如下概念:
y是預測值(樣本,標簽)組合的集合 是真實值(樣本,標簽)組合的集合 L是標簽的集合 S是樣本的集合 是y的樣本s 的子集,例如: 是y的標簽l的子集 同樣地,和均是的子集 (在處理B=\emptyset時,公約有所不同;這個執行使用R(A, B): = 0,并且與P類似 )
各指標定義如下:
average | Precision | Recall | F_beta |
---|---|---|---|
"micro" | |||
"samples" | |||
"macro" | |||
"weighted" | |||
None |
>>> from sklearn import metrics
>>> y_true = [0, 1, 2, 0, 1, 2]
>>> y_pred = [0, 2, 1, 0, 0, 1]
>>> metrics.precision_score(y_true, y_pred, average='macro')
0.22...
>>> metrics.recall_score(y_true, y_pred, average='micro')
0.33...
>>> metrics.f1_score(y_true, y_pred, average='weighted')
0.26...
>>> metrics.fbeta_score(y_true, y_pred, average='macro', beta=0.5)
0.23...
>>> metrics.precision_recall_fscore_support(y_true, y_pred, beta=0.5, average=None)
(array([0.66..., 0. , 0. ]), array([1., 0., 0.]), array([0.71..., 0. , 0. ]), array([2, 2, 2]...))
對于帶有“負類”的多分類類別,可以除去一些標簽:
>>> metrics.recall_score(y_true, y_pred, labels=[1, 2], average='micro')
... # excluding 0, no labels were correctly recalled
0.0
同樣地,一些未在樣本中出現的標簽,可以考慮使用宏-平均(macro-averaging)。
>>> metrics.precision_score(y_true, y_pred, labels=[0, 1, 2, 3], average='macro')
0.166...
3.3.2.9 Jaccard相似性系數評分
jacquard_score函數計算Jaccard similarity coefficients(Jaccard相似性系數)的均值,也被稱為Jaccard指數,在標簽對的集合中。
第i個樣本的Jaccard相似性系數,與真實標簽和預測標簽的定義如下:
jaccard_score與precision_recall_fscore_support的作用類似,應用于二分類標簽,并且通過使用參數average可以擴展到多標簽和多分類(詳見above)。
在二分類例子中:
>>> 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...
用二分類標簽指標的多標簽例子:
>>> jaccard_score(y_true, y_pred, average='samples')
0.5833...
>>> jaccard_score(y_true, y_pred, average='macro')
0.6666...
>>> jaccard_score(y_true, y_phred, average=None)
array([0.5, 0.5, 1. ])
多分類問題被二分類化,并且與多標簽問題的解決方法一致:
>>> y_pred = [0, 2, 1, 2]
>>> y_true = [0, 1, 2, 2]
>>> jaccard_score(y_true, y_pred, average=None)
array([1. , 0. , 0.33...])
>>> jaccard_score(y_true, y_pred, average='macro')
0.44...
>>> jaccard_score(y_true, y_pred, average='micro')
0.33...
3.3.2.10 Hinge loss
hinge_loss函數指通過使用hinge loss方法計算模型和數據之間的平均距離,它是一個單邊指數,即僅考慮預測誤差。(Hinge loss被用于最大化邊際分類器,如支持向量機。)
如果標簽被編碼為+1和-1,y:是真實值,w是預測決策,是decision_function的產出值,hinge loss被定義如下:
如果多于兩個標簽,根據Crammer & Singer,hinge_loss使用多分類變體。詳見論文鏈接。
如果是真實樣本的預測決策,是所有樣本預測決策的最大值,預測決策是預測函數的返回值,多分類hinge loss的定義如下:
如下是用帶有hinge_loss函數的支持向量機分類器解決的二分類問題的小例子:
>>> from sklearn import svm
>>> from sklearn.metrics import hinge_loss
>>> X = [[0], [1]]
>>> y = [-1, 1]
>>> est = svm.LinearSVC(random_state=0)
>>> est.fit(X, y)
LinearSVC(random_state=0)
>>> pred_decision = est.decision_function([[-2], [3], [0.5]])
>>> pred_decision
array([-2.18..., 2.36..., 0.09...])
>>> hinge_loss([-1, 1, 1], pred_decision)
0.3...
如下是用帶有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...
3.3.2.11 對數損失函數(Log loss)
對數損失函數,也被稱作邏輯回歸損失函數或者交叉熵損失函數,是基于可能性的估計值。它被廣泛應用于(多項式)邏輯回歸和神經網絡模型中,以及一些計算期望最大化的變種模型,并且被用于評估一個分類器而不是離散預測值的可能性產出(predict_proba)。
對于帶有真實標簽二分類分類模型和一個可能性估計,每個樣本的對數損失函數是給定真實標簽分類器的負對數似然值:
它延伸到多分類的例子如下所示。樣本中的真實標簽可以被編碼為1-of-K 二分類指標矩陣 Y,例如:如果樣本i的標簽k是從標簽集合K中提取的。通過,讓P成為可能性估計矩陣。對數損失函數的集合就是:
如想詳細了解上述二分類對數損失函數是如何生成的,需要注意在二分類的例子中,和,所以給出二分類對數損失函數,需要擴展的內部和。
提供真實標簽值的列表和可能性矩陣,log_loss函數計算對數損失函數,會通過估計器的predict_proba方法得到返回值。
>>> 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的可能性為90%。對數損失函數是非負的。
3.3.2.12 馬修斯相關系數
對于二分類,matters_corrcoef函數計算的是Matthew's correlation coefficient (MCC)。 下面引用自維基百科:
“馬修斯相關系數被用于機器學習是作為測量二分類(兩類)分類模型質量的評估。它考慮真正,假正,真負和假負,并且被認為是一個平衡值,可被用于類大小不均衡的數據。馬修斯相關系數(MCC)本質上是一個介于-1和+1之間的相關系數值。如果系數值為+1,則表示預測非常好,0表示一個平均隨機的預測,-1表示預測相反。在統計學中也被稱作phi系數。”
在二分類(兩類)的例子中,tp,tn,fp和fn分別是真正,真負,假正和假負的數量,MCC被定義如下:
在多分類的例子中,馬修斯相關系數被定義為可以根據K個分類計算混淆矩陣C。為了簡化定義,考慮如下的中間變量:
是類別k真實發生的次數, 是類別k預測的次數, 是正確預測的總樣本個數, 是總樣本的個數。
多分類MCC被定義為:
當多于兩個標簽時,MCC的值不再介于-1和+1之間。而是最小值值介于-1和0之間,且依據真實標簽的數量和分布而定。最大值依然是+1。
以下是解釋matthews_corrcoef函數的用法:
>>> 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...
3.3.2.13 多標簽混合矩陣
multilabel_confusion_matrix函數計算class-wise(初始值)或者sample-wise(sample wise = True)多標簽混淆矩陣來評估分類模型的準確率。如果是多標簽,多標簽混淆矩陣(multilabel_confusion_matrix)也被認為是多分類數據。這種轉變被普遍用于使用二分類分類模型指標(例如精確率,召回率等。)評估多分類問題。
當計算class-wise多標簽混淆矩陣C,類別i的真負個數是,假負是,真正是,和假正是。
如下示例解釋帶有多標簽指標矩陣(多標簽指標矩陣)投入的multilabel_confusion_matrix函數的使用:
>>> import numpy as np
>>> from sklearn.metrics import multilabel_confusion_matrix
>>> y_true = np.array([[1, 0, 1],
... [0, 1, 0]])
>>> y_pred = np.array([[1, 0, 0],
... [0, 1, 1]])
>>> multilabel_confusion_matrix(y_true, y_pred)
array([[[1, 0],
[0, 1]],
[[1, 0],
[0, 1]],
[[0, 1],
[1, 0]]])
或者,可以為每一個標簽構建一個混淆矩陣:
>>> multilabel_confusion_matrix(y_true, y_pred, samplewise=True)
array([[[1, 0],
[1, 1]],
<BLANKLINE>
[[1, 1],
[0, 1]]])
如下例子解釋了帶有multiclass(多分類)投入的multilabel_confusion_matrix的使用:
>>> y_true = ["cat", "ant", "cat", "cat", "ant", "bird"]
>>> y_pred = ["ant", "ant", "cat", "cat", "ant", "cat"]
>>> multilabel_confusion_matrix(y_true, y_pred,
... labels=["ant", "bird", "cat"])
array([[[3, 1],
[0, 2]],
[[5, 0],
[1, 0]],
[[2, 1],
[1, 2]]])
如下是一些例子,解釋使用multilabel_confusion_matrix函數計算多標簽指標矩陣投入的,每一個類別的召回率(或者靈敏度),特異度,fall out(假正率)和 miss rate(假負率)。
計算每一個類的recall(召回率)(也被稱作真正率和靈敏度):
>>> y_true = np.array([[0, 0, 1],
... [0, 1, 0],
... [1, 1, 0]])
>>> y_pred = np.array([[0, 1, 0],
... [0, 0, 1],
... [1, 1, 0]])
>>> mcm = multilabel_confusion_matrix(y_true, y_pred)
>>> tn = mcm[:, 0, 0]
>>> tp = mcm[:, 1, 1]
>>> fn = mcm[:, 1, 0]
>>> fp = mcm[:, 0, 1]
>>> tp / (tp + fn)
array([1. , 0.5, 0. ])
計算每一個類的specificity(特異度)(也被稱作真負率)
>>> tn / (tn + fp)
array([1. , 0. , 0.5])
計算每個類的fall out(也被稱作假正率):
>>> fp / (fp + tn)
array([0. , 1. , 0.5])
計算每一個類的miss rate(也被稱作假負率):
>>> fn / (fn + tp)
array([0. , 0.5, 1. ])
3.3.2.14 Receiver operating characteristic (ROC)
roc_curve函數計算receiver operating characteristic curve, or ROC curve。引用維基百科:
“receiver operating characteristic (ROC),或簡稱ROC 曲線, 是一個圖,它解釋二分類分類器系統隨著不同閾值變化的表現。用來繪制在各種閾值的設置中,真正數占總正樣本的比率(TPR = 真正率(true positive rate))與假正數占總負樣本的比率(FPR = 假正率(false positive rate))之間的關系。TPR也被認為是敏感度,和FPR(1-敏感度或者真負率)。”
這個函數要求真二分類值和目標分數,它或者是正類別的可能性估計,置信度值,或者是二分類決策值。如下是使用roc_curve函數的小例子:
>>> import numpy as np
>>> from sklearn.metrics import roc_curve
>>> y = np.array([1, 1, 2, 2])
>>> scores = np.array([0.1, 0.4, 0.35, 0.8])
>>> fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)
>>> fpr
array([0. , 0. , 0.5, 0.5, 1. ])
>>> tpr
array([0. , 0.5, 0.5, 1. , 1. ])
>>> thresholds
array([1.8 , 0.8 , 0.4 , 0.35, 0.1 ])
下圖是上例ROC曲線:
roc_auc_score函數計算ROC曲線的面積,被稱為AUC或者AUROC。通過計算ROC曲線的面積,整個曲線的信息被總結為一個數字。詳見Wikipedia article on AUC。
>>> import numpy as np
>>> from sklearn.metrics import roc_auc_score
>>> y_true = np.array([0, 0, 1, 1])
>>> y_scores = np.array([0.1, 0.4, 0.35, 0.8])
>>> roc_auc_score(y_true, y_scores)
0.75
在多標簽分類模型中,roc_auc_curve函數可以通過在標簽上進行平均來擴展,如上例子。
諸如子集準確率,Hamming損失函數,或者F1分數相比,ROC不能給每一個標簽提供最佳的閾值。 roc_auc_score函數可以用于多類別分類模型。當前有兩個平均策略可以使用:one-vs-one算法計算ROC AUC評分的均值;one-vs-rest算法計算每一個類ROC AUC評分的均值,而不是總均值。在上面兩個例子中,預測標簽以數組形式提供,值的范圍是0到n_classes,評分與屬于某類樣本的可能性估計值相一致。OvO和OvR算法支持均勻加權(average = "macro")和prevalence(average = "weighted")。
One-vs-one Algorithm: 計算所有可能類組合的AUC的均值。[HT2001]定義一個多類別AUC指標均勻權重:
其中c是類的個數,AUC(j|k)是類別j作為正類和類別k作為負類的AUC值。總而言之,在多分類的例子中。這個算法是用"ovo"給參數multiclass賦值和"macro"給"average"賦值。
[HT2001]多分類AUC指標可以延伸到用prevalence進行加權:
其中c是類別數。該算法是用“ovo”給參數multiclass賦值,和用“weighted”給參數average賦值。“weighted”選項返回一個prevalence-weighted均值,詳見如下描述[FC2009]。
**One-vs-rest Algorithm: **計算每個類別的AUC而不是剩余的[PD2000]。該算法在功能上與多標簽的例子相同。通過設置"ovr"給參數multiclass來使用該算法。正如OvO, OvR支持兩種均值策略:“macro”[F2006]和"weighted"[F2001]。
在那些高(false positive rate)不被容忍的情況下,roc_auc_score函數的參數max_fpr可被用來把ROC曲線累加到一個給定的限制。

例子:
參見 ROC曲線 使用ROC去評估一個分類器產出的質量。 參見 帶交叉驗證的ROC曲線 使用ROC評估模型分類質量,使用交叉驗證。 參見 物種分布模型 使用ROC建模分類分布。
參考:
HT2001(1,2) Hand, D.J. and Till, R.J., (2001). A simple generalisation of the area under the ROC curve for multiple class classification problems. Machine learning, 45(2), pp.171-186.
[FC2009]Ferri, Cèsar & Hernandez-Orallo, Jose & Modroiu, R. (2009). An Experimental Comparison of Performance Measures for Classification. Pattern Recognition Letters. 30. 27-38.
[PD2000]Provost, F., Domingos, P. (2000). Well-trained PETs: Improving probability estimation trees (Section 6.2), CeDER Working Paper #IS-00-04, Stern School of Business, New York University.
[F2006]Fawcett, T., 2006. An introduction to ROC analysis. Pattern Recognition Letters, 27(8), pp. 861-874.
[F2001]Fawcett, T., 2001. Using rule sets to maximize ROC performance In Data Mining, 2001. Proceedings IEEE International Conference, pp. 131-138.
3.3.2.15 Zeor one loss
zero_one_loss函數是通過來計算0-1分類模型的損失函數()的求和或者均值。初始情況下,函數會將整個數據標準化。為了得到的求和,設置normalize=False。
在多標簽分類模型中,zero_one_loss給子集打分,嚴格按照標簽和預測值的對應關系,如果有任何錯誤,都評為0分。初始情況下,函數返回未能較好預測的子集比例。如果想得到這樣的子集計數,設置normalize = False。
如果是第i個樣本的預測值, 是與值對應的真實值,那么0-1損失函數就被如下定義:
其中*l(x)*是指標函數(indicator function)。
>>> from sklearn.metrics import zero_one_loss
>>> y_pred = [1, 2, 3, 4]
>>> y_true = [2, 2, 3, 4]
>>> zero_one_loss(y_true, y_pred)
0.25
>>> zero_one_loss(y_true, y_pred, normalize=False)
1
在帶有二分類標簽指標的多標簽例子中,第一個標簽集[0, 1]有一個錯誤:
>>> zero_one_loss(np.array([[0, 1], [1, 1]]), np.ones((2, 2)))
0.5
>>> zero_one_loss(np.array([[0, 1], [1, 1]]), np.ones((2, 2)), normalize=False)
1
例如:
參見 brier_score_loss 函數計算二分類的Brier score。引用自維基百科:
“Brier score是一個合適的評分函數,它測量概率預測的準確率。它適用于預測必須將該率分配給一組相互排斥的離散結果的任務。”
該函數返回一個實際結果與預測的可能結果的可能性之間的均方差的評分。實際結果應是1或者0(真或假),盡管實際結果的預測可能性是一個介于0和1之間的數。
brier分數損失也是一個介于0和1之間的數,評分越低(均方差很小),預測越準確。它被看作是測量一個可能性預測集合的“標尺”。
其中:N是總預測值,是實際結果的預測可能性。
以下是使用該函數的小例子:
>>> import numpy as np
>>> from sklearn.metrics import brier_score_loss
>>> y_true = np.array([0, 1, 1, 0])
>>> y_true_categorical = np.array(["spam", "ham", "ham", "spam"])
>>> y_prob = np.array([0.1, 0.9, 0.8, 0.4])
>>> y_pred = np.array([0, 1, 1, 0])
>>> brier_score_loss(y_true, y_prob)
0.055
>>> brier_score_loss(y_true, 1 - y_prob, pos_label=0)
0.055
>>> brier_score_loss(y_true_categorical, y_prob, pos_label="ham")
0.055
>>> brier_score_loss(y_true, y_prob > 0.5)
0.0
例子:
參見 Probability calibration of classifiers 是一個使用Brier score損失來校準分類器的可能性。
參考:
G. Brier, Verification of forecasts expressed in terms of probability, Monthly weather review 78.1 (1950)
3.3.3 多標簽排序指標
在多標簽的機器學習中,每個樣本可以有很多與之相關聯的真實標簽。目標是提供高的評分和較好的真實值排名。
3.3.3.1 覆蓋誤差
coverage_error函數計算必須包含在最中預測的標簽的平均數量,以預測所有真實的標簽。如果想知道高分數標簽的個數,需要可以預測不缺少任何真實標簽的平均值。因此,該指標的最佳值是真實標簽的平均值。
**注意:**這里實現的得分比在Tsoumakas et al., 2010文獻中提供的計算方式大1.這個延伸是為了解決一些例子中不包含真實標簽的退化現象。
在形式上,提供真實標簽的二分類指標矩陣,以及與每一個標簽相聯合的得分,覆蓋誤差定義如下:
其中,。給定等級定義,通過給出將被分配給所有綁定值的最大等級,y_scores中的關系被破壞。
這是使用該函數的小例子:
>>> import numpy as np
>>> from sklearn.metrics import coverage_error
>>> y_true = np.array([[1, 0, 0], [0, 0, 1]])
>>> y_score = np.array([[0.75, 0.5, 1], [1, 0.2, 0.1]])
>>> coverage_error(y_true, y_score)
2.5
3.3.3.2 標簽排名平均精確度
label_ranking_average_precision_score函數執行標簽排名平均精確度(label ranking average precision LRAP)。這個指標與average_precision_score函數相聯系,但是基于標簽排名的概念而不是精確度和召回率。
標簽排名平均精確度(LRAP)平均所有樣本,并是回答如下問題的答案:對于每一個真實標簽,多大的較高排名標簽的比例是真實的標簽?如果可以與每一個樣本相關的排名,這個指標測量值會較高。得到的評分均會大于0,最佳值是1。如果每個樣本有一個確定的相關標簽,標簽排名平均精確度等價于mean reciprocal rank。
形式上地,給定一個真實標簽的二分類指標矩陣,且與每個標簽相聯系的評分 ,平均精確度的定義如下:
其中計算集合的基數(例如,集合中元素的數量),是“范式”(它計算向量中非零元素個數)。
如下是使用該函數的小例子:
>>> import numpy as np
>>> from sklearn.metrics import label_ranking_average_precision_score
>>> y_true = np.array([[1, 0, 0], [0, 0, 1]])
>>> y_score = np.array([[0.75, 0.5, 1], [1, 0.2, 0.1]])
>>> label_ranking_average_precision_score(y_true, y_score)
0.416...
3.3.3.3 排序損失
label_ranking_loss函數用于計算排序損失,它計算樣本中標簽匹配排序不正確的個數均值。例如,真實標簽的得分比錯誤標簽的得分低,賦予排序的錯誤和正確標簽匹配個數倒數作為權重。最低的排序損失值為0。
給定一個真實標簽的二分類指標矩陣,以及與每一個標簽相聯系的評分,排序損失函數的定義如下:
其中,計算集合的基數(例如,集合中各元素的個數)以及是"范式"(它計算向量中非零元素的個數)。
如下是使用該函數的小例子:
>>> import numpy as np
>>> from sklearn.metrics import label_ranking_loss
>>> y_true = np.array([[1, 0, 0], [0, 0, 1]])
>>> y_score = np.array([[0.75, 0.5, 1], [1, 0.2, 0.1]])
>>> label_ranking_loss(y_true, y_score)
0.75...
>>> # With the following prediction, we have perfect and minimal loss
>>> y_score = np.array([[1.0, 0.1, 0.2], [0.1, 0.2, 0.9]])
>>> label_ranking_loss(y_true, y_score)
0.0
參考資料:
Tsoumakas, G., Katakis, I., & Vlahavas, I. (2010). Mining multi-label data. In Data mining and knowledge discovery handbook (pp. 667-685). Springer US.
3.3.3.4 Normalized Discounted Cumulative Gain
Discounted Cumulative Gain(DCG)和Normalized Discounted Cumulative Gain(NDCG)均是排序指數;它們對預測序列和真實得分進行比較,例如一個查詢答案的相關性。
在維基百科中對于Discounted Cumulative Gain的解釋如下:
“Discounted cumulative gain(DCG)是一個對排序質量的測量。在信息檢索中,該指標經常被用來搜索引擎算法或者相關應用的效率。在搜索引擎結果集中,使用文檔的分級相關性比例,DCG基于它在結果列表中的位置,測量文檔有用性,或者增益。增益在結果表中是由上到下的累積,根據每一個結果的增益,不考慮較低的排名。”
DCG在預測序列中,給正確標簽排序(例如查詢答案的相關性),然后乘以對數衰減,最后匯總求和。在最先的K個結果后,求和會被截斷,因此稱它為DCG@K。KDCG,或者NDCG@K是DCG除以最佳預測對應的DCG,從而該值是介于0和1之間的。通常,NDCG優先于DCG。
與排序損失作比較,NDCG能夠考慮相關性評分,而不是真實值排序。所以,所過真實值僅由一個序列構成,使用排序損失會更好;如果真實值是由實際有用性評分構成(例如,0表示不相關,1表示相關,2表示非常相關),可以選用NDCG。
對于某樣本,給定每一個標簽的連續真實值向量,其中M是返回值的個數,預測值是,它是排序函數的索引f,DCG評分是:
并且,NDCG評分是DCG評分除以從y中得到的DCG評分。
參考資料:
Wikipedia entry for Discounted Cumulative Gain Jarvelin, K., & Kekalainen, J. (2002). Cumulated gain-based evaluation of IR techniques. ACM Transactions on Information Systems (TOIS), 20(4), 422-446. Wang, Y., Wang, L., Li, Y., He, D., Chen, W., & Liu, T. Y. (2013, May). A theoretical analysis of NDCG ranking measures. In Proceedings of the 26th Annual Conference on Learning Theory (COLT 2013) McSherry, F., & Najork, M. (2008, March). Computing information retrieval performance measures efficiently in the presence of tied scores. In European conference on information retrieval (pp. 414-421). Springer, Berlin, Heidelberg.
3.3.4 回歸指標
skearn.metrics模塊實現一些損失函數,評分,并且應用函數去測度回歸標簽。其中一些已經改進,可以處理多指標案例:mean_squared_error,mean_absolute_error,explained_variance_score和r2_score。
這些函數使用關鍵參數multioutout,它指定計算方式,每一個標簽的得分或損失都會被平均。初始值是“uniform_average”,它指定給所有輸出均勻權重,計算所有輸出的平均值。如果一個ndarray的形狀(n_outputs,)被傳入,它的各條目會被解釋為權重,同時返回相應的加權平均值。如果multioutput的值指定為“raw_values”,則所有未改變的得分或損失將會被返回,并以數組形式返回(n_outputs,)。
r2_score和explained_variance_score接受一個額外的值"variance_weighted"給multioutput參數。這個選項是每一個得分的權重通過與目標變量相一致的方差得到。這個設置量化全局捕捉未縮放的方差。如果目標變量是不同的比例,那么這個分數就會將更多的重點放到解釋較高方差的變量上。對于向后兼容,r2_score的初始值是multioutput = "variance_weighted"。這個值將會在未來變為uniform_average。
3.3.4.1 可解釋的方差分數
explained_variance_score計算explained variance regression score。
如果是標簽估計值,是與之相一致(正確)的標簽輸出,并且Var是Variance,標準差的平方,則可解釋的方法計算如下:
最好的可能取值是1.0,值越低越不好。
如下是一個使用explained_variane_score函數的小例子:
>>> 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...
3.3.4.2 最大誤差
max_error函數計算最大殘差(residual error),它是捕捉預測值和真實值中最不好的誤差。在一個完美擬合的單輸出回歸模型中,max_error在訓練集上可能為0,但是在現實中基本不可能出現這種情況,這個指標表明擬合模型的誤差程度。
如果是第i個樣本的預測值,是與之相一致的真實值,最大誤差定義如下:
如下是使用max_error函數的小例子:
>>> 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
max_error不支持多輸出(multioutput)。
3.3.4.3 平均絕對誤差
mean_absolute_error函數計算mean absolute error,一個與絕對誤差損失或者-正則損失相一致的風險指標。
如果是第i個樣本的預測值,且y{i}是與之相一致的真實值,樣本的平均絕對誤差(MAE)定義如下:
如下是使用mean_absolute_error函數的小例子:
>>> 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...
3.3.4.4 均方誤差
mean_squared_error函數計算mean square error,平方(二次的)誤差或損失的期望值相一致的風險指標。
如果是第i個樣本的預測值,是與之相一致的真實值,均方誤差(MAE)對的估計值被定義如下:
如下是一個使用mean_squared_error函數的小例子:
>>> 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...
例子:
參見 Gradient Boosting regression 是一個使用均方誤差估計梯度提升回歸模型的例子。
3.3.4.5 均方誤差對數
mean_squared_log_error函數計算與平方(二次方)對數誤差或損失的期望值相一致的風險指標。
如果是第i個樣本的預測*值,是與之相一致的真實值,那么如下定義是的均方誤差對數(MSLE):
其中,表示x的自然對數。當目標呈指數倍增長的時候,最好使用這個方法,例如人口計數,跨度為一年的商品平均銷售額等。需要注意的是:這個指標懲罰低于預測值的多余于高于預測值的。
如下是使用mean_squared_error函數的小例子:
>>> 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...
3.3.4.6 中值絕對誤差
median_absolute_error是一個有趣的指標,因為它對異常值具有魯棒性。這個損失通過目標值和預測值所有絕對插值的中值來計算。
如果是第i個樣本的預測值,是與之相一致的真實值,那么中值絕對誤差(MedAE)通過對的估計如下:
median_absolute_error不支持多輸出。
如下是使用median_absolute_error函數的小例子:
>>> 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
3.3.4.7 R2 score,可決系數
r2_score函數計算coefficient of determination,通常用R2表示。
它代表方差(y的)的比例,被解釋為模型中的獨立變量。它是模型的擬合度指數,因此,可以代表模型對未知數據的預測好壞程度,通過計算可解釋方差的比例。
因此,方差取決于數據集,對比不同的數據集R2,可能不具有意義。最好的分數是1,且它可以小于零(因為模型可能會變得更糟)。一個常數模型在預測y的期望值時,不考慮輸入特征,它的R2得分可能為0.0。
如果是樣本i的預測值,那么是與所有n個樣本相一致的真實值,則R2的估計表達式為:
其中,和。
需要注意的是:r2_score計算的是未調整的R2(沒有調整y的樣本方差的偏差)。
如下是使用r2_score函數的小例子:
>>> 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...
例子:
參見 稀疏信號的套索和彈性網 是一個在sparse signals數據集上使用Lasso和Elastic Net的R2來評估的例子。
3.3.4.8 平均泊松,Gamma,和Tweedie偏差
mean_tweedie_deviance函數使用power參數(p)計算mean Tweedie deviance error。
此指標可得出回歸目標的預測期望值。
存在以下特殊情況:
當power = 0時,等價于使用mean_squared_error。 當power = 1時,等價于使用mean_poisson_deviance。 當power = 2時,等價于使用mean_gamma_deviance。
如果是第i個樣本的預測值,是與之相對應的真實值,則估計的平均Tweedie偏差誤差(D)對于參數為p如下:
Tweedie偏差是一個自由度為2-power的齊次函數。因此,power = 2時的Gamma分布表明同時縮放y_true和y_pred對偏差沒有影響。對于power=1的泊松分布偏差呈線性比例,二次地正態分布(power=0)。總而言之,在真實和預測值之間,越高的power,越少的權重賦予給極端偏差。
例如,比較兩個預測值1.0和100,它們均與真實值相差50%。
均方誤差(power=0)對于與預測值不同的第二點非常敏感,:
>>> from sklearn.metrics import mean_tweedie_deviance
>>> mean_tweedie_deviance([1.0], [1.5], power=0)
0.25
>>> mean_tweedie_deviance([100.], [150.], power=0)
2500.0
如果將power設置為1:
>>> mean_tweedie_deviance([1.0], [1.5], power=1)
0.18...
>>> mean_tweedie_deviance([100.], [150.], power=1)
18.9...
誤差在下降。最后,設置power = 2:
>>> mean_tweedie_deviance([1.0], [1.5], power=2)
0.14...
>>> mean_tweedie_deviance([100.], [150.], power=2)
0.14...
可以得到相同的誤差。當power = 2時,偏差只對相對誤差敏感。
3.3.5 聚類指標
sklearn.metrics模塊實行幾種損失,評分和實用功能。詳見 Clustering performance evaluation 部分的聚類示例,以及 Biclustering evaluation 的雙集群。
3.3.6 Dummy 評估器
當是有監督機器學習時,一個簡單的方法是用某個估計器的結果與經驗相比較。DummyClassifier實現一些簡單的分類策略:
參數stratified通過考慮訓練集類別的分布,產生隨機預測值。 參數most_frequent 是預測訓練集中頻率最高的標簽。 參數prior 通過預測可以使類別最大化的類(如most_frequent )和predict_proba返回優先類。 參數uniform 產生均勻隨機的預測值。 參數constant預測的是常量標簽(由用戶定義)。當正類是少數類時,這種方法的主要動機是F1-scoring。
需要注意的是:所有這些策略,predict方法完全忽略輸入數據!
為了解釋DummyClassifier,首先需要創建一個不平衡數據集:
>>> from sklearn.datasets import load_iris
>>> from sklearn.model_selection import train_test_split
>>> X, y = load_iris(return_X_y=True)
>>> y[y != 1] = -1
>>> X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
下一步,比較SVC和most_frequent的準確率:
>>> from sklearn.dummy import DummyClassifier
>>> from sklearn.svm import SVC
>>> clf = SVC(kernel='linear', C=1).fit(X_train, y_train)
>>> clf.score(X_test, y_test)
0.63...
>>> clf = DummyClassifier(strategy='most_frequent', random_state=0)
>>> clf.fit(X_train, y_train)
DummyClassifier(random_state=0, strategy='most_frequent')
>>> clf.score(X_test, y_test)
0.57...
SVC沒有dummy 分類器做的好。現在,改變SVC的核函數:
>>> clf = SVC(kernel='rbf', C=1).fit(X_train, y_train)
>>> clf.score(X_test, y_test)
0.94...
可以看到準確率提升到接近100%。如果不是因為消耗CPU成本太高,交叉驗證的策略值得推薦使用以找到更高的準確率估計。詳見 交叉驗證:評估模型表現 部分。 如果想優化參數空間,強烈推薦使用合適的方法;詳見調整估計器的超參數 部分。
整體上,當一個分類器的結果太接近隨機選取的時候,可能意味著哪里出了問題:也許是特征選取的不合適,超參數選取的不合適,分類器不能很好的作用在不均衡樣本上,等...
DummyRegressor 也可以執行回歸的四個簡單經驗法則:
mean 預測的是訓練目標的均值。 median 預測的是訓練目標的中值。 quantile 預測的是由用戶提供分位數的訓練目標。 contant 預測的是由用戶提供的某個常量目標。
在所有這些策略中,predict 方法完全忽略投入數據。