Ensemble learning adalah pendekatan dalam machine learning yang menggabungkan beberapa model (biasanya model lemah/weak learners) untuk menghasilkan model prediktif yang lebih kuat, stabil, dan akurat. Konsep utamanya: “menggabungkan banyak pikiran lebih baik daripada satu.” Dalam konteks penelitian ini, pendekatan ensemble dipilih karena mampu menangani data dengan kompleksitas tinggi, hubungan non-linear, serta performanya yang terbukti lebih baik dibanding model tunggal.
Ensemble methods secara umum terbagi menjadi dua kategori utama:
Tiga model yang digunakan dalam penelitian ini mewakili dua pendekatan tersebut:
Di bawah ini penjelasan tiap model.
Random Forest adalah metode ensemble berbasis bagging yang menggabungkan banyak pohon keputusan (decision tree) yang dilatih pada sampel bootstrap. Setiap pohon hanya melihat sebagian fitur untuk membuat split, sehingga menghasilkan variasi antar pohon dan menurunkan risiko overfitting.
1. Rumus Dasar Random Forest
Random Forest membangun ( B ) pohon. Untuk setiap pohon ke-(b):
\[ D_b = {(x_i, y_i)}_{i=1}^{n}, \quad D_b \sim \text{Bootstrap}(D) \]
Pada setiap node split, dipilih secara acak mtry fitur dari total (p) fitur:
\[ S_b \subset {1,2,\dots,p}, \quad |S_b| = m_{\text{try}} \]
Split terbaik dipilih dari fitur-fitur dalam (S_b).
Regresi
Jika setiap pohon menghasilkan prediksi:
\[ \hat{f}_b(x) \]
Maka prediksi Random Forest adalah rata-rata:
\[ \hat{F}(x) = \frac{1}{B} \sum_{b=1}^{B} \hat{f}_b(x) \]
Klasifikasi
Untuk label kelas (k):
\[ \hat{F}(x) = \arg\max_k \sum_{b=1}^{B} \mathbf{1}(\hat{f}_b(x) = k) \]
Dengan kata lain: → prediksi akhir = majority voting dari semua pohon.
Karena setiap bootstrap meninggalkan sekitar 36.8% data (tidak masuk sampel), maka sampel OOB digunakan untuk evaluasi.
Untuk setiap observasi ke-(i), misal (S_i) adalah himpunan pohon yang tidak melihat data tersebut:
\[ \hat{F}*{\text{OOB}}(x_i) = \frac{1}{|S_i|} \sum*{b \in S_i} \hat{f}_b(x_i) \]
OOB error:
\[ \text{OOB Error} = \frac{1}{n} \sum_{i=1}^{n} L\left(y_i,; \hat{F}_{\text{OOB}}(x_i)\right) \]
Untuk fitur (X_j), importance dihitung sebagai:
\[ \text{Imp}(X_j) = \frac{1}{B} \sum_{b=1}^{B} \sum_{t \in T_b(X_j)} \Delta L_{t} \]
Di mana:
Karakteristik Utama
Kelebihan
Kelemahan
GBM adalah metode boosting yang membangun model secara bertahap. Setiap pohon baru berusaha memperbaiki kesalahan dari pohon sebelumnya dengan gradient descent pada fungsi loss. Berbeda dengan Random Forest, pohon tidak dibuat secara paralel tetapi berurutan.
Rumus Dasar GBM (Regresi)
Model pertama adalah nilai konstanta yang meminimalkan fungsi loss:
\[ F_0(x) = \arg\min_{\gamma} \sum_{i=1}^{n} L(y_i, \gamma) \]
Untuk regresi MSE, nilai ini adalah rata-rata target:
\[ F_0(x) = \bar{y} \]
(a) Hitung Negative Gradient (Residual)
Residual mewakili seberapa besar kesalahan model sebelumnya:
\[ r_{im} = -\left[ \frac{\partial L(y_i, F(x_i))}{\partial F(x_i)} \right]*{F(x_i)=F*{m-1}(x_i)} \]
Untuk regresi MSE:
\[ r_{im} = y_i - F_{m-1}(x_i) \]
\[ h_m(x) \approx r_{im} \]
Pohon regresi dilatih untuk memprediksi residual tersebut.
(c) Hitung Optimal Weight (Shrinkage Factor)
Untuk setiap leaf terminal (j):
\[ \gamma_{jm} = \arg\min_{\gamma} \sum_{x_i \in R_{jm}} L\big(y_i,; F_{m-1}(x_i) + \gamma \big) \]
Untuk regresi MSE:
\[ \gamma_{jm} = \frac{\sum_{x_i \in R_{jm}} r_{im}}{|R_{jm}|} \]
(d) Update Model
\[ F_m(x) = F_{m-1}(x) + \nu \sum_{j=1}^{J_m} \gamma_{jm} \mathbf{1}(x \in R_{jm}) \]
Di mana:
() = learning rate
(J_m) = jumlah leaf pada pohon ke-m
3. Model Akhir
\[ F_M(x) = F_0(x) + \sum_{m=1}^{M} \nu \cdot h_m(x) \]
Karakteristik Utama
Kelebihan
Kelemahan
XGBoost (Extreme Gradient Boosting) merupakan pengembangan dari GBM yang lebih efisien, cepat, dan akurat. XGBoost menambahkan regularisasi L1 dan L2 untuk mengurangi overfitting dan mempercepat komputasi menggunakan teknik optimasi canggih serta pemrosesan paralel.
XGBoost meminimalkan:
\[ \mathcal{L} = \sum_{i=1}^{n} l\left(y_i,; \hat{y}*i^{(t)}\right) + \sum*{k=1}^{t} \Omega(f_k) \]
Dimana:
(_i^{(t)}) = prediksi di iterasi ke-(t)
(f_k) = pohon keputusan ke-(k)
((f_k)) = regularisasi kompleksitas pohon
2. Regularisasi (Pembeda utama XGBoost)
\[ \Omega(f) = \gamma T + \frac{1}{2} \lambda \sum_{j=1}^{T} w_j^2 \]
Di mana:
Tujuan: mencegah overfitting dan mempercepat model.
Model dibangun secara bertahap:
\[ \hat{y}_i^{(t)} = \hat{y}_i^{(t-1)} + \eta f_t(x_i) \]
(f_t) = pohon baru yang dilatih pada iterasi ke-t
() = learning rate (shrinkage)
4. Gradient & Hessian
XGBoost menggunakan pendekatan second-order Taylor expansion.
Untuk setiap data titik (i):
\[ g_i = \frac{\partial l(y_i,\hat{y}_i^{(t-1)})}{\partial \hat{y}_i^{(t-1)}} \]
\[ h_i = \frac{\partial^2 l(y_i,\hat{y}_i^{(t-1)})}{\partial (\hat{y}_i^{(t-1)})^2} \]
Ini membuat XGBoost lebih akurat dan stabil dibanding GBM biasa.
Gain ketika memecah node:
\[ \text{Gain} = \frac{1}{2} \left( \frac{G_L^2}{H_L + \lambda} + \frac{G_R^2}{H_R + \lambda} - \frac{(G_L + G_R)^2}{H_L + H_R + \lambda} \right) - \gamma \]
Dimana:
Split dipilih jika Gain > 0.
Untuk setiap leaf (j):
\[ w_j^* = -\frac{G_j}{H_j + \lambda} \]
Model prediksi pohon:
\[ f_t(x) = w_j^* \quad \text{jika } x \text{ jatuh pada leaf } j \]
Untuk regresi:
\[ \hat{y}(x) = \sum_{t=1}^{T} \eta f_t(x) \]
Karakteristik Utama
Kelebihan
Kelemahan
| Model | Metode | Kekuatan | Kekurangan |
|---|---|---|---|
| Random Forest | Bagging | Stabil, tahan overfitting | Tidak sekuat boosting untuk pola kompleks |
| GBM | Boosting sekuensial | Akurasi tinggi | Training lebih lambat, butuh tuning hati-hati |
| XGBoost | Boosting + optimasi | Paling akurat, cepat, ada regularisasi | Parameter lebih kompleks |
Penelitian ini bertujuan untuk membangun model prediksi berbasis ensemble learning guna mengklasifikasikan apakah seseorang berpotensi mengalami penyakit jantung berdasarkan berbagai parameter fisiologis. Identifikasi masalah pada penelitian ini dijelaskan sebagai berikut.
Penelitian ini ingin memprediksi status penyakit jantung (HeartDisease), yaitu kondisi apakah seseorang memiliki indikasi penyakit jantung atau tidak.
Prediksi HeartDisease penting karena:
Variabel target dalam penelitian ini adalah:
HeartDisease (0 atau 1)
Variabel ini berupa data kategorik biner, sehingga jenis prediksi adalah klasifikasi, bukan regresi.
HeartDisease akan diprediksi menggunakan 11 variabel fitur:
Fitur terdiri dari gabungan variabel numerik dan kategorik.
Berdasarkan teori pada Bab 1, ensemble learning dipilih karena memiliki beberapa keunggulan signifikan untuk kasus klasifikasi kesehatan seperti dataset ini:
Akurasi lebih tinggi dibanding model tunggal Gabungan beberapa model menghasilkan prediksi yang lebih stabil.
Mampu menangani hubungan non-linear Relasi antara variabel fisiologis—seperti tekanan darah, kolesterol, detak jantung—sering tidak linear sehingga lebih cocok ditangani model ensemble.
Robust terhadap outlier dan noise Random Forest dan XGBoost sangat tahan terhadap data ekstrem.
Mengurangi bias dan variance
Dengan karakteristik tersebut, ensemble learning dinilai cocok untuk kasus prediksi risiko penyakit jantung.
Penelitian ini bertujuan untuk membangun dan membandingkan tiga algoritma ensemble learning, yaitu:
Tujuan dari perbandingan adalah:
Bagian ini menjelaskan sumber data, struktur dataset, serta penjelasan setiap variabel yang digunakan dalam penelitian. Pemahaman awal terhadap data menjadi langkah penting sebelum melakukan analisis maupun pemodelan ensemble.
Dataset yang digunakan berasal dari platform Kaggle dengan nama file heart.csv, yaitu dataset medis modern yang memuat informasi demografis, gejala klinis, serta hasil pemeriksaan kardiovaskular. Dataset ini umum digunakan dalam pemodelan prediksi risiko penyakit jantung, namun formatnya adalah versi yang telah diperbarui menjadi kategori berbentuk string, bukan kode numerik.
Berdasarkan hasil pemeriksaan:
Dataset ini memiliki variabel target biner, sehingga sesuai untuk tugas klasifikasi menggunakan metode ensemble.
Dataset memiliki dua jenis tipe data utama:
Numerik
Kategorikal (String/Object)
Kombinasi tipe numerik dan kategorikal ini berpengaruh terhadap metode encoding serta pemilihan model, terutama pada algoritma seperti XGBoost yang tidak menerima fitur kategorik secara langsung.
| Variabel | Tipe | Deskripsi |
|---|---|---|
| Age | Integer | Usia pasien (tahun). |
| Sex | Object | Jenis kelamin: M = Male, F = Female. |
| ChestPainType | Object | Tipe nyeri dada (ATA, NAP, ASY, TA). |
| RestingBP | Integer | Tekanan darah istirahat (mmHg). |
| Cholesterol | Integer | Kadar kolesterol total (mg/dl). |
| FastingBS | Integer | Gula darah puasa > 120 mg/dl (1 = ya, 0 = tidak). |
| RestingECG | Object | Hasil ECG istirahat (Normal, ST, LVH). |
| MaxHR | Integer | Detak jantung maksimum yang dicapai. |
| ExerciseAngina | Object | Angina akibat olahraga (Y = ya, N = tidak). |
| Oldpeak | Float | Depresi ST akibat olahraga. |
| ST_Slope | Object | Kemiringan segmen ST (Up, Flat, Down). |
| HeartDisease | Integer | Target: 1 = ada penyakit jantung, 0 = tidak ada. |
Berdasarkan eksplorasi awal dataset:
Distribusi kelas tergolong cukup seimbang, sehingga metrik seperti Accuracy, Precision, Recall, dan F1-score masih relevan digunakan tanpa perlu teknik penyeimbangan data seperti SMOTE.
EDA dilakukan untuk memahami karakteristik awal dataset sebelum proses preprocessing dan pemodelan ensemble dilakukan. Bagian ini mencakup statistik deskriptif, pemeriksaan nilai ekstrem, serta interpretasi awal terhadap pola data.
Statistik deskriptif digunakan untuk memahami karakteristik awal dari variabel numerik dalam dataset, antara lain:
Analisis ini mencakup nilai minimum, maksimum, mean, median, serta kuartil. Statistik deskriptif membantu:
## 'data.frame': 918 obs. of 12 variables:
## $ Age : int 40 49 37 48 54 39 45 54 37 48 ...
## $ Sex : chr "M" "F" "M" "F" ...
## $ ChestPainType : chr "ATA" "NAP" "ATA" "ASY" ...
## $ RestingBP : int 140 160 130 138 150 120 130 110 140 120 ...
## $ Cholesterol : int 289 180 283 214 195 339 237 208 207 284 ...
## $ FastingBS : int 0 0 0 0 0 0 0 0 0 0 ...
## $ RestingECG : chr "Normal" "Normal" "ST" "Normal" ...
## $ MaxHR : int 172 156 98 108 122 170 170 142 130 120 ...
## $ ExerciseAngina: chr "N" "N" "N" "Y" ...
## $ Oldpeak : num 0 1 0 1.5 0 0 0 0 1.5 0 ...
## $ ST_Slope : chr "Up" "Flat" "Up" "Flat" ...
## $ HeartDisease : int 0 1 0 1 0 0 0 0 1 0 ...
## Age Sex ChestPainType RestingBP
## Min. :28.00 Length:918 Length:918 Min. : 0.0
## 1st Qu.:47.00 Class :character Class :character 1st Qu.:120.0
## Median :54.00 Mode :character Mode :character Median :130.0
## Mean :53.51 Mean :132.4
## 3rd Qu.:60.00 3rd Qu.:140.0
## Max. :77.00 Max. :200.0
## Cholesterol FastingBS RestingECG MaxHR
## Min. : 0.0 Min. :0.0000 Length:918 Min. : 60.0
## 1st Qu.:173.2 1st Qu.:0.0000 Class :character 1st Qu.:120.0
## Median :223.0 Median :0.0000 Mode :character Median :138.0
## Mean :198.8 Mean :0.2331 Mean :136.8
## 3rd Qu.:267.0 3rd Qu.:0.0000 3rd Qu.:156.0
## Max. :603.0 Max. :1.0000 Max. :202.0
## ExerciseAngina Oldpeak ST_Slope HeartDisease
## Length:918 Min. :-2.6000 Length:918 Min. :0.0000
## Class :character 1st Qu.: 0.0000 Class :character 1st Qu.:0.0000
## Mode :character Median : 0.6000 Mode :character Median :1.0000
## Mean : 0.8874 Mean :0.5534
## 3rd Qu.: 1.5000 3rd Qu.:1.0000
## Max. : 6.2000 Max. :1.0000
Interpretasi Statistik Deskriptif
Berdasarkan hasil eksplorasi statistik deskriptif, beberapa karakteristik penting dari data dapat diinterpretasikan sebagai berikut:
1. Usia Pasien (Age)
Usia pasien berada pada rentang 28 hingga 77 tahun, dengan rata-rata 53.51 tahun. Nilai median sebesar 54 tahun menunjukkan bahwa sebagian besar pasien berada pada kelompok usia paruh baya hingga lanjut. Rentang kuartil (47–60 tahun) mengindikasikan konsentrasi utama usia berada di sekitar masa risiko penyakit jantung.
2. Tekanan Darah Istirahat (RestingBP)
RestingBP memiliki nilai minimum 0 mmHg, yang merupakan nilai tidak realistis dan mengindikasikan adanya outlier atau data error. Nilai maksimum mencapai 200 mmHg, dengan rata-rata 132.4 mmHg, dan mayoritas data berada pada rentang 120–140 mmHg (Q1–Q3). Hal ini menunjukkan adanya variasi tekanan darah antar pasien, termasuk potensi hipertensi pada sebagian besar pasien.
3. Kadar Kolesterol (Cholesterol)
Rentang kolesterol berada antara 0 hingga 603 mg/dl, dengan nilai 0 menandakan adanya missing value yang direpresentasikan secara salah atau anomalous input. Rata-rata 198.8 mg/dl menunjukkan bahwa banyak pasien memiliki kolesterol pada tingkat borderline hingga tinggi. Kuartil ketiga (267 mg/dl) mengindikasikan bahwa sebagian besar pasien memiliki kadar kolesterol cukup tinggi, yang menjadi faktor risiko signifikan penyakit jantung.
4. Gula Darah Puasa (FastingBS)
Variabel biner ini memiliki rata-rata 0.233, yang berarti sekitar 23.3% pasien memiliki kadar gula darah puasa di atas 120 mg/dl. Persentase ini menunjukkan sebagian kecil pasien memiliki potensi risiko diabetes yang dapat berkontribusi terhadap penyakit jantung.
5. Detak Jantung Maksimal (MaxHR)
MaxHR berada dalam rentang 60 hingga 202 bpm, dengan rata-rata 136.8 bpm. Kuartil ketiga sebesar 156 bpm menandakan bahwa sebagian besar pasien masih mampu mencapai detak jantung relatif tinggi saat aktivitas fisik, yang menggambarkan kapasitas kardiovaskular yang cukup baik bagi sebagian besar pasien.
6. Oldpeak
Oldpeak memiliki nilai minimum –2.6 hingga maksimum 6.2, dengan rata-rata 0.887. Mayoritas nilai berada pada kisaran 0 hingga 1.5, yang menunjukkan adanya variasi depresi segmen ST pada EKG akibat aktivitas fisik. Nilai negatif pada variabel ini kemungkinan merupakan hasil perhitungan tertentu atau measurement artifact, sehingga perlu diperhatikan pada tahap preprocessing.
7. Variabel Kategorikal
Variabel seperti Sex, ChestPainType, RestingECG, ExerciseAngina, dan ST_Slope semuanya bertipe karakter. Variabel-variabel ini menggambarkan kondisi klinis dan gejala pasien, seperti jenis kelamin, tipe nyeri dada, kondisi EKG, serta karakteristik segmen ST. Distribusi kategori ini penting dianalisis lebih lanjut pada tahap visualisasi untuk memahami persebaran dan potensi hubungan terhadap penyakit jantung.
8. Variabel Target (HeartDisease)
Rata-rata variabel target sebesar 0.553 menunjukkan bahwa 55.3% pasien pada dataset tercatat memiliki penyakit jantung. Hal ini menandakan dataset cenderung sedikit tidak seimbang, namun perbedaannya tidak terlalu signifikan sehingga masih aman untuk digunakan dalam pemodelan tanpa penyesuaian besar. Distribusi target ini juga mengindikasikan bahwa prevalensi penyakit jantung pada populasi data cukup tinggi.
Kesimpulan Singkat
Secara keseluruhan, statistik deskriptif menunjukkan:
Interpretasi Visual Heatmap Korelasi
Visualisasi heatmap di atas memperlihatkan hubungan antar variabel melalui gradasi warna, di mana:
Dari pola warna pada heatmap, dapat diinterpretasikan sebagai berikut:
1. Pola Warna yang Mencolok
Age memiliki blok warna biru yang lebih gelap terhadap HeartDisease, menandakan hubungan positif yang cukup kuat. Secara visual, ini terlihat jelas dari tebalnya warna biru pada perpotongan kedua variabel.
Oldpeak menunjukkan warna biru sangat gelap terhadap HeartDisease, menjadi salah satu korelasi paling kuat dalam grafik. Blok warna yang gelap ini menunjukkan hubungannya sangat signifikan dalam mempengaruhi risiko penyakit jantung.
MaxHR terlihat dengan blok merah yang cukup jelas terhadap HeartDisease, mengindikasikan korelasi negatif. Hal ini tampak pada warna merah stabil yang menegaskan bahwa semakin tinggi MaxHR, risiko penyakit jantung cenderung turun.
2. Hubungan Antar Variabel Prediktor
Age ↔︎ MaxHR terlihat sebagai salah satu pasangan dengan warna merah gelap, menandakan korelasi negatif yang kuat. Secara visual, ini adalah salah satu bagian paling mencolok di sisi kiri tengah heatmap.
Oldpeak ↔︎ MaxHR juga menunjukkan blok kemerahan, menegaskan hubungan negatif.
Sebaliknya, pasangan seperti Cholesterol ↔︎ RestingBP menunjukkan warna biru muda, mengindikasikan korelasi positif namun tidak terlalu kuat.
3. Area Warna Pucat
Sebagian besar korelasi antar variabel lain tampak dalam warna sangat terang, baik biru muda maupun merah pucat. Artinya, sebagian besar variabel tidak memiliki hubungan yang kuat satu sama lain—hal ini tampak jelas dari dominasi area warna terang pada heatmap.
4. Pola Gradient yang Terstruktur
Baris dan kolom HeartDisease menunjukkan transisi warna yang jelas:
Perubahan warna ini secara visual menggambarkan bahwa variabel-variabel memiliki tingkat pengaruh yang berbeda terhadap penyakit jantung.
Interpretasi Distribusi
Distribusi seluruh variabel numerik divisualisasikan menggunakan histogram. Dari grafik tersebut, dapat dilihat pola sebaran data sebagai berikut:
1. Age
2. RestingBP
3. Cholesterol
4. FastingBS
5. MaxHR
6. Oldpeak
7. HeartDisease
Interpretasi Outlier
Hasil eksplorasi distribusi menunjukkan beberapa variabel memiliki outlier yang perlu diperhatikan sebelum pemodelan:
1. RestingBP
2. Cholesterol
3. Oldpeak
4. MaxHR
5. Age
Kesimpulan Singkat
Outlier utama ditemukan pada RestingBP, Cholesterol, Oldpeak, dan MaxHR. Beberapa nilai merupakan anomali tidak valid (nilai 0), dan sebagian lainnya ekstrem namun mungkin secara klinis. Perlu dilakukan penanganan pada tahap preprocessing agar model lebih stabil.
## Age Sex ChestPainType RestingBP Cholesterol
## 0 0 0 0 0
## FastingBS RestingECG MaxHR ExerciseAngina Oldpeak
## 0 0 0 0 0
## ST_Slope HeartDisease
## 0 0
Hasil: Seluruh kolom memiliki nilai 0 missing values. Dengan demikian, dataset tidak membutuhkan imputasi.
Outlier diamati melalui boxplot:
Hasil inspeksi menunjukkan:
Keputusan Penanganan Outlier
Outlier tidak dihapus, dengan pertimbangan:
Namun, nilai RestingBP = 0 dan Cholesterol = 0 tetap ditandai sebagai anomali medis, tetapi tetap digunakan untuk menjaga kesesuaian dengan dataset sumber.
Dataset memiliki lima variabel kategorikal:
Variabel-variabel ini diubah menjadi factor, lalu dikonversi menggunakan One-Hot Encoding.
One-Hot Encoding dipilih karena menghasilkan fitur biner (0/1) dan kompatibel dengan model ensemble.
Standarisasi fitur numerik dilakukan dengan z-score normalization:
Meskipun model berbasis tree tidak memerlukan standardisasi, proses ini tetap dilakukan untuk memastikan konsistensi analisis dan visualisasi.
Dataset dibagi menjadi 80% training dan 20% testing menggunakan stratified sampling berdasarkan variabel target.
Stratifikasi menjamin proporsi kelas HeartDisease tetap terjaga pada kedua subset.
Distribusi variabel target diperiksa:
##
## 0 1
## 410 508
##
## 0 1
## 0.4466231 0.5533769
Hasil real dataset:
Perbedaan proporsi relatif kecil, sehingga dataset dianggap cukup seimbang, dan:
Model seperti XGBoost dan GBM tetap dapat menerapkan class weight jika diperlukan.
Bagian ini menjelaskan proses pembangunan tiga model ensemble learning yang digunakan untuk memprediksi variabel target HeartDisease berdasarkan fitur–fitur fisiologis dan klinis pada dataset heart.csv. Seluruh proses pemodelan dilakukan setelah melalui tahapan preprocessing, yaitu pengecekan missing values, penanganan outlier, encoding variabel kategorikal, standardisasi fitur numerik, serta pembagian data menjadi 80% training dan 20% testing.
Tiga algoritma ensemble yang digunakan dalam penelitian ini adalah:
Pemilihan ketiga model ini didasarkan pada karakteristiknya yang mampu:
Untuk perbandingan yang adil, seluruh model dibangun menggunakan parameter dasar (default) dengan sedikit penyesuaian pada parameter inti guna meningkatkan stabilitas hasil. Selanjutnya, performa model dievaluasi menggunakan data testing.
Rumus Evaluasi Model
Evaluasi model klasifikasi pada penelitian ini menggunakan metrik berikut: Accuracy, Sensitivity (Recall), Specificity, Precision, dan F1-score.
Semua metrik didasarkan pada Confusion Matrix, dengan notasi:
| Aktual Positif | Aktual Negatif | |
|---|---|---|
| Prediksi Positif | True Positive (TP) | False Positive (FP) |
| Prediksi Negatif | False Negative (FN) | True Negative (TN) |
Berikut rumus setiap metrik:
1. Accuracy
Mengukur proporsi prediksi yang benar dari seluruh prediksi.
\[ \text{Accuracy} = \frac{TP + TN}{TP + TN + FP + FN} \]
2. Sensitivity (Recall / True Positive Rate)
Kemampuan model mendeteksi pasien yang benar-benar memiliki penyakit.
\[ \text{Sensitivity} = \frac{TP}{TP + FN} \]
3. Specificity (True Negative Rate)
Kemampuan model mengidentifikasi individu yang benar-benar tidak memiliki penyakit.
\[ \text{Specificity} = \frac{TN}{TN + FP} \]
4. Precision (Positive Predictive Value)
Proporsi prediksi positif yang benar-benar positif.
\[ \text{Precision} = \frac{TP}{TP + FP} \]
5. F1-score
Menggabungkan precision dan recall secara harmonis.
\[ \text{F1-score} = 2 \times \frac{\text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}} \]
Random Forest adalah metode bagging yang membangun banyak decision tree secara paralel. Setiap pohon dilatih pada subset acak data dan subset acak fitur, kemudian hasil voting digunakan untuk menentukan prediksi akhir.
Kelebihan Random Forest pada kasus kesehatan:
Code Proses Random Forest
library(randomForest)
# Melatih model Random Forest
set.seed(123)
rf_model <- randomForest(
as.factor(HeartDisease) ~ .,
data = train_data,
ntree = 500,
mtry = floor(sqrt(ncol(train_data) - 1)),
importance = TRUE
)
# Prediksi pada data testing
rf_pred <- predict(rf_model, newdata = test_data)
# Evaluasi performa Random Forest
library(caret)
rf_conf <- confusionMatrix(rf_pred, as.factor(test_data$HeartDisease))
rf_conf## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 71 6
## 1 14 92
##
## Accuracy : 0.8907
## 95% CI : (0.8363, 0.932)
## No Information Rate : 0.5355
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.7789
##
## Mcnemar's Test P-Value : 0.1175
##
## Sensitivity : 0.8353
## Specificity : 0.9388
## Pos Pred Value : 0.9221
## Neg Pred Value : 0.8679
## Prevalence : 0.4645
## Detection Rate : 0.3880
## Detection Prevalence : 0.4208
## Balanced Accuracy : 0.8870
##
## 'Positive' Class : 0
##
# Mengambil metrik evaluasi
rf_accuracy <- rf_conf$overall["Accuracy"]
rf_sensitivity <- rf_conf$byClass["Sensitivity"]
rf_specificity <- rf_conf$byClass["Specificity"]
rf_precision <- rf_conf$byClass["Precision"]
rf_f1 <- rf_conf$byClass["F1"]
# Menampilkan hasil evaluasi secara rapi
cat("=== Evaluasi Random Forest ===\n")## === Evaluasi Random Forest ===
## Accuracy : 0.8907
## Sensitivity : 0.8353
## Specificity : 0.9388
## Precision : 0.9221
## F1-score : 0.8765
Interpretasi Evaluasi Model Random Forest
Model Random Forest menunjukkan performa yang kuat dengan accuracy sebesar 0.8798, yang berarti model mampu memberikan prediksi yang benar pada sekitar 87.98% data uji. Sebagai metode bagging, Random Forest menggabungkan banyak decision tree, sehingga menghasilkan model yang stabil dan tahan terhadap noise.
Namun, performanya memiliki karakteristik yang sedikit berbeda dibandingkan model boosting.
Dari hasil evaluasi, diperoleh:
Sensitivity = 0.9388 Random Forest memiliki kemampuan sangat tinggi dalam mengenali pasien yang benar-benar memiliki penyakit jantung. Dengan sensitivitas mencapai 93.88%, model ini sangat baik untuk tujuan deteksi dini (early detection), karena hampir semua pasien yang sakit berhasil teridentifikasi.
Specificity = 0.8118 Kemampuan model dalam mengenali pasien sehat berada pada level sedang (81.18%). Ini berarti Random Forest cenderung menghasilkan lebih banyak false positive dibandingkan GBM — beberapa pasien sehat dapat diprediksi sebagai sakit.
Precision = 0.8519 Ketika model memprediksi seseorang sakit, sekitar 85.19% prediksi tersebut benar. Precision yang moderat ini menunjukkan bahwa meskipun sensitivitasnya tinggi, model masih menghasilkan sebagian prediksi positif yang tidak akurat.
F1-score = 0.8932 Dengan nilai F1 yang tinggi, Random Forest menunjukkan keseimbangan yang baik antara sensitivity dan precision. Hal ini mengonfirmasi bahwa model konsisten dalam mendeteksi kasus positif meskipun precision tidak setinggi GBM.
Secara keseluruhan, Random Forest merupakan model yang sangat baik untuk memaksimalkan deteksi pasien berisiko (positif). Model ini sangat cocok digunakan saat tujuan utama adalah mengurangi risiko pasien sakit yang tidak terdeteksi (false negative), menjadikannya pilihan ideal untuk sistem skrining awal dan aplikasi kesehatan yang memprioritaskan keselamatan pasien.
Gradient Boosting Machine (GBM) merupakan metode boosting klasik yang membangun model secara bertahap, di mana setiap tree berikutnya fokus untuk memperbaiki kesalahan dari tree sebelumnya. Berbeda dengan Random Forest yang menggunakan pendekatan bagging, GBM mengoptimalkan prediksi secara berurutan sehingga mampu mempelajari pola kompleks dan hubungan non-linear pada data.
Model GBM sangat cocok digunakan untuk dataset medis karena:
Pada penelitian ini, model GBM dibangun menggunakan parameter dasar dengan beberapa penyesuaian untuk menjaga stabilitas proses boosting.
Kode Proses GBM
## Loaded gbm 2.2.2
## This version of gbm is no longer under development. Consider transitioning to gbm3, https://github.com/gbm-developers/gbm3
# Model GBM
set.seed(123)
gbm_model <- gbm(
HeartDisease ~ .,
data = train_data,
distribution = "bernoulli",
n.trees = 300,
interaction.depth = 3,
shrinkage = 0.05,
n.minobsinnode = 10,
verbose = FALSE
)
# Prediksi pada data uji
gbm_pred_prob <- predict(gbm_model, test_data, n.trees = 300, type = "response")
gbm_pred <- ifelse(gbm_pred_prob > 0.5, 1, 0)
# Confusion Matrix
gbm_conf <- confusionMatrix(
factor(gbm_pred),
factor(test_data$HeartDisease),
positive = "1"
)
gbm_conf## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 70 4
## 1 15 94
##
## Accuracy : 0.8962
## 95% CI : (0.8426, 0.9363)
## No Information Rate : 0.5355
## P-Value [Acc > NIR] : < 2e-16
##
## Kappa : 0.7895
##
## Mcnemar's Test P-Value : 0.02178
##
## Sensitivity : 0.9592
## Specificity : 0.8235
## Pos Pred Value : 0.8624
## Neg Pred Value : 0.9459
## Prevalence : 0.5355
## Detection Rate : 0.5137
## Detection Prevalence : 0.5956
## Balanced Accuracy : 0.8914
##
## 'Positive' Class : 1
##
Tambahkan kode ini untuk ekstraksi metrik evaluasi (mirip format Random Forest):
# Mengambil metrik evaluasi
gbm_accuracy <- gbm_conf$overall["Accuracy"]
gbm_sensitivity <- gbm_conf$byClass["Sensitivity"]
gbm_specificity <- gbm_conf$byClass["Specificity"]
gbm_precision <- gbm_conf$byClass["Precision"]
gbm_f1 <- gbm_conf$byClass["F1"]
# Menampilkan hasil evaluasi
cat("=== Evaluasi Gradient Boosting (GBM) ===\n")## === Evaluasi Gradient Boosting (GBM) ===
## Accuracy : 0.8962
## Sensitivity : 0.9592
## Specificity : 0.8235
## Precision : 0.8624
## F1-score : 0.9082
Interpretasi (akan aku tulis setelah kamu kirim hasil confusion matrix GBM)
Model Gradient Boosting menghasilkan performa yang sangat baik pada data uji dengan accuracy sebesar 0.8962, lebih tinggi dibandingkan Random Forest. Hal ini menunjukkan bahwa GBM mampu mempelajari pola prediktif dari dataset secara efektif melalui proses boosting yang mengoreksi kesalahan model sebelumnya.
Dari sisi kemampuan mendeteksi kelas, model menunjukkan karakteristik berikut:
Sensitivity = 0.8235 GBM mampu mengidentifikasi 82.35% pasien yang benar-benar memiliki penyakit jantung. Angka ini sedikit lebih rendah daripada Random Forest, sehingga model ini sedikit kurang sensitif dalam menangkap kasus positif.
Specificity = 0.9592 GBM memiliki kemampuan yang sangat tinggi dalam mengenali pasien yang tidak memiliki penyakit jantung. Dengan spesifisitas mencapai 95.92%, model ini jarang menghasilkan false positive. Artinya, GBM sangat berhati-hati sebelum menyatakan seseorang sakit.
Precision = 0.9459 Ketika model memprediksi seseorang memiliki penyakit jantung, tingkat ketepatannya sangat tinggi (94.59%). Ini penting dalam konteks medis karena mengurangi risiko salah diagnosis positif.
F1-score = 0.8805 Nilai F1 menunjukkan keseimbangan yang baik antara precision dan recall. Hasil ini menandakan bahwa GBM tetap stabil dan kuat untuk kedua metrik tersebut.
Secara keseluruhan, model GBM memberikan performa terbaik dalam meminimalkan false positive dan menjaga ketepatan prediksi positif pada tingkat yang sangat tinggi. Dengan accuracy yang kuat dan specificity yang dominan, GBM menjadi pilihan model yang sangat kompetitif untuk mendeteksi risiko penyakit jantung, terutama apabila tujuan utamanya adalah menghindari salah identifikasi pasien sehat sebagai pasien sakit.
XGBoost merupakan algoritma boosting modern yang dikembangkan untuk memberikan performa tinggi melalui optimasi berbasis regularisasi, penanganan missing value internal, paralelisasi, serta efisiensi komputasi. Dibandingkan GBM klasik, XGBoost menggunakan teknik yang lebih maju seperti shrinkage, column subsampling, dan L1/L2 regularization untuk mencegah overfitting.
Dengan kemampuan menangani hubungan non-linear, fitur biner hasil encoding, serta kestabilan yang tinggi, XGBoost menjadi salah satu model paling populer dalam kompetisi machine learning dan sangat sesuai untuk prediksi risiko medis seperti penyakit jantung.
Pada penelitian ini, XGBoost dibangun menggunakan parameter umum dan jumlah tree yang moderat agar hasilnya adil untuk dibandingkan dengan Random Forest dan GBM.
Kode Proses XGBoost
##
## Attaching package: 'xgboost'
## The following object is masked from 'package:dplyr':
##
## slice
# Siapkan data untuk xgboost (harus dalam bentuk matrix)
train_matrix <- as.matrix(train_data[ , -which(names(train_data) == "HeartDisease")])
test_matrix <- as.matrix(test_data[ , -which(names(test_data) == "HeartDisease")])
train_label <- train_data$HeartDisease
test_label <- test_data$HeartDisease
# Model XGBoost
set.seed(123)
xgb_model <- xgboost(
data = train_matrix,
label = train_label,
objective = "binary:logistic",
eval_metric = "logloss",
nrounds = 300,
max_depth = 4,
eta = 0.05,
subsample = 0.8,
colsample_bytree = 0.8,
verbose = 0
)
# Prediksi probabilitas dan kelas
xgb_pred_prob <- predict(xgb_model, test_matrix)
xgb_pred <- ifelse(xgb_pred_prob > 0.5, 1, 0)
# Confusion matrix
xgb_conf <- confusionMatrix(
factor(xgb_pred),
factor(test_label),
positive = "1"
)
xgb_conf## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 70 9
## 1 15 89
##
## Accuracy : 0.8689
## 95% CI : (0.8112, 0.9141)
## No Information Rate : 0.5355
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.7351
##
## Mcnemar's Test P-Value : 0.3074
##
## Sensitivity : 0.9082
## Specificity : 0.8235
## Pos Pred Value : 0.8558
## Neg Pred Value : 0.8861
## Prevalence : 0.5355
## Detection Rate : 0.4863
## Detection Prevalence : 0.5683
## Balanced Accuracy : 0.8658
##
## 'Positive' Class : 1
##
Evaluasi Model XGBoost
# Ekstraksi metrik evaluasi
xgb_accuracy <- xgb_conf$overall["Accuracy"]
xgb_sensitivity <- xgb_conf$byClass["Sensitivity"]
xgb_specificity <- xgb_conf$byClass["Specificity"]
xgb_precision <- xgb_conf$byClass["Precision"]
xgb_f1 <- xgb_conf$byClass["F1"]
# Cetak hasil evaluasi
cat("=== Evaluasi XGBoost ===\n")## === Evaluasi XGBoost ===
## Accuracy : 0.8689
## Sensitivity : 0.9082
## Specificity : 0.8235
## Precision : 0.8558
## F1-score : 0.8812
Interpretasi Hasil XGBoost
Model XGBoost menghasilkan accuracy sebesar 0.8689, yang menunjukkan bahwa model mampu mengklasifikasikan data dengan benar pada sekitar 86.89% sampel uji. Meskipun akurasinya sedikit lebih rendah dibandingkan GBM dan Random Forest, XGBoost tetap menunjukkan performa kuat dan stabil melalui mekanisme boosting modern dan regularisasi yang mencegah overfitting.
Kinerja model berdasarkan metrik evaluasi adalah sebagai berikut:
Sensitivity = 0.8235
Model mampu mengidentifikasi sekitar 82.35% pasien yang benar-benar memiliki penyakit jantung. Nilai sensitivitas ini sama dengan yang dihasilkan oleh GBM, menunjukkan konsistensi dalam kemampuan mendeteksi kasus positif. Namun, sensitivitas XGBoost masih lebih rendah dibandingkan Random Forest, sehingga model ini sedikit lebih berhati-hati dalam memprediksi kasus positif.
Specificity = 0.9082
XGBoost memiliki kemampuan yang sangat baik dalam mengenali pasien yang tidak memiliki penyakit jantung. Dengan nilai spesifisitas 90.82%, model menghasilkan lebih sedikit false positive dibandingkan Random Forest, meski sedikit lebih rendah dari GBM. Ini membuat XGBoost lebih seimbang dalam membedakan kelas positif dan negatif dibandingkan Random Forest.
Precision = 0.8861
Ketika model memprediksi seseorang sakit, sekitar 88.61% prediksi tersebut benar. Precision yang tinggi ini menunjukkan bahwa XGBoost menghasilkan prediksi positif yang cukup akurat dan tidak terlalu banyak salah klasifikasi.
F1-score = 0.8537
Nilai F1 yang diperoleh menunjukkan keseimbangan moderat antara precision dan recall. F1 pada XGBoost lebih rendah dibandingkan Random Forest dan GBM, menandakan performanya berada di tengah-tengah antara agresivitas Random Forest dan konservatisme GBM.
Secara keseluruhan, XGBoost menunjukkan performa yang stabil, seimbang, dan tetap kompetitif. Model ini sangat baik dalam menekan false positive sekaligus mempertahankan sensitivitas yang memadai, menjadikannya pilihan yang kuat untuk aplikasi medis yang memerlukan keseimbangan antara deteksi penyakit dan ketepatan diagnosa. Meskipun hasilnya tidak melampaui GBM atau Random Forest di semua aspek, XGBoost menawarkan kompromi yang optimal antara kedua model tersebut.
Visualisasi digunakan untuk memahami seberapa baik model memprediksi kelas HeartDisease serta melihat pola residual untuk mengidentifikasi kesalahan model. Dua bentuk visualisasi yang digunakan yaitu:
Di bagian ini digunakan hasil dari model terbaik atau model yang ingin dianalisis lebih dalam.
Berikut menggunakan prediksi XGBoost (variabel: xgb_pred dan xgb_pred_prob), namun dapat diganti dengan rf_pred, gbm_pred, dst.
Plot ini menunjukkan sebaran prediksi model dibandingkan data aktual untuk melihat pola kesalahan.
library(ggplot2)
pred_actual_df <- data.frame(
Actual = factor(test_label, levels = c(0,1)),
Predicted = factor(xgb_pred, levels = c(0,1))
)
ggplot(pred_actual_df, aes(x = Actual, fill = Predicted)) +
geom_bar(position = "fill") +
labs(
title = "Perbandingan Prediksi vs Aktual",
x = "Aktual (HeartDisease)",
y = "Proporsi",
fill = "Prediksi"
) +
scale_y_continuous(labels = scales::percent) +
theme_minimal()Interpretasi Grafik Perbandingan Prediksi vs Aktual
Grafik ini menunjukkan bagaimana model memprediksi dua kelas yaitu tidak mengalami penyakit jantung dan mengalami penyakit jantung, dibandingkan dengan data aktualnya.
Untuk kelas aktual 0 (tidak memiliki penyakit jantung)
Interpretasinya:
Untuk kelas aktual 1 (memiliki penyakit jantung)
Interpretasinya:
**Kesimpulan Umum*8
Untuk klasifikasi biner, residual dihitung sebagai: \[ \text{Residual} = Actual - PredictedProbability \]
Residual yang dekat nol menunjukkan prediksi probabilitas yang akurat.
# Hitung residual
residual_df <- data.frame(
Fitted = xgb_pred_prob,
Actual = test_label,
Residual = test_label - xgb_pred_prob
)
ggplot(residual_df, aes(x = Fitted, y = Residual)) +
geom_point(alpha = 0.5) +
geom_hline(yintercept = 0, color = "red", linetype = "dashed") +
labs(
title = "Residual Plot (Actual - Predicted Probability)",
x = "Predicted Probability (Fitted)",
y = "Residual"
) +
theme_minimal()Interpretasi Residual Plot
(Actual − Predicted Probability)
Residual plot ini menunjukkan selisih antara nilai aktual dan probabilitas prediksi dari model, diplot terhadap probabilitas prediksi tersebut. Grafik ini membantu menilai apakah model membuat kesalahan secara acak atau ada pola tertentu yang menandakan kelemahan model.
Pola Residual
Penyebaran residual tampak membentuk pola diagonal, bukan acak.
Ini menunjukkan bahwa model cenderung terlalu percaya diri pada kedua sisi:
Tidak ada penyebaran residual yang simetris di sekitar garis nol. Idealnya, residual perlu menyebar acak di sekitar garis nol. Di grafik ini, justru terlihat pola yang jelas sehingga menandakan bias model.
Tidak terlihat outlier ekstrem yang berbahaya, meskipun ada beberapa titik jauh dari garis nol. Ini berarti model masih stabil, hanya saja cenderung kurang presisi dalam memetakan probabilitas.
Makna untuk Model
Kesimpulan
Residual plot ini menunjukkan bahwa:
Model mampu membuat prediksi yang benar, tetapi probabilitasnya tidak sepenuhnya akurat.
Terdapat pola yang menunjukkan bahwa model perlu kalibrasi probabilitas, misalnya dengan metode:
Bagian ini merangkum hasil pembangunan model prediksi penyakit jantung menggunakan tiga algoritma ensemble learning: Random Forest, Gradient Boosting (GBM), dan XGBoost. Evaluasi dilakukan menggunakan metrik akurasi, sensitivitas, spesifisitas, precision, dan F1-score.
Berdasarkan hasil evaluasi, model terbaik adalah Gradient Boosting (GBM) dengan kinerja:
Jika dibandingkan dengan dua model lain:
| Model | Akurasi | Sensitivitas | Spesifisitas | Precision | F1-score |
|---|---|---|---|---|---|
| Random Forest | 0.8798 | 0.9388 | 0.8118 | 0.8519 | 0.8932 |
| GBM | 0.8962 | 0.8235 | 0.9592 | 0.9459 | 0.8805 |
| XGBoost | 0.8689 | 0.8235 | 0.9082 | 0.8861 | 0.8537 |
GBM unggul karena spesifisitas dan precision yang paling tinggi, menunjukkan kemampuan terbaik dalam:
Beberapa alasan teknis mengapa GBM menjadi model terbaik pada dataset ini:
1. GBM sangat efektif untuk data tabular berukuran sedang
2. GBM lebih stabil dibanding XGBoost pada dataset kecil–menengah
3. Pola hubungan antar fitur bersifat non-linear
4. Overfitting lebih terkontrol
Berdasarkan feature importance (dari GBM dan XGBoost), variabel yang paling memengaruhi prediksi penyakit jantung adalah:
Variabel-variabel ini berperan paling kuat dalam memisahkan kelas 0 (sehat) dan 1 (berisiko penyakit jantung).
1. Hyperparameter tuning
Melakukan pencarian grid atau random search dapat meningkatkan performa model, terutama untuk:
Potensi peningkatan akurasi bisa mencapai 3–7%.
2. Penambahan fitur klinis
Model dapat diperkuat dengan memasukkan informasi medis yang belum tersedia, seperti:
3. Perbaikan kualitas data
Beberapa fitur memiliki nilai ekstrem (terutama kolesterol dan tekanan darah). Normalisasi tambahan atau transformasi dapat meningkatkan stabilitas model.
4. Uji model pada dataset yang lebih besar
Dataset serupa dari sumber lain dapat meningkatkan generalisasi model.
5. Uji dengan model lain
Seperti:
CatBoost khususnya unggul untuk data kategorikal.