AUC - ROC曲線
分類では、さまざまな評価指標がある。最もポピュラーなのは精度で、モデルがどれくらいの頻度で正しいかを測定します。これは理解しやすく、最も正しい推測を得ることが望まれることが多いので、素晴らしい評価基準です。他の評価指標を使うことを検討する場合もあります。
もう1つの一般的な評価指標は、AUC(ROC(receiver operating characteristic)曲線下面積)です。ROC曲線は、異なる分類しきい値での真陽性(TP)率と偽陽性(FP)率をプロットします。しきい値は、2値分類で2つのクラスを分離する異なる確率のカットオフです。これは、モデルがどの程度クラスを分離するかを知るために確率を使用します。
もう 1 つの一般的な指標は次のとおりです。AUC、受信者動作特性の下の領域 (ROC) 曲線。受信者動作特性曲線は、真陽性 (TP) 率と偽陽性 (FP) 異なる分類しきい値でのレート。しきい値は、バイナリ分類で 2 つのクラスを分離する異なる確率カットオフです。確率を使用して、モデルがクラスをどの程度分離しているかを示します。
不均衡なデータ
データの大部分が 1 つの値である不均衡なデータ セットがあるとします。多数派クラスを予測することで、モデルの高い精度を得ることができます。
例
import numpy as np
from sklearn.metrics import accuracy_score, confusion_matrix, roc_auc_score, roc_curve
n = 10000
ratio = .95
n_0 = int((1-ratio) * n)
n_1 = int(ratio * n)
y = np.array([0] * n_0 + [1] * n_1)
# below are the probabilities obtained from a hypothetical model that always predicts the majority class
# probability of predicting class 1 is going to be 100%
y_proba = np.array([1]*n)
y_pred = y_proba > .5
print(f'accuracy score: {accuracy_score(y, y_pred)}')
cf_mat = confusion_matrix(y, y_pred)
print('Confusion matrix')
print(cf_mat)
print(f'class 0 accuracy: {cf_mat[0][0]/n_0}')
print(f'class 1 accuracy: {cf_mat[1][1]/n_1}')
実行例 »
広告
非常に高い精度が得られますが、モデルはデータに関する情報を提供していないため、役に立ちません。クラス1は100%の確率で正確に予測しますが、クラス0は0%の確率で不正確に予測します。精度を犠牲にして、2つのクラスをある程度分離できるモデルを使用する方がよい場合があります。
例
# below are the probabilities obtained from a hypothetical model that doesn't always predict the mode
y_proba_2 = np.array(
np.random.uniform(0, .7, n_0).tolist() +
np.random.uniform(.3, 1, n_1).tolist()
)
y_pred_2 = y_proba_2 > .5
print(f'accuracy score: {accuracy_score(y, y_pred_2)}')
cf_mat = confusion_matrix(y, y_pred_2)
print('Confusion matrix')
print(cf_mat)
print(f'class 0 accuracy: {cf_mat[0][0]/n_0}')
print(f'class 1 accuracy: {cf_mat[1][1]/n_1}')
実行例 »
2番目の予測セットでは、最初の予測ほど精度スコアは高くありませんが、各クラスの精度はよりバランスが取れています。精度を評価指標として使用すると、データについて何も教えてくれなくても、最初のモデルを2番目のモデルよりも高く評価します。
このような場合は、AUCなどの別の評価指標を使用することをお勧めします。
import matplotlib.pyplot as pltdef plot_roc_curve(true_y, y_prob): """ plots the roc curve based of the probabilities """ fpr, tpr, thresholds = roc_curve(true_y, y_prob) plt.plot(fpr, tpr) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate')
例
モデル1:
plot_roc_curve(y, y_proba)
print(f'model 1 AUC score: {roc_auc_score(y, y_proba)}')
結果
モデル 1 AUC スコア: 0.5
実行例 »例
モデル 2:
plot_roc_curve(y, y_proba_2)
print(f'model 2 AUC score: {roc_auc_score(y, y_proba_2)}')
結果
モデル2 AUC スコア: 0.8270551578947367
実行例 »
AUCスコアが0.5程度であれば、モデルは2つのクラスを区別することができず、曲線は傾き1の直線のようになります。AUCスコアが1に近ければ、モデルは2つのクラスを分離する能力があり、曲線はグラフの左上隅に近づきます。
確率
AUCはクラス予測の確率を利用するメトリックであるため、精度が類似していても、AUCスコアが低いモデルよりもAUCスコアが高いモデルの方が信頼性が高くなります。
以下のデータには、仮説モデルからの確率の2つのセットがあります。最初の確率は、2つのクラスを予測するときに「信頼できる」ものではありません (確率は0.5に近い)。 2番目のクラスは、2つのクラスを予測する際により「信頼できる」確率を持っています (確率は0または1の極値に近い)。
例
import numpy as np
n = 10000
y = np.array([0] * n + [1] * n)
#
y_prob_1 = np.array(
np.random.uniform(.25, .5, n//2).tolist() +
np.random.uniform(.3, .7, n).tolist() +
np.random.uniform(.5, .75, n//2).tolist()
)
y_prob_2 = np.array(
np.random.uniform(0, .4, n//2).tolist() +
np.random.uniform(.3, .7, n).tolist() +
np.random.uniform(.6, 1, n//2).tolist()
)
print(f'model 1 accuracy score: {accuracy_score(y, y_prob_1>.5)}')
print(f'model 2 accuracy score: {accuracy_score(y, y_prob_2>.5)}')
print(f'model 1 AUC score: {roc_auc_score(y, y_prob_1)}')
print(f'model 2 AUC score: {roc_auc_score(y, y_prob_2)}')
実行例 »例
モデル1のプロット:
plot_roc_curve(y, y_prob_1)
結果
実行例 »
例
モデル2のプロット:
fpr, tpr, thresholds = roc_curve(y, y_prob_2)
plt.plot(fpr, tpr)
結果
実行例 »
2つのモデルの精度は似ていますが、AUCスコアが高いモデルの方が信頼性が高くなります。これは、予測される確率が考慮されているためです。将来のデータを予測するときに、より高い精度が得られる可能性が高くなります。