パープルハット

※当サイトではGoogleアドセンス広告を利用しています

モデル評価指標(混同行列、正解率、再現率、適合率)



混同行列とは?

2値分類(分類するクラスは陽性・陰性と呼ばれる)において予測データと実際のデータを見比べて、以下の4つのグループで分類する行列です。

  • TP(真陽性):予測=陽性、結果=陽性
  • TN(真陰性):予測=陰性、結果=陰性
  • FP(偽陽性):予測=陽性、結果=陰性
  • FN(偽陽性):予測=陰性、結果=陽性


例) 試合に勝った時を陽性、負けた時を陰性とするときの混合行列
混同行列の例



評価指標解説

正解率(accuracy)

概要

以下の式により予測の正答率を示す。
(正解率) = \frac{TP+TN}{TP+TN+FP+FN}

例) 以下の表なら、(正解率) = \frac{4+2}{4+2+1+3}=0.6

勝つと予測 負けると予測
実際は勝った TP = 4 FN = 3
実際は負けた FP = 1 TN = 2


問題点

  • データに偏りがある場合に向いていないという問題があります。
  • 例えば、正常と異常の2クラスの予測をするが異常を正常と誤検知して欲しくないとき、混同行列が次のようになるとする。このとき、異常を全く検知していないが正解率は約99.1%と極めて高い。
異常と予測 正常と予測
実際は異常 TP = 1 FN = 9
実際は正常 FP = 0 TN = 990



再現率(recall)

(再現率) = \frac{TP}{TP+FN}

  • 実際に陽性データのうち、どれぐらい陽性と予測できたかを示す。
  • 先ほどの異常検知の場合なら(再現率) = \frac{1}{1+9}=0.1となるので、モデルが十分でないことが評価できる。
異常と予測 正常と予測
実際は異常 TP = 1 FN = 9
実際は正常 FP = 0 TN = 990



適合率(precision)

(適合率) = \frac{TP}{TP+FP}

  • 陽性と予測したうち、どれぐらいが実際に陽性かを示す。
  • 再現率とはトレードオフの関係。
  • 例) 以下の表なら、(適合率) = \frac{4}{4+1}=0.8
勝つと予測 負けると予測
実際は勝った 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


各指標を計算すると次の通りで出力結果と一致したことが確認できる。
(正解率) = \frac{TP+TN}{TP+TN+FP+FN} = \frac{22+23}{22+23+1+4} = 0.9
(再現率) = \frac{TP}{TP+FN} = \frac{22}{22+4} = 0.841615...
(適合率) = \frac{TP}{TP+FP} = \frac{22}{22 + 1} = 0.956521...