Python, scikit-learn

【scikit-learn】ROC曲線の描画


機械学習の手法を用いたクラス分類において、モデルの性能評価にROC曲線を利用するケースがあります。

この記事では、そのためのプログラム作成の方法などについて解説しています。

そもそも「ROC曲線」とは?

まずはROC曲線とは何かについて簡単に説明します。

分類モデルの評価指標の一つ

ROC曲線は分類モデルの性能評価に用いられる指標の一つです。

真偽を区別するカットオフポイントごとに真陽性率(TPF)と偽陽性率(FPF)を計算し、縦軸をTPF、横軸をFPFとしたグラフにプロットすることで作成します。

曲線下の部分をAUC(Area Under the Curve)と呼び、この部分が大きいほど優れた分類性能を持つモデルであると判断されます。

実際にプログラムを作成してみる

それでは実際にROC曲線の描画を行うプログラムを作成してみます。

プログラム作成の手順

ここでは、以下の手順で処理を実装します。

  1. サンプルのデータセットを用意する
  2. 用意したデータセットで機械学習モデルの学習を行う
  3. 学習済みのモデルで分類予測を行う
  4. 分類予測の結果から真陽性率、偽陽性率を算出する
  5. 求めた真陽性率、偽陽性率からROC曲線を描画する

実装例

上記の手順に従ってプログラムを作成します。使用する言語はPythonです。

from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import roc_curve, auc

import matplotlib.pyplot as plt

if __name__ == "__main__":

    # データセットを作成する
    x, y = make_blobs(n_samples=100, n_features=4, centers=2, cluster_std=5.0)
    train_x, test_x, train_y, test_y = train_test_split(x, y, test_size=0.3)

    # 機械学習モデルの学習を行う
    estimator = MLPClassifier()
    estimator.fit(train_x, train_y)

    # テストデータに対する予測を行う
    proba = estimator.predict_proba(test_x)[:,1]

    # 真陽性率、偽陽性率を算出する
    fpr, tpr, _ = roc_curve(test_y, proba)

    # ROC曲線を描画する
    plt.plot(fpr, tpr, label='ROC curve (AUC=%.2f)'%auc(fpr, tpr))
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.legend(loc="lower right")
    plt.show()

このプログラムを実行すると以下の出力結果が得られます。

応用:複数のROC曲線の同時プロット

単一のROC曲線を描画するだけであれば上記のプログラムでも何ら問題はありませんが、複数のROC曲線を描画して比較するのには向きません。

ここでは一例として、複数のモデルのROC曲線を同時に描画するプログラムの作成方法について紹介します。

実装例

同様の手順でプログラムを作成します。使用する言語はPythonです。

from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.metrics import roc_curve, auc

import matplotlib.pyplot as plt

if __name__ == "__main__":

    # データセットを作成する
    x, y = make_blobs(n_samples=100, n_features=4, centers=2, cluster_std=5.0)
    train_x, test_x, train_y, test_y = train_test_split(x, y, test_size=0.3)

    # 使用するモデルを定義する
    ESTIMATORS = {
        'Neural Network' : MLPClassifier(),
        'Decision Tree' : DecisionTreeClassifier(),
        'SVM' : SVC()
    }

    names = list(ESTIMATORS.keys())
    estimators = list(ESTIMATORS.values())

    # 各モデルのROC曲線をそれぞれプロットする
    for name, estimator in zip(names, estimators):
        estimator.fit(train_x, train_y)
        if hasattr(estimator, "decision_function"):
            proba = estimator.decision_function(test_x)
        else:
            proba = estimator.predict_proba(test_x)[:,1]
        fpr, tpr, _ = roc_curve(test_y, proba)
        label = name + ' (AUC={:.2f})'.format(auc(fpr, tpr))
        plt.plot(fpr, tpr, label=label)

    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.legend(loc="lower right")
    plt.show()

このプログラムを実行すると以下の出力結果が得られます。