Jak uzyskać dokładność, F1, precyzję i wycofanie, dla modelu Keras?

22

Chcę obliczyć precyzję, pamięć i wynik F1 dla mojego binarnego modelu KerasClassifier, ale nie znajduję żadnego rozwiązania.

Oto mój rzeczywisty kod:

# Split dataset in train and test data 
X_train, X_test, Y_train, Y_test = train_test_split(normalized_X, Y, test_size=0.3, random_state=seed)

# Build the model
model = Sequential()
model.add(Dense(23, input_dim=45, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal', activation='sigmoid'))

# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])


tensorboard = TensorBoard(log_dir="logs/{}".format(time.time()))

time_callback = TimeHistory()

# Fit the model
history = model.fit(X_train, Y_train, validation_split=0.3, epochs=200, batch_size=5, verbose=1, callbacks=[tensorboard, time_callback]) 

A potem przewiduję nowe dane testowe i otrzymuję macierz zamieszania w następujący sposób:

y_pred = model.predict(X_test)
y_pred =(y_pred>0.5)
list(y_pred)

cm = confusion_matrix(Y_test, y_pred)
print(cm)

Ale czy jest jakieś rozwiązanie, aby uzyskać wynik dokładności, wynik F1, precyzję i wycofanie? (Jeśli nie jest to skomplikowane, również ocena krzyżowa, ale nie jest to konieczne dla tej odpowiedzi)

Dziękuję za wszelką pomoc!

ZelelB
źródło

Odpowiedzi:

22

Dane zostały usunięte z rdzenia Keras. Musisz je obliczyć ręcznie. Usunęli je w wersji 2.0 . Te dane są danymi globalnymi, ale Keras działa partiami. W rezultacie może to być bardziej mylące niż pomocne.

Jeśli jednak naprawdę ich potrzebujesz, możesz to zrobić w ten sposób

from keras import backend as K

def recall_m(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    recall = true_positives / (possible_positives + K.epsilon())
    return recall

def precision_m(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision

def f1_m(y_true, y_pred):
    precision = precision_m(y_true, y_pred)
    recall = recall_m(y_true, y_pred)
    return 2*((precision*recall)/(precision+recall+K.epsilon()))

# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc',f1_m,precision_m, recall_m])

# fit the model
history = model.fit(Xtrain, ytrain, validation_split=0.3, epochs=10, verbose=0)

# evaluate the model
loss, accuracy, f1_score, precision, recall = model.evaluate(Xtest, ytest, verbose=0)
Tasos
źródło
jeśli mogą wprowadzać w błąd, to jak ocenić model Kerasa?
ZelelB
1
Ponieważ Keras oblicza te metryki na końcu każdej partii, możesz uzyskać inne wyniki od „prawdziwych” metryk. Alternatywnym sposobem byłoby podzielenie zestawu danych na szkolenie i testowanie oraz wykorzystanie części testowej do przewidywania wyników. Ponieważ znasz prawdziwe etykiety, oblicz precyzję i przywołaj ręcznie.
Tasos
Taso, czy mogę zasugerować ponowne przesłanie odpowiedzi w tym pytaniu SO: Jak powinienem wdrożyć precyzję i przywołać metryki w moim modelu sieci neuronowej w keras? Pozdrawiam, Iraklis
desertnaut
Przepraszamy, właśnie widziałem, że został zamknięty :(
desertnaut
Wiesz, dlaczego to nie działa w przypadku sprawdzania poprawności? działa dobrze na treningu.
Rodrigo Ruiz
13

Możesz użyć raportu klasyfikacji scikit-learn . Aby przekonwertować etykiety na format numeryczny lub binarny, spójrz na koder etykiet scikit-learn .

from sklearn.metrics import classification_report

y_pred = model.predict(x_test, batch_size=64, verbose=1)
y_pred_bool = np.argmax(y_pred, axis=1)

print(classification_report(y_test, y_pred_bool))

co daje (dane wyjściowe skopiowane z przykładu scikit-learn):

             precision  recall   f1-score    support

 class 0       0.50      1.00      0.67         1
 class 1       0.00      0.00      0.00         1
 class 2       1.00      0.67      0.80         3
matze
źródło
2
To jest to, czego używam, proste i skuteczne.
Matthew
2

Możesz także spróbować, jak wspomniano poniżej.

from sklearn.metrics import f1_score, precision_score, recall_score, confusion_matrix
y_pred1 = model.predict(X_test)
y_pred = np.argmax(y_pred1, axis=1)

# Print f1, precision, and recall scores
print(precision_score(y_test, y_pred , average="macro"))
print(recall_score(y_test, y_pred , average="macro"))
print(f1_score(y_test, y_pred , average="macro"))
Ashok Kumar Jayaraman
źródło
0

Spróbuj tego: https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_recall_fscore_support.html z Y_test, y_pred jako parametrami.

Wiaczesław Komisarenko
źródło
Próbowałem tego: model.recision_recall_fscore_support (Y_test, y_pred, average = 'micro') i otrzymałem ten błąd przy wykonywaniu: AttributeError: Obiekt „Sequential” nie ma atrybutu „recision_recall_fscore_support”
ZelelB
Nie musisz określać modelu.recision_recall_fscore_support (), a po prostu recision_recall_fscore_support (Y_test, y_pred, average = 'micro') (bez „model.” I upewnij się, że masz prawidłowy import: ze sklearn.metrics importu precision_recall_fscore_support)
Viacheslav Komisarenko,