Pengembangan Model Machine Learning untuk Prediksi Gagal Jantung Berbasis Rekam Medis Klinis

I Made Hermanto
6 min readJul 17, 2024

--

Sumber : https://www.kaggle.com/datasets/aadarshvelu/heart-failure-prediction-clinical-records/

Gagal jantung adalah kondisi serius yang mempengaruhi jutaan orang di seluruh dunia. Dengan kemajuan teknologi dan data medis, kini kita memiliki kesempatan untuk menggunakan machine learning untuk membantu prediksi gagal jantung secara lebih akurat dan efisien. Dalam penelitian ini, saya menggunakan dataset yang kaya dengan informasi klinis dari Kaggle untuk membangun model prediksi gagal jantung yang dapat membantu dalam pengambilan keputusan medis.

Pendahuluan

Pada era digital ini, data menjadi aset yang sangat berharga, terutama dalam bidang kesehatan. Dengan menggunakan data medis, kita dapat memprediksi berbagai kondisi kesehatan yang dapat membantu para profesional medis dalam membuat keputusan yang lebih baik. Salah satu kondisi kesehatan yang menjadi fokus penelitian saya adalah gagal jantung.

Gagal jantung merupakan kondisi di mana jantung tidak dapat memompa darah sesuai kebutuhan tubuh. Hal ini dapat disebabkan oleh berbagai faktor seperti usia, anemia, diabetes, tekanan darah tinggi, dan lain-lain. Untuk membantu prediksi kondisi ini, saya menggunakan dataset dari Kaggle yang berjudul “Heart Failure Prediction — Clinical Records”.

Dataset ini berisi rekam medis dari 5000 pasien yang mengalami gagal jantung, dikumpulkan selama periode tindak lanjut. Setiap profil pasien memiliki 13 fitur klinis, yang meliputi:

  • age: usia pasien (tahun)
  • anaemia: penurunan sel darah merah atau hemoglobin (boolean)
  • creatinine phosphokinase (CPK): tingkat enzim CPK dalam darah (mcg/L)
  • diabetes: apakah pasien menderita diabetes (boolean)
  • ejection fraction: persentase darah yang keluar dari jantung setiap kontraksi (persentase)
  • high blood pressure: apakah pasien menderita hipertensi (boolean)
  • platelets: jumlah trombosit dalam darah (kiloplatelets/mL)
  • sex: jenis kelamin (wanita atau pria)
  • serum creatinine: tingkat kreatinin serum dalam darah (mg/dL)
  • serum sodium: tingkat natrium serum dalam darah (mEq/L)
  • smoking: apakah pasien merokok atau tidak (boolean)
  • time: periode tindak lanjut (hari)
  • DEATH_EVENT: apakah pasien meninggal selama periode tindak lanjut (boolean)

Referensi dataset ini dapat ditemukan di Kaggle.

Dalam penelitian ini, saya menggunakan model machine learning untuk memprediksi gagal jantung berdasarkan fitur-fitur klinis tersebut. Hasil penelitian ini diharapkan dapat memberikan wawasan yang berharga dan membantu dalam pengembangan alat prediksi yang lebih akurat untuk penggunaan klinis.

Langkah-langkah dalam Kode

Import Libraries

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report, roc_auc_score, roc_curve
  • pandas: Digunakan untuk manipulasi dan analisis data.
  • numpy: Digunakan untuk operasi numerik.
  • matplotlib: Digunakan untuk visualisasi data.
  • seaborn: Digunakan untuk visualisasi data yang lebih menarik dan informatif.
  • sklearn.model_selection: Mengandung fungsi untuk split data menjadi set training dan testing, serta melakukan pencarian grid untuk hyperparameter tuning.
  • sklearn.ensemble: Mengandung implementasi model Random Forest.
  • sklearn.metrics: Mengandung metrik evaluasi model.

Load the Dataset

df = pd.read_csv('heart_failure_clinical_records.csv')  # replace 'path_to_your_dataset.csv' with the actual path
df.head()
  • df = pd.read_csv(): Membaca dataset dari file CSV ke dalam DataFrame pandas.
  • df.head(): Menampilkan lima baris pertama dari DataFrame untuk memastikan data ter-load dengan benar.

Check for Missing Values and Encode Categorical Variables

print(df.isnull().sum())
  • df.isnull().sum(): Mengecek apakah ada nilai yang hilang (missing values) dalam dataset. Hasilnya menunjukkan jumlah nilai yang hilang di setiap kolom.
df['sex'] = df['sex'].apply(lambda x: 1 if x == 'male' else 0)
  • df[‘sex’] = df[‘sex’].apply(lambda x: 1 if x == ‘male’ else 0): Mengubah nilai kolom ‘sex’ menjadi angka biner. Jika jenis kelamin adalah ‘male’ maka nilai 1, jika tidak (female) maka nilai 0.

Feature and Target Variables

X = df.drop(columns=['DEATH_EVENT'])
y = df['DEATH_EVENT']
  • X: Data fitur (input) dengan menghapus kolom target ‘DEATH_EVENT’.
  • y: Data target (output) yaitu kolom ‘DEATH_EVENT’.

Split the Dataset into Training and Testing Sets

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
  • train_test_split(): Membagi dataset menjadi set training dan testing dengan proporsi 80% training dan 20% testing. random_state=42 digunakan untuk memastikan hasil pembagian yang sama setiap kali dijalankan.

Initialize the Model and Define the Hyperparameters Grid

rf = RandomForestClassifier(random_state=42)
  • rf = RandomForestClassifier(random_state=42): Menginisialisasi model Random Forest dengan parameter acak yang ditetapkan untuk memastikan hasil yang konsisten.
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [None, 10, 20, 30],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
  • param_grid: Mendefinisikan grid hyperparameter untuk dicoba selama pencarian grid. Ini termasuk jumlah pohon dalam hutan (n_estimators), kedalaman maksimum pohon (max_depth), jumlah minimum sampel untuk memisahkan node (min_samples_split), dan jumlah minimum sampel pada daun (min_samples_leaf).

Perform Grid Search

grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, n_jobs=-1, scoring='accuracy')
grid_search.fit(X_train, y_train)
  • GridSearchCV: Melakukan pencarian grid untuk menemukan kombinasi hyperparameter terbaik berdasarkan kriteria yang ditentukan (di sini, akurasi). cv=5 berarti menggunakan validasi silang 5 kali lipat.
  • grid_search.fit(X_train, y_train): Melatih model dengan data training menggunakan semua kombinasi hyperparameter yang ditentukan dalam grid.
best_rf = grid_search.best_estimator_
print(f"Best parameters: {grid_search.best_params_}")
  • best_rf = grid_search.best_estimator_: Mendapatkan model terbaik berdasarkan pencarian grid.
  • print(f”Best parameters: {grid_search.best_params_}”): Menampilkan kombinasi hyperparameter terbaik yang ditemukan.

Make Predictions and Evaluate the Model

y_pred = best_rf.predict(X_test)
  • y_pred = best_rf.predict(X_test): Membuat prediksi berdasarkan data testing menggunakan model terbaik.
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
class_report = classification_report(y_test, y_pred)
roc_auc = roc_auc_score(y_test, best_rf.predict_proba(X_test)[:, 1])

print(f"Accuracy: {accuracy}")
print(f"Confusion Matrix:\n{conf_matrix}")
print(f"Classification Report:\n{class_report}")
print(f"ROC AUC Score: {roc_auc}")
  • accuracy_score: Menghitung akurasi prediksi.
  • confusion_matrix: Menghasilkan confusion matrix untuk melihat performa klasifikasi.
  • classification_report: Menyediakan metrik evaluasi yang lebih rinci termasuk precision, recall, dan F1-score.
  • roc_auc_score: Menghitung nilai AUC-ROC untuk mengukur performa model dalam membedakan kelas.

Output :

Accuracy: 0.992
Confusion Matrix:
[[692 6]
[ 2 300]]
Classification Report:
precision recall f1-score support

0 1.00 0.99 0.99 698
1 0.98 0.99 0.99 302

accuracy 0.99 1000
macro avg 0.99 0.99 0.99 1000
weighted avg 0.99 0.99 0.99 1000

ROC AUC Score: 0.9998576823089622

Plot ROC Curve

fpr, tpr, thresholds = roc_curve(y_test, best_rf.predict_proba(X_test)[:, 1])
plt.figure()
plt.plot(fpr, tpr, color='blue', label=f'ROC Curve (area = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='gray', linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic (ROC) Curve')
plt.legend(loc="lower right")
plt.show()
  • roc_curve: Menghitung False Positive Rate (FPR) dan True Positive Rate (TPR) untuk berbagai threshold.
  • plt.plot(): Membuat plot ROC curve berdasarkan FPR dan TPR. Garis abu-abu diagonal menunjukkan performa acak.
  • plt.xlabel(), plt.ylabel(), plt.title(), plt.legend(): Menambahkan label sumbu, judul, dan legenda pada plot

Output :

Receiver Operating Characteristic (ROC) Curve

Save the Model

import joblib

# Save the model to a file
joblib.dump(best_rf, 'heart_failure_prediction_model.pkl')
  • joblib.dump(): Menyimpan model terbaik ke dalam file untuk digunakan di masa depan.

Hasil

Berikut adalah analisis dari hasil yang dapatkan:

Accuracy: 0.992

  • Deskripsi: Akurasi model adalah 99.2%, yang berarti model ini berhasil mengklasifikasikan 99.2% dari semua kasus dengan benar.

Confusion Matrix:

[[692   6]
[ 2 300]]
  • True Negatives (TN): 692 — Jumlah kasus negatif yang diklasifikasikan dengan benar.
  • False Positives (FP): 6 — Jumlah kasus negatif yang salah diklasifikasikan sebagai positif.
  • False Negatives (FN): 2 — Jumlah kasus positif yang salah diklasifikasikan sebagai negatif.
  • True Positives (TP): 300 — Jumlah kasus positif yang diklasifikasikan dengan benar.

Classification Report:

  • Precision:
    Class 0:
    1.00
    Class 1: 0.98
  • Recall:
    Class 0:
    0.99
    Class 1: 0.99
  • F1-Score:
    Class 0:
    0.99
    Class 1: 0.99
  • Macro Average:
    Precision: 0.99
    Recall: 0.99
    F1-Score: 0.99
  • Weighted Average:
    Precision: 0.99
    Recall: 0.99
    F1-Score: 0.99

ROC AUC Score: 0.9998576823089622

  • Deskripsi: ROC AUC Score mendekati 1, yang menunjukkan bahwa model memiliki performa yang sangat baik dalam membedakan antara kelas positif dan negatif.

Kesimpulan:

  1. Akurasi Tinggi: Model ini menunjukkan akurasi yang sangat tinggi, yaitu 99.2%. Ini berarti model sangat efektif dalam memprediksi gagal jantung berdasarkan rekam medis klinis yang digunakan.
  2. Precision dan Recall: Nilai precision dan recall yang tinggi (mendekati 1) untuk kedua kelas (0 dan 1) menunjukkan bahwa model ini tidak hanya baik dalam mengidentifikasi pasien yang tidak mengalami gagal jantung (Class 0), tetapi juga sangat baik dalam mengidentifikasi pasien yang mengalami gagal jantung (Class 1).
  3. Confusion Matrix: Hanya ada sedikit kesalahan klasifikasi (6 false positives dan 2 false negatives), yang menunjukkan bahwa model ini sangat andal.
  4. ROC AUC Score: Nilai ROC AUC yang sangat tinggi menunjukkan kemampuan model dalam membedakan antara kelas positif dan negatif dengan sangat baik.

Secara keseluruhan, model ini menunjukkan performa yang sangat baik dan dapat diandalkan untuk prediksi gagal jantung berdasarkan dataset yang Anda miliki. Namun, disarankan untuk juga melakukan validasi silang (cross-validation) dan uji coba pada dataset yang berbeda untuk memastikan bahwa model ini tidak overfitting dan mampu menggeneralisasi dengan baik pada data yang belum pernah dilihat sebelumnya.

--

--