はじめに
一射絶命、nikkieです。
ツルネを見終えました(沙絵ちゃんかわいい)
scikit-learnの実装を眺めていて、「各種評価指標を一発で出せる関数あるじゃん!」と気付きました。
この感動を共有していきます。
目次
- はじめに
- 目次
- sklearn.metrics.precision_recall_fscore_support
- Re: scikit-learnのf1_scoreのaverage引数に指定するmicroやmacroやsamplesって、なに?
- 終わりに
- P.S. zero_division引数もあります
- P.S. その2 各種評価指標はprecision_recall_fscore_supportを呼び出す実装です!
sklearn.metrics.precision_recall_fscore_support
Compute precision, recall, F-measure and support for each class.
- F-measureですが、要はF1スコアです
- F1スコアは実はF-betaスコアのbeta=1のケースです。
precision_recall_fscore_support
関数にはbeta
引数があり、デフォルト値は1.0
です
- F1スコアは実はF-betaスコアのbeta=1のケースです。
- supportとは、
y_true
の中で各クラスに属するサンプルの数です1
4要素のタプルを返します。
(precision, recall, f1_score, support)
Re: scikit-learnのf1_scoreのaverage引数に指定するmicroやmacroやsamplesって、なに?
average引数を使いこなすための素振り記事の内容は、precision_recall_fscore_support
を使うと一瞬でした!
今回の動作環境
- Python 3.11.4
- scikit-learn 1.3.0
joblib==1.3.1 numpy==1.25.1 scikit-learn==1.3.0 scipy==1.11.1 threadpoolctl==3.2.0
指標算出の前準備
MultiLabelBinarizer
で処理した後のラベルを扱っていきます。
>>> import numpy as np >>> from sklearn.metrics import precision_recall_fscore_support >>> y_true = np.array([[1,1,0], [1,0,0], [1,1,1], [0,1,1], [0,0,1]]) >>> y_pred = np.array([[1,0,1], [0,1,0], [1,0,1], [0,0,1], [0,0,1]])
クラスごとに算出(average=None
)
average
引数のデフォルト値はNone
で、クラスごとに各指標を算出します。
>>> precision_recall_fscore_support(y_true, y_pred) (array([1. , 0. , 0.75]), array([0.66666667, 0. , 1. ]), array([0.8 , 0. , 0.85714286]), array([3, 3, 3]))
3つのクラスについてインデックス+1で表すと
- クラス1
- precision 1
- recall 0.66666667
- F1 score 0.8
- クラス2
- precision 0
- recall 0
- F1 score 0
- クラス3
- precision 0.75
- recall 1
- F1 score 0.85714286
クラスごとの混同行列を書いて確認した結果と一致します。
一発で求まるなんて!
サンプルごとに算出(転置してaverage=None
)
y_true
とy_pred
を両方転置して、average
引数にNone
を指定したらサンプルごとに算出できます。
>>> precision_recall_fscore_support(y_true.T, y_pred.T) (array([0.5, 0. , 1. , 1. , 1. ]), array([0.5 , 0. , 0.66666667, 0.5 , 1. ]), array([0.5 , 0. , 0.8 , 0.66666667, 1. ]), array([2, 1, 3, 2, 1]))
5つのサンプルについてインデックス+1で表すと
- サンプル1
- precision 0.5
- recall 0.5
- F1 score 0.5
- サンプル2
- precision 0
- recall 0
- F1 score 0
- サンプル3
- precision 1
- recall 0.66666667
- F1 score 0.8
- サンプル4
- precision 1
- recall 0.5
- F1 score 0.66666667
- サンプル5
- precision 1
- recall 1
- F1 score 1
サンプルごとの混同行列を書いて確認した結果と一致しますね!
average="micro"
>>> precision_recall_fscore_support(y_true, y_pred, average="micro") (0.7142857142857143, 0.5555555555555556, 0.6250000000000001, None)
average
引数の値がNone
でないとき、supportはNone
になります2。
average="macro"
>>> precision_recall_fscore_support(y_true, y_pred, average="macro") (0.5833333333333334, 0.5555555555555555, 0.5523809523809523, None)
average="samples"
>>> precision_recall_fscore_support(y_true, y_pred, average="samples") (0.7, 0.5333333333333333, 0.5933333333333334, None)
終わりに
sklearn.metrics.precision_recall_fscore_support
でprecision, recall, f1_scoreの3つを一度に求められることを共有しました。
y_true
とy_pred
からタプル(precision, recall, f1_score, support)
を得られますaverage
引数を変えて、precision, recall, f1_scoreを一通り求められます
scikit-learnを初めて触るときはtoo muchな印象ですが、慣れてきた今となっては初手でprecision_recall_fscore_support
を使いたいなと思いました。コスパ最高じゃん!
なお、各種評価指標については『評価指標入門』がオススメです3。私も勉強中〜
P.S. zero_division
引数もあります
zero_division
引数はF1 scoreに限らず、precisionにもrecallにも提供されます。
これらを一発で出せるprecision_recall_fscore_support
もzero_division
引数を持ちます!
P.S. その2 各種評価指標はprecision_recall_fscore_support
を呼び出す実装です!
- precision_score
- recall_score
- f1_score
- fbeta_scoreを
beta=1
で呼び出します - fbeta_scoreが
precision_recall_fscore_support
を呼び出します
- fbeta_scoreを
なお、precision_recall_fscore_support
の返り値のうち使わない評価指標は_
を並べたアンパック代入で受けることで捨てています。