二分類使用Accuracy和F1-score,多分類使用Accuracy和宏F1。
最近在使用sklearn做分類時候,用到metrics中的評價函數,其中有一個非常重要的評價函數是F1值,
在sklearn中的計算F1的函數為 f1_score ,其中有一個參數average用來控制F1的計算方式,今天我們就說說當參數取micro和macro時候的區別
1、准確率,查准率,查全率,F1值:
對於二分類問題,可將樣例根據其真實類別和分類器預測類別划分為:
真正例(True Positive,TP):真實類別為正例,預測類別為正例。
假正例(False Positive,FP):真實類別為負例,預測類別為正例。
假負例(False Negative,FN):真實類別為正例,預測類別為負例。
真負例(True Negative,TN):真實類別為負例,預測類別為負例。
然后可以構建混淆矩陣(Confusion Matrix)如下表所示。
准確率(Accuracy,Acc):
精確率,又稱查准率(Precision,P):
召回率,又稱查全率(Recall,R):
F1值:
F1的一般形式:
#二分類
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score y_true = [0, 1, 1, 0, 1, 0] y_pred = [1, 1, 1, 0, 0, 1] Accuracy = accuracy_score(y_true, y_pred) #注意沒有average參數
Precision = precision_score(y_true, y_pred, average='binary') recall = recall_score(y_true, y_pred, average='binary') f1score = f1_score(y_true, y_pred, average='binary')
如果只有一個二分類混淆矩陣,那么用以上的指標就可以進行評價,沒有什么爭議,但是當我們在n個二分類混淆矩陣上要綜合考察評價指標的時候就會用到宏平均和微平均。
2、F1_score中關於參數average的用法描述和理解:
'micro':Calculate metrics globally by counting the total true positives, false negatives and false positives. 'micro':通過先計算總體的TP,FN和FP的數量,再計算F1 'macro':Calculate metrics for each label, and find their unweighted mean. This does not take label imbalance into account. 'macro':分布計算每個類別的F1,然后做平均(各類別F1的權重相同)
通過參數用法描述,想必大家從字面層次也能理解他是什么意思,micro就是先計算所有的TP,FN , FP的個數后,然后再利上文提到公式計算出F1
macro其實就是先計算出每個類別的F1值,然后去平均,比如下面多分類問題,總共有1,2,3,4這4個類別,我們可以先算出1的F1,2的F1,3的F1,4的F1,然后再取平均(F1+F2+F3+F4)/4
y_true = [1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4] y_pred = [1, 1, 1, 0, 0, 2, 2, 3, 3, 3, 4, 3, 4, 3]
3、微平均(Micro-averaging)
首先計算總TP值,這個很好就算,就是數一數上面有多少個類別被正確分類,比如1這個類別有3個分正確,2有2個,3有2個,4有1個,那TP=3+2+2+1=8
其次計算總FP值,簡單的說就是不屬於某一個類別的元數被分到這個類別的數量,比如上面不屬於4類的元素被分到4的有1個
如果還比較迷糊,我們在計算時候可以把4保留,其他全改成0,就可以更加清楚地看出4類別下面的FP數量了,其實這個原理就是 One-vs-All (OvA),把4看成正類,其他看出負類
所以micro的 精確度P 為 TP/(TP+FP)=8/(8+4)=0.666 召回率R TP/(TP+FN)=8/(8+6)=0.571 所以F1-micro的值為:0.6153
可以用sklearn來核對,把average設置成micro
y_true = [1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4] y_pred = [1, 1, 1, 0, 0, 2, 2, 3, 3, 3, 4, 3, 4, 3] print(f1_score(y_true,y_pred,labels=[1,2,3,4],average='micro')) #>>> 0.615384615385
4、宏平均(Macro-averaging)
先在各混淆矩陣上分別計算各類的查准率,查全率和F1,然后再計算平均值。 這樣就得到“宏查准率”(macro-P)、“宏查全率”(macro-R)、“宏F1”(macro-F1) 正常最終求得就是“宏F1”
宏查准率
宏查全率
宏F1 (我們要求的就是宏F1,每個類別的F1值的平均)
macro先要計算每一個類的F1,有了上面那個表,計算各個類的F1就很容易了,比如1類,它的精確率P=3/(3+0)=1 召回率R=3/(3+2)=0.6 F1=2*(1*0.5)/1.5=0.75
可以sklearn,來計算核對,把average設置成macro
#average=None,取出每一類的P,R,F1值
p_class, r_class, f_class, support_micro=precision_recall_fscore_support( y_true=y_true, y_pred=y_pred, labels=[1, 2, 3, 4], average=None) print('各類單獨F1:',f_class) print('各類F1取平均:',f_class.mean()) #>>>各類單獨F1: [ 0.75 0.66666667 0.5 0.5 ] #>>>各類F1取平均: 0.604166666667
#注意這里,輸出《宏F》
print(f1_score(y_true,y_pred,labels=[1,2,3,4],average='macro')) #>>>0.604166666667
5、sklearn實現
注意:分類報告最后一行為加權平均值。0.64就是加權平均F1-score
https://blog.csdn.net/baidu_38945893/article/details/82141975
f1_score (y_true, y_pred, labels=None, pos_label=1, average=’binary’, sample_weight=None)
關鍵參數是 average: string, [None, ‘binary’ (default), ‘micro’, ‘macro’, ‘weighted’, ‘samples’],This parameter is required for multiclass/multilabel targets.
① None:返回每一類各自的f1_score,得到一個array。
② 'binary': 只對二分類問題有效,返回由pos_label指定的類的f1_score。
Only report results for the class specified by pos_label. This is applicable only if targets (y_{true,pred}) are binary.
③ 'micro': 設置average='micro'時,Precision = Recall = F1_score = Accuracy。
注意:這是正確的, 微查准率、微查全率、微F1都等於Accuracy。
下例中為什么不等於?因為預測中有幾個0,出現錯誤了。
Note that for “micro”-averaging in a multiclass setting with all labels included will produce equal precision, recall and F_beta.
Calculate metrics globally by counting the total true positives, false negatives and false positives.
④ 'macro': 對每一類別的f1_score進行簡單算術平均(unweighted mean), with assumption that all classes are equally important。
Calculate metrics for each label, and find their unweighted mean. This does not take label imbalance into account.
⑤ 'weighted': 對每一類別的f1_score進行加權平均,權重為各類別數在y_true中所占比例。
Calculate metrics for each label, and find their average, weighted by support (the number of true instances for each label). This alters ‘macro’ to account for label imbalance; it can result in an F-score that is not between precision and recall.
⑥ 'samples': Calculate metrics for each instance, and find their average (only meaningful for multilabel classification where this differs from accuracy_score)
from sklearn import metrics y_test = [1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4] y_predict = [1, 1, 1, 3, 3, 2, 2, 3, 3, 3, 4, 3, 4, 3] print('准確率:', metrics.accuracy_score(y_test, y_predict)) #預測准確率輸出
print('宏平均精確率:',metrics.precision_score(y_test,y_predict,average='macro')) #預測宏平均精確率輸出
print('微平均精確率:', metrics.precision_score(y_test, y_predict, average='micro')) #預測微平均精確率輸出
print('加權平均精確率:', metrics.precision_score(y_test, y_predict, average='weighted')) #預測加權平均精確率輸出
print('宏平均召回率:',metrics.recall_score(y_test,y_predict,average='macro'))#預測宏平均召回率輸出
print('微平均召回率:',metrics.recall_score(y_test,y_predict,average='micro'))#預測微平均召回率輸出
print('加權平均召回率:',metrics.recall_score(y_test,y_predict,average='micro'))#預測加權平均召回率輸出
print('宏平均F1-score:',metrics.f1_score(y_test,y_predict,labels=[1,2,3,4],average='macro'))#預測宏平均f1-score輸出
print('微平均F1-score:',metrics.f1_score(y_test,y_predict,labels=[1,2,3,4],average='micro'))#預測微平均f1-score輸出
print('加權平均F1-score:',metrics.f1_score(y_test,y_predict,labels=[1,2,3,4],average='weighted'))#預測加權平均f1-score輸出
print('混淆矩陣輸出:\n',metrics.confusion_matrix(y_test,y_predict,labels=[1,2,3,4]))#混淆矩陣輸出
print('分類報告:\n', metrics.classification_report(y_test, y_predict,labels=[1,2,3,4]))#分類報告輸出
輸出: 准確率: 0.571428571429 宏平均精確率: 0.696428571429 微平均精確率: 0.571428571429 加權平均精確率: 0.775510204082 宏平均召回率: 0.566666666667 微平均召回率: 0.571428571429 加權平均召回率: 0.571428571429 宏平均F1-score: 0.579166666667 微平均F1-score: 0.571428571429 加權平均F1-score: 0.615476190476 混淆矩陣輸出: [[3 0 2 0] [0 2 2 0] [0 0 2 1] [0 0 1 1]] 分類報告: precision recall f1-score support 1 1.00 0.60 0.75 5
2 1.00 0.50 0.67 4
3 0.29 0.67 0.40 3
4 0.50 0.50 0.50 2 avg / total 0.78 0.57 0.62 14