Warning: Undefined variable $position in /home/pystyles/pystyle.info/public_html/wp/wp-content/themes/lionblog/functions.php on line 4897

機械学習 – 精度、適合率、再現率、F値について

機械学習 – 精度、適合率、再現率、F値について

概要

精度 (Accuracy)、適合率 (Precision)、再現率 (Recall)、F値 (F-Measure) について解説します。

Advertisement

指標の一覧

評価指標 関数
正答率、精度 (Accuracy) sklearn.metrics.accuracy_score()
誤答率 (Error Rate) 1 – sklearn.metrics.accuracy_score()
適合率 (Precision) sklearn.metrics.precision_score()
再現率 (Recall) sklearn.metrics.recall_score()
F値 (F-Measure) sklearn.metrics.f1_score()

2クラス分類の場合

正答率、精度 (Accuracy)

全サンプルのうち、分類したクラスと正解クラスが一致する数の割合を正答率または精度 (accuracy) といいます。

$$ \text{Accuracy} = \frac{TP + TN}{TP + FP + TN + FN} $$

精度は scikit-learn の sklearn.metrics.accuracy_score() で計算できます。

In [1]:
import numpy as np
from sklearn.metrics import accuracy_score, confusion_matrix

y_true = np.array([1, 0, 1, 1, 0, 1])
y_pred = np.array([0, 0, 1, 1, 0, 0])

# scikit-learn で計算する場合
accuracy = accuracy_score(y_true, y_pred)
print(accuracy)

# 混同行列から計算する場合
C = confusion_matrix(y_true, y_pred)
TN, FP, FN, TP = C.flat
accuracy = (TP + TN) / (TP + FP + FN + TP)
print(accuracy)
0.6666666666666666
0.6666666666666666

誤答率 (Error Rate)

全サンプルのうち、分類したクラスと正解クラスが一致しない数の割合を誤答率 (Error Rate) といいます。正答率とは以下の関係があります。

$$ \text{ErrorRate} = 1 – \text{Accuracy} $$
Advertisement

適合率 (Precision)

positive と分類したサンプルのうち、正解した割合を適合率 (Precision) といいます。

$$ \text{Precision} = \frac{TP}{TP + FP} $$

適合率は scikit-learn の sklearn.metrics.precision_score() で計算できます。

In [2]:
import numpy as np
from sklearn.metrics import precision_score

y_true = np.array([0, 1, 0, 0, 1, 0])
y_pred = np.array([0, 1, 0, 1, 1, 0])

# scikit-learn で計算する場合
precision = precision_score(y_true, y_pred)
print(precision)

# 混同行列から計算する場合
C = confusion_matrix(y_true, y_pred)
TN, FP, FN, TP = C.flat
precision = TP / (TP + FP)
print(precision)
0.6666666666666666
0.6666666666666666

再現率 (Recall)

正解ラベルが positive のサンプルのうち、分類ラベルも positive となった割合を再現率 (Recall)感度 (Sensitivity) または真陽性率 (True Positive Rate, TTR) といいます。

$$ \text{Recall} = \frac{TP}{TP + FN} $$

再現率は scikit-learn の sklearn.metrics.recall_score() で計算できます。

In [3]:
import numpy as np
from sklearn.metrics import recall_score

y_true = np.array([0, 1, 0, 0, 1, 0])
y_pred = np.array([0, 1, 0, 1, 1, 0])

# scikit-learn で計算する場合
recall = recall_score(y_true, y_pred)
print(recall)

# 混同行列から計算する場合
C = confusion_matrix(y_true, y_pred)
TN, FP, FN, TP = C.flat
recall = TP / (TP + FN)
print(recall)
1.0
1.0

F値 (F-Measure)

次のように計算される値を F値 (F-Measure) といいます。

$$ \begin{aligned} \text{F1} &= \frac{2}{\frac{1}{\text{Precision}} + \frac{1}{\text{Recall}}} \\ &= \frac{2 (\text{Precision} \times \text{Recall})}{\text{Precision} + \text{Recall}} \\ &= \frac{2 TP}{2 TP + FN + FP} \end{aligned} $$

scikit-learn の sklearn.metrics.f1_score() で計算できます。

In [4]:
import numpy as np
from sklearn.metrics import f1_score

y_true = np.array([0, 1, 0, 0, 1, 0])
y_pred = np.array([0, 1, 0, 1, 1, 0])

# scikit-learn で計算する場合
f1 = f1_score(y_true, y_pred)
print(f1)

# 式に従って計算する場合
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1 = 2 * precision * recall / (precision + recall)
print(f1)

# 混同行列から計算する場合
C = confusion_matrix(y_true, y_pred)
TN, FP, FN, TP = C.flat
f1 = 2 * TP / (2 * TP + FN + FP)
print(f1)
0.8
0.8
0.8

多クラス分類の場合

$m$ クラス分類問題の混同合行列を $C$ とします。

Advertisement

正答率、精度 (Accuracy)

混同行列の対角成分は各クラスの正解した数を表しているので、精度は以下で計算します。

$$ \text{Accuracy} = \frac{正解したサンプル数}{サンプル数} = \frac{\sum_{i = 1}^m C_{ii}}{\sum_{i = 1}^m \sum_{j = 1}^m C_{ij}} $$

In [5]:
import numpy as np
from sklearn.metrics import accuracy_score, confusion_matrix

y_true = np.array([1, 2, 1, 1, 2, 1])
y_pred = np.array([0, 0, 1, 2, 2, 0])

# scikit-learn で計算する場合
accuracy = accuracy_score(y_true, y_pred)
print(accuracy)

# 混同行列から計算する場合
C = confusion_matrix(y_true, y_pred)
accuracy = C.trace() / C.sum()  # 対角成分の和 / すべての成分の和
print(accuracy)
0.3333333333333333
0.3333333333333333

マクロ平均 (macro mean)

まず各クラスごとに適合率 (Precision)、再現率 (Recall) 及びF値 (F-measure) を計算します。

$$ \text{Precision}_i = \frac{TP_i}{TP_i + FP_i} = \frac{C_{ii}}{\sum_{j = 1}^m C_{ji}} $$

$$ \text{Recall}_i = \frac{TP_i}{TP_i + FN_i} = \frac{C_{ii}}{\sum_{j = 1}^m C_{ij}} $$

$$ \begin{aligned} \text{F1}_i &= \frac{2}{\frac{1}{\text{Precision}\ _i} + \frac{1}{\text{Recall}\ _i}} \\ &= \frac{2 (\text{Precision}_i \times \text{Recall}_i)}{\text{Precision}_i + \text{Recall}_i} \end{aligned} $$

各指標の全クラスの平均をとったものをマクロ平均 (macro mean) といいます。

$$ \text{Precision} = \frac{1}{m} \sum_{i = 1}^m \text{Precision}_i $$$$ \text{Recall} = \frac{1}{m} \sum_{i = 1}^m \text{Recall}_i $$$$ \text{F1} = \frac{1}{m} \sum_{i = 1}^m \text{F1}_i $$
In [6]:
import numpy as np
from sklearn.metrics import precision_score

y_true = np.array([0, 2, 0, 0, 1, 0])
y_pred = np.array([0, 1, 0, 1, 2, 0])

precision = precision_score(y_true, y_pred, average="macro")
print(precision)

recall = recall_score(y_true, y_pred, average="macro")
print(recall)

f1 = f1_score(y_true, y_pred, average="macro")
print(f1)
0.3333333333333333
0.25
0.2857142857142857

マイクロ平均 (micro mean)

クラスごとではなく、混合行列全体で TP、FP、FN を算出して、適合率、再現率、F値を計算する方法をマイクロ平均といいます。 TPは混合行列の対角成分の合計で、FP、FN は混合行列の対角成分以外の合計になります。

$TP = \sum_{i = 1}^m C_{ii}, FP = FN = \sum_{i \ne j} C_{ij}$ に注意すると、

$$ \text{Precision} = \frac{TP}{TP + FP} = \frac{\sum_{i = 1}^m C_{ii}}{\sum_{i = 1}^m \sum_{j = 1}^m C_{ij}} $$$$ \text{Recall} = \frac{TP}{TP + FN} = \frac{\sum_{i = 1}^m C_{ii}}{\sum_{i = 1}^m \sum_{j = 1}^m C_{ij}} $$$$ \text{F1} = \frac{2 TP}{2 TP + FN + FP} = \frac{TP}{TP + FP} $$

であり、精度、適合率、再現率、F値はすべて精度と同じ値になります。

In [7]:
import numpy as np
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

y_true = np.array([0, 2, 0, 0, 1, 0])
y_pred = np.array([0, 1, 0, 1, 2, 0])

accuracy = accuracy_score(y_true, y_pred)
print(accuracy)

precision = precision_score(y_true, y_pred, average="micro")
print(precision)

recall = recall_score(y_true, y_pred, average="micro")
print(recall)

f1 = f1_score(y_true, y_pred, average="micro")
print(f1)
0.5
0.5
0.5
0.5

参考文献