混同行列とは?
2値分類(分類するクラスは陽性・陰性と呼ばれる)において予測データと実際のデータを見比べて、以下の4つのグループで分類する行列です。
- TP(真陽性):予測=陽性、結果=陽性
- TN(真陰性):予測=陰性、結果=陰性
- FP(偽陽性):予測=陽性、結果=陰性
- FN(偽陽性):予測=陰性、結果=陽性
例) 試合に勝った時を陽性、負けた時を陰性とするときの混合行列
評価指標解説
正解率(accuracy)
概要
以下の式により予測の正答率を示す。例) 以下の表なら、
勝つと予測 | 負けると予測 | |
---|---|---|
実際は勝った | TP = 4 | FN = 3 |
実際は負けた | FP = 1 | TN = 2 |
問題点
- データに偏りがある場合に向いていないという問題があります。
- 例えば、正常と異常の2クラスの予測をするが異常を正常と誤検知して欲しくないとき、混同行列が次のようになるとする。このとき、異常を全く検知していないが正解率は約99.1%と極めて高い。
異常と予測 | 正常と予測 | |
---|---|---|
実際は異常 | TP = 1 | FN = 9 |
実際は正常 | FP = 0 | TN = 990 |
再現率(recall)
- 実際に陽性データのうち、どれぐらい陽性と予測できたかを示す。
- 先ほどの異常検知の場合ならとなるので、モデルが十分でないことが評価できる。
異常と予測 | 正常と予測 | |
---|---|---|
実際は異常 | TP = 1 | FN = 9 |
実際は正常 | FP = 0 | TN = 990 |
適合率(precision)
- 陽性と予測したうち、どれぐらいが実際に陽性かを示す。
- 再現率とはトレードオフの関係。
- 例) 以下の表なら、。
勝つと予測 | 負けると予測 | |
---|---|---|
実際は勝った | TP = 4 | FN = 3 |
実際は負けた | FP = 1 | TN = 2 |
Pythonでの実装
環境構築
- sklearnライブラリをインポートすることでこれらの評価指標が簡単に計算できる。
- 今回はirisデータのうち、ラベル=0のデータを陽性、ラベル=1のデータを陰性として評価を行う。
- 以下condaを使った環境構築。
conda create -n 環境名 python=3.10.6 conda activate 環境名 conda install scikit-learn
ソースコード
- 今回はモデル構築・データ分類などには注目しないので説明は省略。
- 各指標の評価関数は次の通りで引数は真値、予測値の順(逆にすると行列も転置する)。
指標 | 関数名 |
---|---|
混同行列 | confusion_matrix |
正解率 | accuracy_score |
適合率 | precision_score |
再現率 | recall_score |
from sklearn import datasets from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score # irisデータを読み込み iris = datasets.load_iris() # 2つのクラスに絞る(本来は3クラスあるため) X = iris.data[iris.target != 0] y = iris.target[iris.target != 0] # 訓練データ・テストデータに分割 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.5, random_state=0) # RandomForestで学習 model = RandomForestClassifier(random_state=0) model.fit(X_train, y_train) # テストデータから予測 y_pred = model.predict(X_test) # 混合行列を表示 conf = confusion_matrix(y_test, y_pred); print(f'混合行列\n{conf}\n'); # 正解率(accuracy)、適合率(precision)、再現率(recall)、F値(F1-score) print(f'正解率 = {accuracy_score(y_test, y_pred)}') print(f'適合率 = {precision_score(y_test, y_pred)}') print(f'再現率 = {recall_score(y_test, y_pred)}')
結果の確認
出力
混合行列 [[22 4] [ 1 23]] 正解率 = 0.9 適合率 = 0.9565217391304348 再現率 = 0.8461538461538461 F値 = 0.8979591836734695
手計算で結果確認
まずは、混合行列を示すと次のようになるTP = 22 | FN = 4 |
---|---|
FP = 1 | TN = 23 |
各指標を計算すると次の通りで出力結果と一致したことが確認できる。