mean-F1とmacro-F1とmicro-F1で手を動かす
『 #Kaggleで勝つデータ分析の技術 』2.3.5
https://github.com/ghmagazine/kagglebook/blob/3d8509d1c1b41a765e3f4744ba1fb226188e2b15/ch02/ch02-01-metrics.py
f1_scoreのaverageがsamples/macro(weighted)/microで分からなくなったらここを見る
理論 F1のmean/macro/micro
Python 3.10.2、scikit-learn 1.1.2
code:practice.py
>> true_labels = 1,2],1,1,2,3,2,3,[3
>> pred_labels = 1,3],2,1,3,3,[3
>> from sklearn.preprocessing import MultiLabelBinarizer
>> mlb = MultiLabelBinarizer() # わかりやすい形でラベルを扱い、コード中で扱う形式に変換する
>> y_true = mlb.fit_transform(true_labels)
>> y_pred = mlb.transform(pred_labels)
>> y_true
array([1, 1, 0,
1, 0, 0,
1, 1, 1,
0, 1, 1,
0, 0, 1])
>> y_pred
array([1, 0, 1,
0, 1, 0,
1, 0, 1,
0, 0, 1,
0, 0, 1])
>> import numpy as np
>> # mean_f1は例単位で計算したF1-scoreの平均値(例単位なのでaverage="samples")
>> mean_f1 = np.mean([f1_score(y_truei, :, y_predi, :) for i in range(len(y_true))])
>> mean_f1
0.5933333333333334
>> f1_score(y_true, y_pred, average="samples")
0.5933333333333334
>> # macro_f1はラベルの**クラス単位**で計算したF1-scoreの平均値
>> n_class = 3
>> macro_f1 = np.mean([f1_score(y_true:, c, y_pred:, c) for c in range(n_class)])
>> macro_f1
0.5523809523809523
>> f1_score(y_true, y_pred, average="macro")
0.5523809523809523
>> y_true.reshape(-1) # 1次のarrayにする(ネストをなくしフラットにする)
array(1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1)
>> y_pred.reshape(-1)
array(1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1)
>> # ネストをなくしたので、例×クラスの各要素についてtrueとpredを比べてTP/TN/FP/FNのどこに該当するかを数え、1つのF1-scoreを求める
>> micro_f1 = f1_score(y_true.reshape(-1), y_pred.reshape(-1))
>> micro_f1
0.6250000000000001
>> f1_score(y_true, y_pred, average="micro")
0.6250000000000001