めも

これはメモ。

予測モデルなどの評価指標について

めも。

問題ごとに評価の目的(何を評価したいか、結果がどのようになっているのが理想か)を決め、それに合う指標を決める。評価指標が具体的に何を計算していて、何を評価しようとしているのかを知るには scikit-learn などのソースコードのコメントとかを見た方が分かりやすいかもしれません。

例:

分類

複数のクラスの中から一つだけ選ぶ場合。

参考文献: Hossin, M., & Sulaiman, M. N. (2015). A review on evaluation metrics for data classification evaluations. International Journal of Data Mining & Knowledge Management Process, 5(2), 1.

二値

多くは多値分類の指標にもなる。

二値分類の混合行列(Confusion Matrix)

表: 二値分類の混合行列

正解\予測 1 0
1 True Positive False Negative
0 False Positive True Negative

表の見方。True Positice = 正解が1で、予測が1だった、など。

以下ではTruePositive = 「True Positice となったデータ数」を指します。

Accuracy(正解率)

全データ数に対して、正解したデータ数の割合。

 Accuracy = \frac{TruePositive+TrueNegative}{all}

from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y, y_pred)

Precision(適合率、精度)

1と予測したもののうち、実際に1だった割合。

 Precision = \frac{TruePositive}{TruePositice+TrueNegative}

from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y, y_pred)

Recall(再現率)

1が正解であるデータのうち、1を予測できた割合。

 Recall = \frac{TruePositive}{TruePositice+FalsePositive}

F値

適合率と再現率の調和平均。

 F-score = 2 \frac{Precision * Recall}{Precision + Recall}

ROC-AUC

縦軸に 「 \frac{TruePositice}{TruePositice+FalseNegative}」、 横軸に 「 \frac{FalsePositive}{TrueNegative+FalsePositive}」としたグラフを用意する。

二クラス分類を行ったモデルが「0.4, 0.8, ...」などと出力したとき、「0.xx以上なら1のラベルを付ける」と閾値を決定する。この閾値を変化させたときの上記二つの値をプロットしていく。この時にできた線(曲線)の面積の値。

完全にランダムな予測を行うと、原点と(1, 1)を結んだ直線付近にプロットがされることになり、面積は0.5に近くなる。完全に分類できるモデルの場合は #FalsePositive=誤って1と予測したデータが0の時点で全部正解となるので面積は1になる。

from sklearn.metrics import roc_auc_score
rocauc = roc_auc_score(y, y_pred)

Log loss

Log Loss - Deep Learning Course Wiki より引用します。

import numpy as np

def logloss(true_label, predicted, eps=1e-15):
  p = np.clip(predicted, eps, 1 - eps)
  if true_label == 1:
    return -log(p)
  else:
    return -log(1 - p)

logloss = log_loss(y, y_pred)

Cohen-Kappa

from sklearn.metrics import cohen_kappa_score
ck = cohen_kappa_score(y, y_pred)

多値

全体のスコアを重視するか、クラスごとのスコアを重視するかでmicroとmacroに分かれる。 正解のクラスラベルごとに2x2の混合行列がある時

  • micro: 全体
  • macro: それぞれのクラスの混合行列ごとに値を出してその平均をとる

参考文献: Sokolova, M., & Lapalme, G. (2009). A systematic analysis of performance measures for classification tasks. Information Processing & Management, 45(4), 427-437.

f:id:misos:20181228053244p:plain
上記論文より引用。tp, fn = true positive, false negativeなど。

  • 上位p%: 各サンプルごとにクラスごとの所属確率が出るとき、 確率が高い上位 p% のクラスの中に正解が含まれている割合はどれくらいかを見る。

確率

Brier score

from sklearn.metrics import brier_score_loss
brier = brier_score_loss(y, y_probability)

回帰

教師データが連続値を持つ場合。

Mean Absolute Error(MAE)

正解からの絶対値誤差を損失として扱う。外れ値(大きく予測を外した値)も絶対値だけ取るため外れ値によって損失が急激に大きくなりにくい。MAEを最小化するようにする場合は誤差がラプラス分布から発生していると仮定した場合の最尤推定を行っていることになる。

 MAE = \frac{1}{N} \sum_{i}^{N} |y_i - \hat{y_i}|

from skelearn.metrics import mean_absolute_error
mae = mean_absolute_error(y, y_pred)

Mean Absolute Percentage Error(MAPE)

式の定義上yにゼロが含まれる場合は計算できなくなる。その場合、yの平均値との比率を見るなどのバリエーションがある。

y = np.random.randint(0, 100, 100)
y_pred = y + np.random.randint(1, 20, 100)/100
mape =  np.mean(np.abs((y - y_pred) / y))*100

Median Absolute Error

誤差の中央値を見るため、非常に誤差が大きいデータは評価されない。誤差が少ない上位半分がどれくらいに収まっているかを見る。

from skelearn.metrics import median_absolute_error
median_abe = median_absolute_error(y, y_pred)

Root Mean Squared Error(RMSE)

正解との誤差の二乗を損失として扱う。つまり、誤差が小さい箇所と比べて誤差が大きい箇所を重要視している。また、二乗誤差を最小化することは誤差が正規分布から発生していると仮定した場合の最尤推定に等しくなる。

 RMSE = \sqrt{\frac{1}{N} \sum_{i}^{N} | y_i - \hat{y_i} |^2}

import numpy as np
from sklearn.metrics import mean_squared_error
rmse = np.sqrt(mean_squared_error(y, y_pred))

Root Mean Squared Log Error(RMSLE)

対数の差を評価する、正解データに対して誤差の比率が大きい場合は誤差が大きくなることになる。 log(0)とならないようにy+1としている。 ログの関数が大きい値になるほど緩やかに増加する形になっていることから、 正解よりも-1低い誤差を出すよりも+1高い誤差た方がわずかに損失が減る。 なので予測モデルの損失関数として利用する場合、正解よりも高い値で誤差を出すケースが増える。

import numpy as np
rmsle = np.sqrt(np.mean(np.square(np.log1p(y+1) - np.log1p(y_pred+1))))

誤差のプロット

サンプルデータとして、yに-0.2~0.2の値をとる乱数を足してそれがモデルの予測値だったとしている。 元のデータが0付近の場合は相対的に誤差の比率が大きくなる。

import numpy as np
import matplotlib.pyplot as plt

y = np.random.randint(0, 100, 100)
y_pred = y + np.random.randint(-20, 20, 100)/100
rmsle_list = np.array([np.sqrt(np.mean(np.square(np.log1p(yi+1) - np.log1p(ypi+1)))) for yi, ypi in zip(y, y_pred)])

plt.subplot(121)
plt.plot(y_pred-y, np.array(rmsle_list), "x")
plt.xlabel("y_pred-y")
plt.ylabel("rmsle")

plt.subplot(122)
plt.plot(y, np.array(rmsle_list), "x")
plt.xlabel("y")
plt.ylabel("rmsle")

plt.tight_layout()

f:id:misos:20181227224000p:plain
RMSLEと誤差・正解値の関係

二つ目の図から、元のデータが0付近で予測値と誤差がある場合は損失が大きくなっていることが分かる。なので、正解データと誤差の比率が大きくなってほしくない場合にこの評価指標を見る 。

決定係数(R2)

教師データと予測値との相関をとり、予測が正解と完全に一致する場合は1をとる。 つまり、値が1に近く(大きい値をとるほど)良いモデルができているとみる。

f:id:misos:20181227224621p:plain

この式からわかるように、決定係数はRMSEを使って書き換えることができて

f:id:misos:20181227230251p:plain

決定係数はRMSEが小さくなるほど高くなる。なので、基本的にはRMSEだけ見ればモデルは評価できる。

from sklearn.metrics import r2_score
r2 = r2_score(y, y_pred)

マルチラベル

教師データが0~複数のクラスのラベルを持つ場合。

データ・ラベルごとの評価をまとめる

データごと

データ一つ一つごとに値を求めて、その集計をとる。

  • Exact-match ratio
  • Precision
  • Recall
  • Accuracy
  • ハミング損失
  • F1

ラベルごと

ラベルごとに正解率などを求めて、その集計(平均など)をとる。

  • Macro Averaged Measures
  • Micro Averaged Measures
  • α-Evaluation

ランキング

モデルがラベルごとに確率を出力できる場合は、その確率のランキングを用いて評価できる。

  • One Error
  • Coverage
  • Ranking Loss

その他

他の問題や比較の指標など。

クラスタリング

2.3. Clustering — scikit-learn 0.20.2 documentation

  • 教師あり:既にクラスタのラベルがある場合、そのラベルをもとにどれくらい正しいクラスタリングができているかを評価する。
  • 教師なし

類似度

scikit-learnにおける Pairwise metrics( 4.8. Pairwise metrics, Affinities and Kernels — scikit-learn 0.20.2 documentation )など、二つのデータ間の比較を行う時の指標。

ベクトル間

cos類似度

ベクトルの向きの類似度を指標とするもので、直交する場合に0。

相関係数

二つの数値ベクトル間の相関を類似度とする。

文字列間

ハミング距離

文字列の不一致数。

編集(レーベンシュタイン)距離

Wikipedia: レーベンシュタイン距離

文字列xに対して文字の挿入,削除,置換を最低 d 回行って y にできるとき、x-y間の編集距離は d。挿入,削除,置換を行うコストがすべて1の場合、例えば5文字の単語間の編集距離は必ず5以下になる。

ジャロ・ウィンクラー距離

[0, 1]間の値をとり、1に近いほど類似度が高い。 三角不等式に従わないので注意。

集合間

集合間の類似度の指標。分子はすべて同じであり、差集合の要素数をどれほど重要視するかに違いがある。

Jaccard係数

|X∧Y|/|X∨Y| = 2つの集合に含まれる要素のうち、共通の要素の割合

Dice係数

2|X∧Y|/(|X|+|Y|) = 二つの集合の平均要素数に対する、共通の要素の割合。

Simpson係数

|X∧Y|/min{|X|,|Y|} = 要素数が少ない集合での共通要素の割合。なので、一方が一方の真部分集合の場合は常に1になる。

三つの係数の比較

XがYの真部分集合でない場合
import numpy as np
X = set(np.arange(10))
Y = set(np.arange(20)+5)

print(X)
print(Y)

// Jaccard, Dice, Simpson係数
len(X&Y)/len(X|Y), 2*len(X&Y)/(len(X)+len(Y)), len(X&Y)/np.min([len(X), len(Y)])
X: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Y: {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}
(0.2, 0.3333333333333333, 0.5)
XがYの真部分集合の場合
import numpy as np
X = set(np.arange(10))
Y = set(np.arange(20))

print(X)
print(Y)

// Jaccard, Dice, Simpson係数
len(X&Y)/len(X|Y), 2*len(X&Y)/(len(X)+len(Y)), len(X&Y)/np.min([len(X), len(Y)])
X: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Y: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
(0.5, 0.6666666666666666, 1.0)

その他

計算量・時間

  • 時間計算量
  • 空間計算量
  • 訓練データのサイズ
  • 訓練時間
    • 特定の性能を達成するために必要な訓練時間
    • 最高性能を達成するまでに必要な訓練時間
  • 予測時間

頑健性

ハイパーパラメータを変えた時の結果の変化の度合い、異常値をもつサンプルの影響を受けにくいなど。

情報量基準

データに基づいて作成した統計モデルを比較するための指標。AIC,BIC(シュワルツ情報量規準),MDLなど。

参照:AICとMDLとBIC

参考文献