Bagaimana cara mendapatkan akurasi, F1, presisi dan daya ingat, untuk model yang keras?

20

Saya ingin menghitung ketepatan, daya ingat dan skor-F1 untuk model KerasClassifier biner saya, tetapi tidak menemukan solusi.

Ini kode saya yang sebenarnya:

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

Dan kemudian saya memprediksi data tes baru, dan mendapatkan matriks kebingungan seperti ini:

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

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

Tetapi apakah ada solusi untuk mendapatkan skor akurasi, skor F1, presisi, dan penarikan kembali? (Jika tidak rumit, juga skor validasi silang, tetapi tidak diperlukan untuk jawaban ini)

Terima kasih atas bantuannya!

ZelelB
sumber

Jawaban:

20

Metrik telah dihapus dari inti Keras. Anda perlu menghitungnya secara manual. Mereka menghapusnya di versi 2.0 . Semua metrik itu adalah metrik global, tetapi Keras bekerja dalam batch. Akibatnya, mungkin lebih menyesatkan daripada membantu.

Namun, jika Anda benar-benar membutuhkannya, Anda dapat melakukannya seperti ini

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
sumber
jika mereka bisa menyesatkan, bagaimana cara mengevaluasi model Keras?
ZelelB
1
Karena Keras menghitung metrik tersebut di akhir setiap batch, Anda bisa mendapatkan hasil yang berbeda dari metrik "nyata". Cara alternatif adalah dengan membagi dataset Anda dalam pelatihan dan pengujian dan menggunakan bagian tes untuk memprediksi hasilnya. Maka karena Anda tahu label aslinya, hitung presisi dan ingat secara manual.
Tasos
Taso, boleh saya sarankan Anda memposting ulang jawaban Anda dalam pertanyaan SO ini: Bagaimana saya harus menerapkan metrik presisi dan mengingat dalam model jaringan saraf saya di keras? Cheers, Iraklis
desertnaut
Maaf, baru saja ditutup :(
desertnaut
Adakah gagasan mengapa ini tidak berfungsi untuk validasi bagi saya? berfungsi dengan baik untuk pelatihan.
Rodrigo Ruiz
13

Anda dapat menggunakan laporan klasifikasi scikit-learn . Untuk mengonversi label Anda ke format numerik atau biner, lihat enkoder label 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))

yang memberi Anda (output disalin dari contoh 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
sumber
2
Inilah yang saya gunakan, sederhana dan efektif.
Matius
2

Anda juga dapat mencoba seperti yang disebutkan di bawah ini.

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

Coba ini: https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_recall_fscore_support.html dengan Y_test, y_pred sebagai parameter.

Viacheslav Komisarenko
sumber
Saya mencoba ini: model.recision_recall_fscore_support (Y_test, y_pred, average = 'micro') dan mendapatkan kesalahan ini pada eksekusi: AttributeError: objek 'Sequential' tidak memiliki atribut 'recision_recall_fscore_support'
ZelelB
Anda tidak perlu menentukan model.recision_recall_fscore_support (), melainkan hanya recision_recall_fscore_support (Y_test, y_pred, rata-rata = 'mikro') (tanpa "model." Dan pastikan Anda memiliki impor yang benar: dari impor sklearn.metrics import precision_recall_fscore_support)
Viacheslav Komisarenko