python - instalar - ¿Cómo calcular la característica operativa de recepción(ROC) y el AUC en keras?
tensorflow python (6)
Tengo un modelo de clasificación binaria de salida múltiple (200) que escribí en keras.
En este modelo, quiero agregar métricas adicionales como ROC y AUC, pero que yo sepa, las keras no tienen funciones métricas ROC y AUC incorporadas.
Traté de importar funciones ROC, AUC de 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''])
pero está dando este error:
Excepción: métrica no válida: roc_curve
¿Cómo debo agregar ROC, AUC a los keras?
''roc_curve'', ''auc'' no son métricas estándar, no puede pasarlas así a la variable de métricas, esto no está permitido. Puede pasar algo como ''medida'', que es una métrica estándar.
Revise las métricas disponibles aquí: https://keras.io/metrics/ Es posible que también desee echar un vistazo a cómo crear su propia métrica personalizada: https://keras.io/metrics/#custom-metrics
También eche un vistazo al método generate_results mencionado en este blog para ROC, AUC ... https://vkolachalama.blogspot.in/2016/05/keras-implementation-of-mlp-neural.html
Agregando a las respuestas anteriores, recibí el error "ValueError: forma de entrada incorrecta ...", así que especifico el vector de probabilidades de la siguiente manera:
y_pred = model.predict_proba(x_test)[:,1]
auc = roc_auc_score(y_test, y_pred)
print(auc)
Al igual que usted, prefiero usar los métodos integrados de scikit-learn para evaluar AUROC. Creo que la mejor y más fácil manera de hacer esto en keras es crear una métrica personalizada. Si tensorflow es su backend, la implementación se puede hacer en muy pocas líneas de código:
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])
Crear una devolución de llamada personalizada como se menciona en otras respuestas no funcionará para su caso ya que su modelo tiene múltiples salidas, pero funcionará. Además, estos métodos permiten evaluar la métrica tanto en los datos de entrenamiento como de validación, mientras que una devolución de llamada keras no tiene acceso a los datos de entrenamiento y, por lo tanto, solo se puede usar para evaluar el rendimiento de los datos de entrenamiento.
Debido a que no puede calcular ROC y AUC por mini lotes, solo puede calcularlo al final de una época. Hay una solución de jamartinh , parcheo los siguientes códigos por conveniencia:
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))])
Una forma más pirateable usando
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)
La siguiente solución funcionó para mí:
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])
Resolví mi problema de esta manera
considere que tiene un conjunto de datos de prueba x_test para características y y_test para sus objetivos correspondientes.
Primero predecimos objetivos a partir de la característica usando nuestro modelo entrenado
y_pred = model.predict_proba(x_test)
luego de sklearn importamos la función roc_auc_score y luego pasamos los objetivos originales y los objetivos predichos a la función.
roc_auc_score(y_test, y_pred)