วิธีรับความแม่นยำ F1 ความแม่นยำและการเรียกคืนสำหรับโมเดล keras ได้อย่างไร


22

ฉันต้องการคำนวณความแม่นยำการเรียกคืนและคะแนน F1 สำหรับโมเดล KerasClassifier ไบนารีของฉัน แต่ไม่พบวิธีแก้ปัญหาใด ๆ

นี่คือรหัสจริงของฉัน:

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

จากนั้นฉันก็ทำนายข้อมูลการทดสอบใหม่และรับเมทริกซ์ความสับสนเช่นนี้

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

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

แต่มีวิธีใดบ้างในการรับคะแนนความแม่นยำคะแนน F1 ความแม่นยำและการเรียกคืน (หากไม่ซับซ้อนก็ต้องใช้ cross-validation-score แต่ไม่จำเป็นสำหรับคำตอบนี้)

ขอบคุณสำหรับความช่วยเหลือ!

คำตอบ:


22

เมตริกถูกลบออกจาก Keras core คุณต้องคำนวณด้วยตนเอง เขาถูกในรุ่น 2.0 ตัวชี้วัดเหล่านั้นเป็นตัวชี้วัดระดับโลกทั้งหมด แต่ Keras ทำงานเป็นชุด ผลก็คือมันอาจทำให้เข้าใจผิดมากกว่าประโยชน์

อย่างไรก็ตามหากคุณต้องการพวกเขาจริงๆคุณสามารถทำเช่นนี้ได้

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)

ถ้าพวกเขาเข้าใจผิดได้อย่างไรจะประเมินโมเดลของ Keras ได้อย่างไร
ZelelB

1
เนื่องจาก Keras คำนวณเมตริกเหล่านั้นในตอนท้ายของแต่ละชุดคุณสามารถรับผลลัพธ์ที่แตกต่างจากตัวชี้วัด "ของจริง" อีกทางเลือกหนึ่งคือการแบ่งชุดข้อมูลของคุณในการฝึกอบรมและทดสอบและใช้ส่วนทดสอบเพื่อทำนายผลลัพธ์ จากนั้นเมื่อคุณรู้จักฉลากจริงให้คำนวณความแม่นยำและเรียกคืนด้วยตนเอง
Tasos

ดังนั้น, ฉันขอแนะนำให้คุณโพสต์คำตอบของคุณอีกครั้งในคำถาม SO นี้: ฉันจะใช้เมตริกที่แม่นยำและจำได้ในโมเดลเครือข่ายประสาทของฉันใน keras ได้อย่างไร? ไชโย
อิราคลีส์

ขออภัยเพิ่งเห็นว่าปิดแล้ว :(
desertnaut

ความคิดใด ๆ ที่ว่าทำไมสิ่งนี้ถึงใช้งานไม่ได้กับการตรวจสอบสำหรับฉัน ทำงานได้ดีสำหรับการฝึกอบรม
Rodrigo Ruiz

13

คุณสามารถใช้รายงานการจัดหมวดหมู่ scikit เรียนรู้ การแปลงป้ายกำกับของคุณในรูปแบบตัวเลขหรือไบนารีจะดูที่การscikit เรียนรู้เข้ารหัสฉลาก

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

ซึ่งให้คุณ (ผลลัพธ์ที่คัดลอกมาจากตัวอย่าง 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

2
นี่คือสิ่งที่ฉันใช้ง่ายและมีประสิทธิภาพ
Matthew

2

คุณสามารถลองตามที่กล่าวไว้ด้านล่าง

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

0

ลองทำสิ่งนี้: https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_recall_fscore_support.htmlด้วย Y_test, y_pred เป็นพารามิเตอร์


ฉันลองสิ่งนี้: model.recision_recall_fscore_support (Y_test, y_pred, average = 'micro') และได้รับข้อผิดพลาดในการดำเนินการนี้: AttributeError: วัตถุ 'ลำดับ' ไม่มีแอตทริบิวต์ 'recision_recall_fscore_support'
ZelelB

คุณไม่จำเป็นต้องระบุ model.recision_recall_fscore_support () ค่อนข้างเพียง recision_recall_fscore_support (Y_test, y_pred เฉลี่ย = 'ไมโคร') (ไม่และให้แน่ใจว่าคุณมีการนำเข้าที่ถูกต้อง "รูปแบบ." จาก sklearn.metrics นำเข้า precision_recall_fscore_support)
Viacheslav Komisarenko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.