(原創)sklearn中 F1-micro 與 F1-macro區別和計算原理

       最近在使用sklearn作分類時候,用到metrics中的評價函數,其中有一個很是重要的評價函數是F1值,(關於這個值的原理自行google或者百度)函數

       在sklearn中的計算F1的函數爲 f1_score ,其中有一個參數average用來控制F1的計算方式,今天咱們就說說當參數取micromacro時候的區別測試

 

一、F1公式描述:google

  F1-score:    2*(P*R)/(P+R)spa


 

                準確率(P): TP/ (TP+FP) 
                召回率(R): TP(TP + FN)
 
對於數據測試結果有下面4種狀況:
真陽性(TP): 預測爲正, 實際也爲正
假陽性(FP): 預測爲正, 實際爲負
假陰性(FN): 預測爲負,實際爲正
真陰性(TN): 預測爲負, 實際也爲負

二、 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

 若有裝載,請註明出處,謝謝

相關文章
相關標籤/搜索