最近在使用sklearn作分類時候,用到metrics中的評價函數,其中有一個很是重要的評價函數是F1值,(關於這個值的原理自行google或者百度)函數
在sklearn中的計算F1的函數爲 f1_score ,其中有一個參數average用來控制F1的計算方式,今天咱們就說說當參數取micro和macro時候的區別測試
一、F1公式描述:google
F1-score: 2*(P*R)/(P+R)spa
二、 f1_score中關於參數average的用法描述:code
'micro'
:Calculate metrics globally by counting the total true positives, false negatives and false positives.blog
'micro':經過先計算整體的TP,FN和FP的數量,再計算F1ci
'macro'
:Calculate metrics for each label, and find their unweighted mean. This does not take label imbalance into account.it
'macro':分佈計算每一個類別的F1,而後作平均(各種別F1的權重相同)io
三、初步理解table
經過參數用法描述,想必你們從字面層次也能理解他是什麼意思,micro就是先計算全部的TP,FN , FP的個數後,而後再利上文提到公式計算出F1
macro其實就是先計算出每一個類別的F1值,而後去平均,好比下面多分類問題,總共有1,2,3,4這4個類別,咱們能夠先算出1的F1,2的F1,3的F1,4的F1,而後再取平均(F1+F2+F3+4)/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]
四、進一步理解
咱們仍是以上面的例子爲例說明sklearn中是如何計算micro 和 macro的:
micro計算原理
首先計算總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當作正類,其餘看出負類
同理咱們能夠再計算FN的數量
1類 | 2類 | 3類 | 4類 | 總數 | |
TP | 3 | 2 | 2 | 1 | 8 |
FP | 0 | 0 | 3 | 1 | 4 |
FN | 2 | 2 | 1 | 1 | 6 |
因此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
計算macro
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()) print(f1_score(y_true,y_pred,labels=[1,2,3,4],average='macro')) #>>>各種單獨F1: [ 0.75 0.66666667 0.5 0.5 ] #>>>各種F1取平均: 0.604166666667 #>>>0.604166666667
若有裝載,請註明出處,謝謝