web-dev-qa-db-ja.com

ケラで受信動作特性(ROC)とAUCを計算する方法は?

私は、kerasで書いたmulti output(200)バイナリ分類モデルを持っています。

このモデルでは、ROCやAUCなどのメトリクスを追加したいのですが、私の知る限りでは、ケラにはROCおよびAUCのメトリクス関数が組み込まれていません。

ROC、AUC関数をscikit-learnからインポートしようとしました

from sklearn.metrics import roc_curve, auc
from keras.models import Sequential
from keras.layers import Dense
.
.
.
model.add(Dense(200, activation='relu'))
model.add(Dense(300, activation='relu'))
model.add(Dense(400, activation='relu'))
model.add(Dense(300, activation='relu'))
model.add(Dense(200,init='normal', activation='softmax')) #outputlayer

model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=['accuracy','roc_curve','auc'])

しかし、それはこのエラーを与えています:

例外:無効なメトリック:roc_curve

ROC、AUCをkerasに追加するにはどうすればよいですか?

44
Eka

そのため、ミニバッチでROC&AUCを計算することはできません。1エポックの終わりにのみ計算できます。 jamartinh から解決策があります。便宜上、以下のコードにパッチを適用します。

from sklearn.metrics import roc_auc_score
from keras.callbacks import Callback
class roc_callback(Callback):
    def __init__(self,training_data,validation_data):
        self.x = training_data[0]
        self.y = training_data[1]
        self.x_val = validation_data[0]
        self.y_val = validation_data[1]


    def on_train_begin(self, logs={}):
        return

    def on_train_end(self, logs={}):
        return

    def on_Epoch_begin(self, Epoch, logs={}):
        return

    def on_Epoch_end(self, Epoch, logs={}):
        y_pred = self.model.predict(self.x)
        roc = roc_auc_score(self.y, y_pred)
        y_pred_val = self.model.predict(self.x_val)
        roc_val = roc_auc_score(self.y_val, y_pred_val)
        print('\rroc-auc: %s - roc-auc_val: %s' % (str(round(roc,4)),str(round(roc_val,4))),end=100*' '+'\n')
        return

    def on_batch_begin(self, batch, logs={}):
        return

    def on_batch_end(self, batch, logs={}):
        return

model.fit(X_train, y_train, validation_data=(X_test, y_test), callbacks=[roc_callback(training_data=(X_train, y_train),validation_data=(X_test, y_test))])

tf.contrib.metrics.streaming_aucを使用したよりハッキング可能な方法

import numpy as np
import tensorflow as tf
from sklearn.metrics import roc_auc_score
from sklearn.datasets import make_classification
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
from keras.callbacks import Callback, EarlyStopping


# define roc_callback, inspired by https://github.com/keras-team/keras/issues/6050#issuecomment-329996505
def auc_roc(y_true, y_pred):
    # any tensorflow metric
    value, update_op = tf.contrib.metrics.streaming_auc(y_pred, y_true)

    # find all variables created for this metric
    metric_vars = [i for i in tf.local_variables() if 'auc_roc' in i.name.split('/')[1]]

    # Add metric variables to GLOBAL_VARIABLES collection.
    # They will be initialized for new session.
    for v in metric_vars:
        tf.add_to_collection(tf.GraphKeys.GLOBAL_VARIABLES, v)

    # force to update metric values
    with tf.control_dependencies([update_op]):
        value = tf.identity(value)
        return value

# generation a small dataset
N_all = 10000
N_tr = int(0.7 * N_all)
N_te = N_all - N_tr
X, y = make_classification(n_samples=N_all, n_features=20, n_classes=2)
y = np_utils.to_categorical(y, num_classes=2)

X_train, X_valid = X[:N_tr, :], X[N_tr:, :]
y_train, y_valid = y[:N_tr, :], y[N_tr:, :]

# model & train
model = Sequential()
model.add(Dense(2, activation="softmax", input_shape=(X.shape[1],)))

model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy', auc_roc])

my_callbacks = [EarlyStopping(monitor='auc_roc', patience=300, verbose=1, mode='max')]

model.fit(X, y,
          validation_split=0.3,
          shuffle=True,
          batch_size=32, nb_Epoch=5, verbose=1,
          callbacks=my_callbacks)

# # or use independent valid set
# model.fit(X_train, y_train,
#           validation_data=(X_valid, y_valid),
#           batch_size=32, nb_Epoch=5, verbose=1,
#           callbacks=my_callbacks)
57
Tom

あなたと同じように、私はscikit-learnの組み込みメソッドを使用してAUROCを評価することを好みます。ケラスでこれを行う最も簡単で簡単な方法は、カスタムメトリックを作成することです。テンソルフローがバックエンドである場合、これを実装することはごくわずかなコード行で実行できます。

import tensorflow as tf
from sklearn.metrics import roc_auc_score

def auroc(y_true, y_pred):
    return tf.py_func(roc_auc_score, (y_true, y_pred), tf.double)

# Build Model...

model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=['accuracy', auroc])

モデルには複数の出力があるため、他の回答に記載されているカスタムコールバックを作成してもケースには機能しませんが、これは機能します。さらに、このメソッドでは、トレーニングデータと検証データの両方でメトリックを評価できますが、kerasコールバックはトレーニングデータにアクセスできないため、トレーニングデータのパフォーマンスを評価するためにのみ使用できます。

28
Kimball Hill

次の解決策は私のために働いた:

import tensorflow as tf
from keras import backend as K

def auc(y_true, y_pred):
    auc = tf.metrics.auc(y_true, y_pred)[1]
    K.get_session().run(tf.local_variables_initializer())
    return auc

model.compile(loss="binary_crossentropy", optimizer='adam', metrics=[auc])
20
B. Kanani

この方法で問題を解決しました

フィーチャのテストデータセットx_testと、対応するターゲットのy_testがあることを考慮してください。

まず、訓練されたモデルを使用して特徴からターゲットを予測します

 y_pred = model.predict_proba(x_test)

次に、sklearnから roc_auc_score 関数をインポートしてから、元のターゲットと予測ターゲットを関数に単純に渡します。

 roc_auc_score(y_test, y_pred)
15
Eka

'roc_curve'、 'auc'は標準のメトリックではないため、そのようなメトリックをメトリック変数に渡すことはできません。これは許可されていません。標準メトリックである「fmeasure」のようなものを渡すことができます。

ここで利用可能なメトリックを確認してください: https://keras.io/metrics/ また、独自のカスタムメトリックの作成を確認することもできます: https://keras.io/metrics/#custom-metrics

ROC、AUCについては、このブログで言及されているgenerate_resultsメソッドもご覧ください... https://vkolachalama.blogspot.in/2016/05/keras-implementation-of-mlp-neural .html

6
sunil manikani

上記の答えに加えて、「ValueError:bad input shape ...」というエラーが出たので、確率のベクトルを次のように指定します。

y_pred = model.predict_proba(x_test)[:,1]
auc = roc_auc_score(y_test, y_pred)
print(auc)
1
KarthikS