Wie erhält man Genauigkeit, F1, Präzision und Rückruf für ein Keras-Modell?

18

Ich möchte die Genauigkeit, den Rückruf und den F1-Score für mein binäres KerasClassifier-Modell berechnen, finde aber keine Lösung.

Hier ist mein aktueller Code:

# 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]) 

Und dann prognostiziere ich neue Testdaten und erhalte die Verwirrungsmatrix wie folgt:

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

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

Aber gibt es eine Lösung, um den Genauigkeitswert, den F1-Wert, die Präzision und den Rückruf zu erhalten? (Wenn nicht kompliziert, auch die Kreuzvalidierungsbewertung, aber für diese Antwort nicht erforderlich)

Vielen Dank für jede Hilfe!

ZelelB
quelle

Antworten:

17

Metriken wurden aus dem Keras-Kern entfernt. Sie müssen sie manuell berechnen. Sie haben sie in der Version 2.0 entfernt . Diese Metriken sind alle globale Metriken, aber Keras arbeitet in Stapeln. Infolgedessen ist es möglicherweise eher irreführend als hilfreich.

Wenn Sie sie jedoch wirklich brauchen, können Sie dies so tun

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
quelle
Wenn sie irreführend sein können, wie bewertet man dann ein Keras-Modell?
ZelelB
1
Da Keras diese Metriken am Ende jedes Stapels berechnet, können Sie unterschiedliche Ergebnisse aus den "echten" Metriken erhalten. Eine alternative Möglichkeit wäre, Ihren Datensatz in Training und Test aufzuteilen und den Testteil zur Vorhersage der Ergebnisse zu verwenden. Da Sie die tatsächlichen Beschriftungen kennen, berechnen Sie die Genauigkeit und rufen Sie sie manuell ab.
Tasos
Taso, darf ich Ihnen freundlicherweise vorschlagen, Ihre Antwort in dieser SO-Frage erneut zu veröffentlichen: Wie soll ich Präzisions- und Rückrufmetriken in meinem neuronalen Netzwerkmodell in Keras implementieren? Prost, Iraklis
desertnaut
Sorry, habe gerade gesehen, dass es geschlossen war :(
desertnaut
Irgendeine Idee, warum dies für mich nicht zur Validierung beiträgt? funktioniert gut für das Training.
Rodrigo Ruiz
11

Sie können den Scikit-Learn-Klassifizierungsbericht verwenden . Um Ihre Beschriftungen in ein numerisches oder binäres Format zu konvertieren, schauen Sie sich den scikit-learn-Beschriftungscodierer an .

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))

was gibt Ihnen (Ausgabe aus dem Scikit-Learn-Beispiel kopiert):

             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
quelle
2
Dies ist, was ich benutze, einfach und effektiv.
Matthew
2

Sie können es auch wie unten beschrieben versuchen.

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
quelle
0

Versuchen Sie Folgendes : https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_recall_fscore_support.html mit Y_test, y_pred als Parametern.

Viacheslav Komisarenko
quelle
Ich habe Folgendes versucht: model.recision_recall_fscore_support (Y_test, y_pred, durchschnitt = 'micro') und habe diesen Fehler bei der Ausführung erhalten: AttributeError: 'Sequentielles' Objekt hat kein Attribut 'recision_recall_fscore_support'
ZelelB
Sie müssen nicht angeben model.recision_recall_fscore_support (), und nicht nur recision_recall_fscore_support (Y_test, y_pred, mittel = 'Mikro') müssen (ohne und stellen Sie sicher , dass Sie den richtigen Import haben "-Modell.": Von sklearn.metrics precision_recall_fscore_support importieren)
Viacheslav Komisarenko