Perkembangan machine learning (ML) telah mendorong pemanfaatan berbagai metode pemodelan prediktif untuk mengolah data dan mendukung pengambilan keputusan di berbagai bidang. Salah satu metode yang banyak digunakan adalah ensemble learning, yaitu pendekatan yang menggabungkan beberapa model pembelajaran untuk menghasilkan prediksi yang lebih baik. Berdasarkan studi bibliometrik Lundberg et al. (2024), algoritma dan aplikasi merupakan dua arah penelitian terbesar dalam bidang machine learning. Penelitian tersebut juga menunjukkan bahwa metode ensemble menjadi salah satu kelompok algoritma yang banyak dikaji dan mengalami perkembangan yang cukup menonjol. Salah satu metode dalam pendekatan ini adalah Boosting, yang bekerja dengan membangun model secara bertahap, dengan setiap model berikutnya berupaya memperbaiki kesalahan prediksi dari model sebelumnya. Pendekatan tersebut memungkinkan penggabungan sejumlah weak learner menjadi model yang memiliki kemampuan prediksi lebih baik. Dalam penerapannya, metode Boosting dapat digunakan untuk berbagai permasalahan, baik klasifikasi maupun regresi.
Meskipun memiliki kemampuan prediksi yang baik, kinerja metode Boosting dapat berbeda bergantung pada karakteristik data dan algoritma yang digunakan. Ahn et al. (2023), misalnya, membandingkan algoritma XGBoost, LightGBM, dan CatBoost dalam peramalan harmful algal blooms. Hasil penelitian menunjukkan bahwa nilai koefisien determinasi (\(R^2\)) yang diperoleh masing-masing algoritma adalah 0,92 untuk XGBoost, 0,93 untuk LightGBM, dan 0,89 untuk CatBoost. Hasil tersebut memperlihatkan bahwa setiap algoritma dapat memberikan kinerja yang berbeda pada permasalahan yang sama. Perbedaan tersebut menunjukkan pentingnya memahami karakteristik dan mekanisme kerja metode Boosting sebelum menerapkannya pada suatu permasalahan. Selain itu, pemilihan algoritma dan pengaturan hiperparameter perlu disesuaikan dengan karakteristik data agar model dapat menghasilkan prediksi yang optimal.
Penerapan metode Boosting juga memerlukan proses evaluasi untuk mengetahui sejauh mana model mampu menghasilkan prediksi yang sesuai dengan nilai aktual. Evaluasi tersebut perlu menggunakan ukuran yang disesuaikan dengan jenis permasalahan yang dianalisis. Pada kasus klasifikasi, evaluasi dapat dilakukan menggunakan accuracy, precision, recall, F1-score, dan AUC-ROC untuk menilai kemampuan model dalam mengklasifikasikan data. Sementara itu, pada kasus regresi, evaluasi dapat menggunakan Mean Absolute Error (MAE), Mean Squared Error (MSE), Root Mean Squared Error (RMSE), dan koefisien determinasi (\(R^2\)) untuk mengukur tingkat kesalahan prediksi dan kemampuan model dalam menjelaskan variasi data. Jiang et al. (2025) menekankan pentingnya penggunaan metrik evaluasi yang sesuai, khususnya ketika data memiliki distribusi kelas yang tidak seimbang. Dengan demikian, penilaian kinerja model tidak cukup hanya didasarkan pada satu ukuran evaluasi, tetapi perlu mempertimbangkan karakteristik permasalahan dan tujuan pemodelan.
Berdasarkan uraian tersebut, pemahaman mengenai metode Boosting menjadi penting dalam penerapan machine learning, terutama untuk menyelesaikan permasalahan klasifikasi dan regresi. Melalui praktikum ini, metode Boosting dipelajari mulai dari konsep dasar sebagai bagian dari ensemble learning, implementasinya menggunakan perangkat lunak R, hingga evaluasi kinerja model dengan ukuran yang sesuai. Kegiatan ini diharapkan dapat membantu mahasiswa memahami mekanisme kerja metode Boosting, menerapkannya pada berbagai jenis permasalahan prediksi, serta menginterpretasikan hasil evaluasi untuk mengetahui kelebihan dan keterbatasan model yang digunakan. Dengan demikian, mahasiswa dapat memperoleh pemahaman yang lebih menyeluruh mengenai penggunaan metode Boosting dalam analisis data berbasis machine learning.
Berdasarkan latar belakang, rumusan masalah yang dapat disimpulkan yaitu sebagai berikut:
Berdasarkan rumusan masalah, tujuan yang dapat disimpulkan yaitu sebagai berikut:
Adapun manfaat pada penelitian ini yaitu:
Bagi penulis:
Bagi pembaca:
Adapun batasan masalah pada penelitian ini yaitu, Lakukan analisis
Boosting klasifikasi menggunakan AdaBoost pada data
BreastCancer secara lengkap mulai dari persiapan data,
pembentukan model, prediksi, evaluasi, visualisasi, dan interpretasi.
Gunakan set.seed(234) agar hasil pembagian data dapat
direproduksi. Clue: Gunakan adabag::boosting()
dengan decision stump sebagai weak learner. Bandingkan
untuk 50, 100 dan 200 jumlah learner. Bandingkan pula performa
model berdasarkan confusion matrix, Accuracy,
Precision, Recall, Specificity, dan
F1-score.
Adapun sistematika penulisan dari praktikum ini adalah:
BAB I PENDAHULUAN
Bab ini merupakan bab yang memuat latar belakang, rumusan masalah, tujuan dan manfaat, batasan masalah dan sistematika penulisan.
BAB II TINJAUAN PUSTAKA
Bab ini merupakan bab yang memuat pengertian dan teori yang diperlukan untuk rancangan penelitian pada bab-bab berikutnya.
BAB III METODE PENELITIAN
Bab ini merupakan bab yang memuat jenis dan sumber data, variabel penelitian, dan analisis data yang diperlukan untuk rancangan penelitian pada bab-bab berikutnya.
BAB IV HASIL DAN PEMBAHASAN
Bab ini merupakan bab yang memuat hasil dan pembahasan yang telah dilakukan pada program, kemudian diinterpretasikan untuk rancangan penelitian pada bab-bab berikutnya.
BAB V KESIMPULAN DAN SARAN
Bab ini merupakan bab yang memuat kesimpulan dan saran yang telah dilakukan.
DAFTAR PUSTAKA
Machine learning merupakan pendekatan dalam ilmu komputer yang memungkinkan sistem mempelajari pola dan hubungan dari data untuk menghasilkan prediksi atau keputusan. Proses pembelajaran dilakukan dengan membangun model berdasarkan data yang tersedia, sehingga model tersebut dapat digunakan untuk menganalisis pengamatan baru. Kemampuan model dalam menghasilkan prediksi dipengaruhi oleh karakteristik data, pemilihan metode, serta proses evaluasi yang dilakukan.
Salah satu pendekatan dalam machine learning adalah supervised learning, yaitu pembelajaran menggunakan data yang memiliki variabel prediktor dan variabel respons. Variabel prediktor digunakan sebagai dasar untuk memperkirakan nilai variabel respons. Berdasarkan jenis variabel responsnya, supervised learning dibedakan menjadi klasifikasi dan regresi. Klasifikasi digunakan ketika variabel respons berbentuk kategori, sedangkan regresi digunakan ketika variabel respons berbentuk numerik.
Salah satu metode supervised learning adalah Decision Tree. Metode ini membentuk model prediksi melalui serangkaian aturan pemisahan data berdasarkan variabel prediktor. Hasil pemodelannya berupa struktur pohon yang menunjukkan proses pengambilan keputusan dari simpul awal hingga simpul akhir. Decision Tree dapat digunakan untuk klasifikasi maupun regresi, serta memiliki kelebihan berupa struktur model yang relatif mudah dipahami dan diinterpretasikan. Oleh karena itu, metode ini dapat digunakan untuk mempelajari hubungan antara variabel prediktor dan variabel respons dalam suatu data (Fransiska, 2026).
Ensemble learning adalah teknik yang menggabungkan beberapa model dasar (base learners) untuk menghasilkan prediksi akhir. Gagasan utama metode ini adalah bahwa kombinasi beberapa model dapat menghasilkan prediksi yang lebih stabil atau lebih akurat dibandingkan satu model saja. Perbaikan tersebut dapat diperoleh melalui pengurangan varians, pengurangan bias, atau pemanfaatan keragaman kesalahan antar-base learners (Mienye & Sun, 2022; Zhang et al., 2022).
Kinerja ensemble dipengaruhi oleh dua unsur penting, yaitu akurasi setiap model dasar dan keragaman antar-model. Model-model yang memiliki akurasi tinggi tetapi menghasilkan prediksi yang hampir sama tidak selalu memberikan peningkatan yang berarti ketika digabungkan. Sebaliknya, model yang memiliki keragaman prediksi dapat saling melengkapi, selama tingkat kesalahan masing-masing model tidak terlalu besar. Dengan demikian, pembentukan ensemble perlu memperhatikan algoritma dasar, mekanisme pembentukan sampel, pemilihan fitur, serta metode penggabungan prediksi.
Tiga pendekatan ensemble yang banyak dibahas adalah bagging, boosting, dan stacking. Bagging membangun model secara paralel pada beberapa sampel hasil bootstrap dan menggabungkan prediksinya. Boosting membangun model secara bertahap dengan memberikan perhatian lebih besar pada observasi yang sebelumnya diprediksi dengan salah. Stacking menggabungkan beberapa model heterogen melalui model tingkat kedua atau meta-learner. Ketiga pendekatan tersebut memiliki mekanisme, kebutuhan komputasi, dan karakteristik performa yang berbeda (Qiu et al., 2025; Zhang et al., 2022).
Boosting merupakan metode ensemble yang membentuk model kuat dari serangkaian weak learner. Pada setiap tahap, algoritma memberikan perhatian lebih besar pada observasi yang sulit diprediksi atau pada residual dari model sebelumnya. Model-model tersebut kemudian digabungkan menjadi fungsi prediksi akhir. Dengan cara ini, Boosting dapat menangkap hubungan nonlinier dan interaksi antarvariabel yang sulit direpresentasikan oleh satu pohon keputusan sederhana (Ahn et al., 2023; Zhang et al., 2022).
Secara umum, model Boosting dapat dituliskan sebagai penjumlahan bertahap:
\[F_m(x)=F_{m-1}(x)+\eta h_m(x),\]
dengan (\(F_m(x)\)) adalah model pada iterasi ke-m, (\(h_m(x)\)) adalah weak learner baru, dan η adalah learning rate. Nilai learning rate mengendalikan kontribusi setiap model baru. Nilai yang kecil biasanya membutuhkan jumlah pohon yang lebih banyak, sedangkan nilai yang besar dapat mempercepat pembelajaran tetapi meningkatkan risiko overfitting. Dalam implementasi modern, performa Boosting juga dipengaruhi oleh kedalaman pohon, jumlah estimator, subsampling, regularisasi, serta karakteristik data.
Kelebihan utama Boosting adalah kemampuannya menghasilkan kinerja prediksi tinggi pada data tabular. Namun, peningkatan kinerja tidak bersifat universal. Ahn et al. (2023) menunjukkan bahwa XGBoost, LightGBM, dan CatBoost menghasilkan performa berbeda pada tugas peramalan yang sama. Perbedaan tersebut menunjukkan bahwa algoritma Boosting perlu dievaluasi berdasarkan karakteristik data dan tujuan penelitian, bukan hanya berdasarkan reputasi atau hasil pada dataset lain.
Adaptive Boosting atau AdaBoost membangun serangkaian weak learner secara berurutan. Pada tahap awal, observasi diberi bobot yang relatif sama. Setelah model pertama menghasilkan prediksi, bobot observasi yang salah diklasifikasikan dinaikkan sehingga model berikutnya lebih memperhatikan observasi tersebut. Prediksi akhir diperoleh dari kombinasi berbobot seluruh weak learner.
Kelebihan AdaBoost terletak pada struktur algoritmanya yang relatif sederhana dan kemampuannya mengubah beberapa pembelajar lemah menjadi model yang lebih kuat. Namun, peningkatan bobot pada observasi yang salah juga dapat membuat model sensitif terhadap pencilan dan noise. Oleh karena itu, jumlah estimator, tipe weak learner, serta learning rate perlu ditentukan melalui validasi. Pada data kecil dan seimbang, AdaBoost dapat menjadi alternatif yang efisien, tetapi kinerjanya tetap perlu dibandingkan dengan algoritma Boosting berbasis pohon lainnya (Nguyen & Ngo, 2025).
Gradient Boosting membangun model secara bertahap dengan meminimalkan fungsi kerugian. Pada setiap iterasi, algoritma membentuk weak learner baru untuk mendekati arah penurunan fungsi kerugian atau residual model sebelumnya. Pendekatan ini dapat digunakan untuk klasifikasi dan regresi dengan fungsi kerugian yang disesuaikan dengan tujuan analisis.
Keberhasilan Gradient Boosting sangat dipengaruhi oleh kombinasi jumlah pohon, kedalaman pohon, learning rate, dan subsampling. Jumlah pohon yang terlalu sedikit dapat menyebabkan underfitting, sedangkan jumlah pohon yang terlalu besar dapat meningkatkan waktu komputasi dan risiko overfitting. Karena itu, penelitian yang menggunakan Gradient Boosting perlu mencantumkan prosedur penyetelan hiperparameter dan skema validasi yang digunakan.
Studi Ptr et al. (2024) menunjukkan bahwa Gradient Boosting, XGBoost, dan CatBoost dapat menghasilkan kinerja berbeda setelah data mengalami prapemrosesan dan normalisasi. Temuan tersebut memperlihatkan bahwa performa algoritma tidak terlepas dari tahap pengolahan data sebelum pemodelan.
Extreme Gradient Boosting atau XGBoost merupakan pengembangan Gradient Boosting berbasis pohon yang dirancang untuk meningkatkan efisiensi, skalabilitas, dan pengendalian kompleksitas model. XGBoost menggunakan regularisasi dan menyediakan berbagai pengaturan untuk mengendalikan pertumbuhan pohon. Algoritma ini banyak digunakan pada data tabular karena dapat menangani hubungan nonlinier dan interaksi antarprediktor.
Dalam praktiknya, hiperparameter penting pada XGBoost meliputi n_estimators, learning rate, max depth, subsample, colsample bytree, serta parameter regularisasi seperti reg alpha dan reg lambda. Max depth mengendalikan kompleksitas setiap pohon, sedangkan subsample dan colsample bytree mengatur proporsi observasi atau fitur yang digunakan pada proses pembentukan pohon. Pengaturan yang tidak tepat dapat menghasilkan model terlalu kompleks, penggunaan memori tinggi, atau performa yang kurang baik pada data tidak seimbang (Ahn et al., 2023).
Light Gradient Boosting Machine atau LightGBM merupakan implementasi Gradient Boosting yang menekankan efisiensi waktu dan penggunaan memori. Dalam ringkasan Ahn et al. (2023), LightGBM dijelaskan memiliki keunggulan pada kecepatan dan efisiensi memori ketika menangani data berukuran besar. Algoritma ini menggunakan strategi pertumbuhan pohon leaf-wise, sehingga dapat meningkatkan pengurangan fungsi kerugian pada setiap tahap.
Strategi leaf-wise dapat menghasilkan pohon yang lebih kompleks dibandingkan pertumbuhan level-wise apabila tidak dikendalikan. Nguyen & Ngo (2025) menyatakan bahwa LightGBM dapat mengalami overfitting, khususnya pada dataset kecil, dan kinerja algoritma dapat berubah sesuai konteks data. Oleh karena itu, parameter seperti num leaves, max depth, min data in leaf, feature fraction, bagging fraction, dan learning rate perlu disetel secara hati-hati.
Categorical Boosting atau CatBoost merupakan algoritma boosting yang dirancang untuk menangani variabel kategorik secara lebih langsung. Keunggulan tersebut dapat mengurangi kebutuhan terhadap pengkodean kategorik yang kompleks pada tahap awal. Ahn et al. (2023) menjelaskan bahwa CatBoost memiliki kemampuan baik dalam menangani variabel kategorik dan menyediakan mekanisme yang mendukung pengendalian overfitting.
CatBoost tetap memiliki keterbatasan. Waktu pelatihan dan kinerja model dapat berubah sesuai dimensi data, jumlah kategori, jumlah estimator, serta konfigurasi parameter. Dalam studi Ptr et al. (2024), CatBoost memberikan hasil terbaik pada klasifikasi spesifikasi telepon seluler setelah prapemrosesan dan cross-validation. Sebaliknya, Ahn et al. (2023) menemukan bahwa CatBoost menghasilkan kinerja yang lebih rendah daripada XGBoost dan LightGBM pada tugas peramalan harmful algal blooms. Perbedaan temuan tersebut memperkuat alasan untuk melakukan evaluasi empiris pada dataset penelitian sendiri.
Kinerja Boosting Classification dievaluasi dengan membandingkan kelas aktual dan kelas hasil prediksi pada data testing. Hasil perbandingan tersebut disajikan dalam confusion matrix (Fransiska, 2026), yaitu tabel yang memuat jumlah prediksi benar dan salah untuk setiap kelas.
| Prediksi Positif | Prediksi Negatif | |
|---|---|---|
| Aktual Positif | True Positive (TP) | False Negative (FN) |
| Aktual Negatif | False Positive (FP) | True Negative (TN) |
Keterangan: TP adalah pengamatan positif yang diprediksi positif, TN adalah pengamatan negatif yang diprediksi negatif, FP adalah pengamatan negatif yang salah diprediksi positif, dan FN adalah pengamatan positif yang salah diprediksi negatif. Berdasarkan confusion matrix, beberapa ukuran evaluasi yang digunakan adalah sebagai berikut.
\[ Accuracy=\frac{TP+TN}{TP+TN+FP+FN} \]
\[ Precision=\frac{TP}{TP+FP} \]
\[ Recall=\frac{TP}{TP+FN} \]
\[ Specificity=\frac{TN}{TN+FP} \]
\[ F1\text{-}Score=2\times\frac{Precision\times Recall}{Precision+Recall} \]
Accuracy mudah diinterpretasikan, tetapi dapat menyesatkan apabila proporsi kelas tidak seimbang, sehingga perlu dilengkapi dengan sensitivity, specificity, precision, dan F1-Score. Pada kasus medis seperti diagnosis kanker, nilai sensitivity menjadi perhatian utama karena kesalahan false negative (kasus positif yang terlewat) umumnya memiliki konsekuensi yang lebih serius daripada false positive.
Selain itu, kemampuan model membedakan kedua kelas pada berbagai ambang klasifikasi dapat dinilai menggunakan kurva Receiver Operating Characteristic (ROC). Kurva ini menggambarkan hubungan antara true positive rate (sensitivity) pada sumbu vertikal dan false positive rate (\(1-Specificity\)) pada sumbu horizontal (Fawcett, 2006). Ringkasan numeriknya adalah Area Under the Curve (AUC), yaitu luas di bawah kurva ROC. Nilai AUC berkisar antara 0 hingga 1; semakin mendekati 1, semakin baik kemampuan model membedakan kelas, sedangkan nilai 0,5 setara dengan tebakan acak (Fawcett, 2006).
Kinerja model regresi dapat dievaluasi menggunakan Mean Squared Error (MSE), yaitu rata-rata kuadrat selisih antara nilai aktual dan nilai prediksi. MSE dirumuskan sebagai berikut.
\[ MSE=\frac{1}{n}\sum_{i=1}^{n}(y_i-\hat{y}_i)^2 \] dengan \(n\) merupakan jumlah pengamatan, \(y_i\) merupakan nilai aktual, dan \(\hat{y}_i\) merupakan nilai prediksi. Nilai MSE yang lebih kecil menunjukkan tingkat kesalahan prediksi yang lebih rendah pada data evaluasi.
Jenis data yang digunakan dalam praktikum ini adalah data kuantitatif
dan data kategorik. Data kuantitatif berupa karakteristik sel yang
digunakan sebagai variabel prediktor, sedangkan data kategorik berupa
kondisi kanker payudara yang terdiri atas dua kelas, yaitu jinak
(benign) dan ganas (malignant). Sumber data
yang digunakan merupakan data sekunder dari dataset
BreastCancer dalam package mlbench
pada perangkat lunak R. Dataset ini memuat informasi karakteristik sel
untuk mengklasifikasikan kondisi kanker payudara. Data tersebut
digunakan dalam pemodelan Boosting Classification dengan
pendekatan AdaBoost.
Variabel penelitian terdiri atas variabel respons dan variabel
prediktor. Variabel respons yang digunakan adalah Class, yang
menunjukkan kondisi kanker payudara dalam kategori jinak
(benign) dan ganas (malignant). Sementara itu,
variabel prediktor meliputi Cl.thickness,
Cell.size, Cell.shape,
Marg.adhesion, Epith.c.size,
Bare.nuclei, Bl.cromatin,
Normal.nucleoli, dan Mitoses, yang
menggambarkan karakteristik sel untuk mengklasifikasikan kondisi kanker
payudara menggunakan metode Boosting Classification.
Langkah-langkah analisis yang dilakukan dalam praktikum Boosting Classification menggunakan AdaBoost adalah sebagai berikut.
Langkah-langkah analisis yang dilakukan dalam praktikum Boosting untuk klasifikasi menggunakan AdaBoost adalah sebagai berikut.
adabag,
mlbench, caret, rpart, dan
tidyverse, kemudian memuat dataset
BreastCancer ke dalam R.Id karena hanya berfungsi sebagai
pengenal, menghapus observasi yang mengandung missing value
menggunakan fungsi na.omit(), dan memastikan variabel
Class bertipe factor.Class sebagai variabel respons dan sembilan
karakteristik sel sebagai variabel prediktor, serta memeriksa distribusi
kelas pada variabel respons.createDataPartition() dengan
set.seed(234).boosting() pada package adabag dengan
decision stump sebagai weak learner
(maxdepth = 1, minsplit = 10,
cp = 0), boos = FALSE, dan
coeflearn = "Freund".mfinal),
yaitu 50, 100, dan 200.malignant sebagai kelas positif.errorevol().Pada batasan masalah diperintahkan untuk melakukan boosting
classification pada data BreastCancer Tahap pertama
adalah memanggil seluruh library yang dibutuhkan dan memuat
dataset BreastCancer dari package
mlbench. Package adabag menyediakan
fungsi boosting() yang digunakan untuk membangun model
AdaBoost, package rpart menyediakan pohon
klasifikasi yang menjadi weak learner, sedangkan
package caret digunakan untuk membagi data dan
menghitung confusion matrix.
library(adabag)
library(mlbench)
library(caret)
library(rpart)
library(tidyverse)
# fungsi bantu: format angka dengan koma desimal
koma <- function(x, d = 4) format(round(x, d), decimal.mark = ",", nsmall = 0)
# A1. Memuat data
data(BreastCancer, package = "mlbench")
bc_raw <- BreastCancer
dim(bc_raw)## [1] 699 11
## 'data.frame': 699 obs. of 11 variables:
## $ Id : chr "1000025" "1002945" "1015425" "1016277" ...
## $ Cl.thickness : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 5 5 3 6 4 8 1 2 2 4 ...
## $ Cell.size : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 1 4 1 8 1 10 1 1 1 2 ...
## $ Cell.shape : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 1 4 1 8 1 10 1 2 1 1 ...
## $ Marg.adhesion : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 1 5 1 1 3 8 1 1 1 1 ...
## $ Epith.c.size : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 2 7 2 3 2 7 2 2 2 2 ...
## $ Bare.nuclei : Factor w/ 10 levels "1","2","3","4",..: 1 10 2 4 1 10 10 1 1 1 ...
## $ Bl.cromatin : Factor w/ 10 levels "1","2","3","4",..: 3 3 3 3 3 9 3 3 1 2 ...
## $ Normal.nucleoli: Factor w/ 10 levels "1","2","3","4",..: 1 2 1 7 1 7 1 1 1 1 ...
## $ Mitoses : Factor w/ 9 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 5 1 ...
## $ Class : Factor w/ 2 levels "benign","malignant": 1 1 1 1 1 2 1 1 1 1 ...
## Id Cl.thickness Cell.size Cell.shape Marg.adhesion
## Length :699 1 :145 1 :384 1 :353 1 :407
## N.unique :645 5 :130 10 : 67 2 : 59 2 : 58
## N.blank : 0 3 :108 3 : 52 10 : 58 3 : 58
## Min.nchar: 5 4 : 80 2 : 45 3 : 56 10 : 55
## Max.nchar: 8 10 : 69 4 : 40 4 : 44 4 : 33
## 2 : 50 5 : 30 5 : 34 8 : 25
## (Other):117 (Other): 81 (Other): 95 (Other): 63
## Epith.c.size Bare.nuclei Bl.cromatin Normal.nucleoli Mitoses
## 2 :386 1 :402 2 :166 1 :443 1 :579
## 3 : 72 10 :132 3 :165 10 : 61 2 : 35
## 4 : 48 2 : 30 1 :152 3 : 44 3 : 33
## 1 : 47 5 : 30 7 : 73 2 : 36 10 : 14
## 6 : 41 3 : 28 4 : 40 8 : 24 4 : 12
## 5 : 39 (Other): 61 5 : 34 6 : 22 7 : 9
## (Other): 66 NAs : 16 (Other): 69 (Other): 69 (Other): 17
## Class
## benign :458
## malignant:241
##
##
##
##
##
| Id | Cl.thickness | Cell.size | Cell.shape | Marg.adhesion | Epith.c.size | Bare.nuclei | Bl.cromatin | Normal.nucleoli | Mitoses | Class |
|---|---|---|---|---|---|---|---|---|---|---|
| 1000025 | 5 | 1 | 1 | 1 | 2 | 1 | 3 | 1 | 1 | benign |
| 1002945 | 5 | 4 | 4 | 5 | 7 | 10 | 3 | 2 | 1 | benign |
| 1015425 | 3 | 1 | 1 | 1 | 2 | 2 | 3 | 1 | 1 | benign |
| 1016277 | 6 | 8 | 8 | 1 | 3 | 4 | 3 | 7 | 1 | benign |
| 1017023 | 4 | 1 | 1 | 3 | 2 | 1 | 3 | 1 | 1 | benign |
| 1017122 | 8 | 10 | 10 | 8 | 7 | 10 | 9 | 7 | 1 | malignant |
Dataset memiliki 699 observasi dan 11 variabel. Variabel
Id hanyalah nomor identitas pasien sehingga tidak dipakai
sebagai prediktor. Variabel Class adalah variabel respons
dengan dua kategori (benign dan malignant),
sedangkan sembilan variabel lainnya (Cl.thickness sampai
Mitoses) adalah karakteristik sel yang menjadi prediktor.
Pada keluaran str(), prediktor tersimpan bertipe
factor dengan skor 1 sampai 10, dan tipe ini dipertahankan
pada pemodelan karena pohon klasifikasi dapat memproses variabel
berskala bertingkat secara langsung. Ringkasan data juga memperlihatkan
adanya NA pada variabel Bare.nuclei.
Persiapan data mengikuti tiga langkah, yaitu menghapus
Id karena hanya berfungsi sebagai pengenal, menghapus
observasi yang mengandung missing value, dan memastikan
variabel respons bertipe factor.
tabel_missing <- data.frame(
Variabel = names(bc_raw)[-1],
Jumlah_NA = as.vector(colSums(is.na(bc_raw[, -1]))),
Persen_NA = round(as.vector(colMeans(is.na(bc_raw[, -1]))) * 100, 2)
)
knitr::kable(tabel_missing, align = "c",
caption = "Jumlah dan persentase missing value per variabel")| Variabel | Jumlah_NA | Persen_NA |
|---|---|---|
| Cl.thickness | 0 | 0.00 |
| Cell.size | 0 | 0.00 |
| Cell.shape | 0 | 0.00 |
| Marg.adhesion | 0 | 0.00 |
| Epith.c.size | 0 | 0.00 |
| Bare.nuclei | 16 | 2.29 |
| Bl.cromatin | 0 | 0.00 |
| Normal.nucleoli | 0 | 0.00 |
| Mitoses | 0 | 0.00 |
| Class | 0 | 0.00 |
# A2. Persiapan data
bc <- bc_raw
# Menghapus Id karena hanya merupakan identifier
bc$Id <- NULL
# Menghapus observasi yang mengandung missing value
bc <- na.omit(bc)
# Memastikan respons berupa factor
bc$Class <- droplevels(as.factor(bc$Class))
# Melihat kategori respons
levels(bc$Class)## [1] "benign" "malignant"
## [1] 683 10
Missing value hanya ditemukan pada Bare.nuclei,
sebanyak 16 observasi (2,29%), sedangkan variabel lainnya lengkap.
Karena proporsinya kecil, observasi tersebut dihapus dengan
na.omit() sehingga data yang dianalisis berjumlah 683
observasi dengan 10 variabel (sembilan prediktor dan satu respons).
Variabel Class memiliki dua kategori, yaitu benign dan
malignant, dengan kelas malignant ditetapkan sebagai kelas
positif.
tabel_class <- data.frame(
Kelas = names(table(bc$Class)),
Jumlah = as.vector(table(bc$Class)),
Persen = round(as.vector(prop.table(table(bc$Class))) * 100, 2)
)
knitr::kable(tabel_class, align = "c", caption = "Distribusi kelas variabel Class")| Kelas | Jumlah | Persen |
|---|---|---|
| benign | 444 | 65.01 |
| malignant | 239 | 34.99 |
ggplot(tabel_class, aes(x = Kelas, y = Jumlah, fill = Kelas)) +
geom_col(color = "black", width = 0.6) +
geom_text(aes(label = Jumlah), vjust = -0.4) +
scale_fill_manual(values = c("#008080", "#E69F00")) +
labs(title = "Distribusi Kondisi Kanker Payudara", x = "Class", y = "Jumlah") +
theme_minimal() +
theme(legend.position = "none")Dari 683 observasi, sebanyak 444 observasi (65,01%) termasuk kelas
jinak (benign) dan 239 observasi (34,99%) termasuk kelas
ganas (malignant). Kelas jinak lebih banyak, tetapi
perbedaannya tidak terlalu ekstrem sehingga data masih tergolong cukup
seimbang untuk dimodelkan tanpa teknik penyeimbangan kelas.
Data dibagi menjadi data training (70%) dan data
testing (30%) menggunakan createDataPartition()
dengan set.seed(234). Fungsi ini melakukan pengambilan
sampel acak yang terstratifikasi berdasarkan Class,
sehingga proporsi kelas pada kedua himpunan data tetap terjaga.
# A3. Membagi data training dan testing (70% training dan 30% testing)
set.seed(234)
idx.cls <- createDataPartition(bc$Class, p = 0.70, list = FALSE)
bc.train <- bc[idx.cls, ]
bc.test <- bc[-idx.cls, ]
# Memeriksa ukuran data
cat("Dimensi data training :", dim(bc.train), "\n")## Dimensi data training : 479 10
## Dimensi data testing : 204 10
perbandingan <- rbind(
Data_Asli = round(prop.table(table(bc$Class)) * 100, 2),
Data_Training = round(prop.table(table(bc.train$Class)) * 100, 2),
Data_Testing = round(prop.table(table(bc.test$Class)) * 100, 2)
)
knitr::kable(perbandingan, align = "c",
caption = "Persentase kelas Class (%) pada tiap himpunan data")| benign | malignant | |
|---|---|---|
| Data_Asli | 65.01 | 34.99 |
| Data_Training | 64.93 | 35.07 |
| Data_Testing | 65.20 | 34.80 |
##
## benign malignant
## 311 168
##
## benign malignant
## 133 71
Data terbagi menjadi 479 observasi training dan 204 observasi testing (sekitar 70:30). Proporsi kelas jinak dan ganas pada kedua himpunan data hampir sama dengan data asli, sehingga keduanya mewakili kondisi data sebenarnya. Data training digunakan untuk membangun model, sedangkan data testing hanya digunakan untuk menguji kemampuan prediksi pada pengamatan baru.
Model AdaBoost dibangun dengan fungsi
boosting() dari paket adabag. Variabel respons
adalah Class dan prediktornya adalah sembilan karakteristik
sel. Dimana Pengaturan yang digunakan adalah sebagai berikut.
mfinal adalah jumlah iterasi atau jumlah weak
learner yang dibentuk, dan pada praktikum ini dibandingkan tiga
nilai, yaitu 50, 100, dan 200.control = rpart.control(maxdepth = 1, minsplit = 10, cp = 0)
membatasi kedalaman pohon sebesar 1 sehingga setiap pohon hanya memiliki
satu pemisahan (decision stump) yang berperan sebagai weak
learner.coeflearn = "Freund" menetapkan bobot learner
\(\alpha_m =
\log\left(\frac{1-err_m}{err_m}\right)\) sesuai algoritma
AdaBoost asli.boos = FALSE berarti bobot observasi digunakan langsung
untuk membentuk setiap pohon tanpa pengambilan ulang sampel
(resampling) berdasarkan bobot.Karena itu, setiap model dibangun dengan set.seed(234)
agar hasilnya dapat direproduksi.
# A4. Membentuk model AdaBoost untuk mfinal = 50, 100, dan 200
mfinal_set <- c(50, 100, 200)
model_ada <- list()
for (m in mfinal_set) {
set.seed(234)
model_ada[[as.character(m)]] <- boosting(
Class ~ ., data = bc.train,
boos = FALSE, mfinal = m, coeflearn = "Freund",
control = rpart.control(maxdepth = 1, minsplit = 10, cp = 0)
)
}
# Ringkasan model (objek lengkap tidak dicetak karena memuat seluruh pohon)
ringkas_model <- do.call(rbind, lapply(names(model_ada), function(m) {
md <- model_ada[[m]]
data.frame(mfinal = as.numeric(m),
Jumlah_Pohon = length(md$trees),
Alpha_Min = min(md$weights),
Alpha_Rata2 = mean(md$weights),
Alpha_Maks = max(md$weights),
Prediktor_Dipakai = sum(md$importance > 0))
}))
knitr::kable(ringkas_model, digits = 4, align = "c",
caption = "Ringkasan model AdaBoost untuk setiap nilai mfinal")| mfinal | Jumlah_Pohon | Alpha_Min | Alpha_Rata2 | Alpha_Maks | Prediktor_Dipakai |
|---|---|---|---|---|---|
| 50 | 50 | 0.1664 | 0.4859 | 2.5717 | 9 |
| 100 | 100 | 0.1093 | 0.3326 | 2.5717 | 9 |
| 200 | 200 | 0.0730 | 0.2336 | 2.5717 | 9 |
# Variabel pemisah pada stump pertama
stump_pertama <- as.character(model_ada[["100"]]$trees[[1]]$frame$var[1])
stump_pertama## [1] "Cell.size"
Hasil output di atas menunjukkan bahwa setiap model terdiri
dari pohon sebanyak nilai mfinal yang ditetapkan,
masing-masing berupa decision stump. Nilai \(\alpha_m\) (bobot kontribusi
learner) berkisar antara 0,073 dan 2,572; semakin besar \(\alpha_m\), semakin besar pengaruh
learner tersebut pada suara akhir karena kesalahan terbobotnya
semakin kecil. Stump pertama memisahkan data berdasarkan
variabel Cell.size, yaitu variabel yang paling mampu membedakan kedua
kelas pada tahap awal ketika seluruh observasi masih berbobot sama.
Jumlah prediktor yang benar-benar dipakai oleh seluruh stump
adalah 9 sampai 9 dari sembilan prediktor.
Setiap model digunakan untuk memprediksi kelas pada data
testing. Hasilnya dibandingkan dengan kelas aktual dalam bentuk
confusion matrix (baris = aktual, kolom = prediksi). Kelas
malignant ditetapkan sebagai kelas positif karena kesalahan
yang paling berbahaya secara klinis adalah gagal mendeteksi sel ganas.
Dengan demikian, TN adalah sel jinak yang diprediksi jinak, FP adalah
sel jinak yang diprediksi ganas, FN adalah sel ganas yang diprediksi
jinak, dan TP adalah sel ganas yang diprediksi ganas.
# A5. Prediksi data testing untuk setiap model
pred_ada <- lapply(model_ada, function(md) {
p <- predict(md, newdata = bc.test)$class
factor(p, levels = levels(bc.test$Class))
})
# Membandingkan aktual dan prediksi (10 observasi pertama)
hasil_ada <- data.frame(
Aktual = bc.test$Class,
Prediksi_50 = pred_ada[["50"]],
Prediksi_100 = pred_ada[["100"]],
Prediksi_200 = pred_ada[["200"]]
)
knitr::kable(head(hasil_ada, 10), align = "c",
caption = "Perbandingan kelas aktual dan prediksi (10 observasi pertama data testing)")| Aktual | Prediksi_50 | Prediksi_100 | Prediksi_200 |
|---|---|---|---|
| benign | malignant | malignant | malignant |
| benign | benign | benign | benign |
| benign | benign | benign | benign |
| benign | benign | benign | benign |
| benign | benign | benign | benign |
| malignant | malignant | malignant | malignant |
| benign | benign | benign | benign |
| benign | benign | benign | benign |
| benign | benign | benign | benign |
| malignant | malignant | malignant | malignant |
# A6. Confusion matrix (caret) untuk setiap model
cm_ada <- lapply(pred_ada, function(p) {
confusionMatrix(data = p, reference = bc.test$Class, positive = "malignant")
})
for (m in names(cm_ada)) {
cat("=============== Confusion Matrix (data testing), mfinal =", m, "===============\n")
print(cm_ada[[m]])
cat("\n")
}## =============== Confusion Matrix (data testing), mfinal = 50 ===============
## Confusion Matrix and Statistics
##
## Reference
## Prediction benign malignant
## benign 130 4
## malignant 3 67
##
## Accuracy : 0.9657
## 95% CI : (0.9306, 0.9861)
## No Information Rate : 0.652
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.9241
##
## Mcnemar's Test P-Value : 1
##
## Sensitivity : 0.9437
## Specificity : 0.9774
## Pos Pred Value : 0.9571
## Neg Pred Value : 0.9701
## Prevalence : 0.3480
## Detection Rate : 0.3284
## Detection Prevalence : 0.3431
## Balanced Accuracy : 0.9606
##
## 'Positive' Class : malignant
##
##
## =============== Confusion Matrix (data testing), mfinal = 100 ===============
## Confusion Matrix and Statistics
##
## Reference
## Prediction benign malignant
## benign 130 4
## malignant 3 67
##
## Accuracy : 0.9657
## 95% CI : (0.9306, 0.9861)
## No Information Rate : 0.652
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.9241
##
## Mcnemar's Test P-Value : 1
##
## Sensitivity : 0.9437
## Specificity : 0.9774
## Pos Pred Value : 0.9571
## Neg Pred Value : 0.9701
## Prevalence : 0.3480
## Detection Rate : 0.3284
## Detection Prevalence : 0.3431
## Balanced Accuracy : 0.9606
##
## 'Positive' Class : malignant
##
##
## =============== Confusion Matrix (data testing), mfinal = 200 ===============
## Confusion Matrix and Statistics
##
## Reference
## Prediction benign malignant
## benign 130 5
## malignant 3 66
##
## Accuracy : 0.9608
## 95% CI : (0.9242, 0.9829)
## No Information Rate : 0.652
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.913
##
## Mcnemar's Test P-Value : 0.7237
##
## Sensitivity : 0.9296
## Specificity : 0.9774
## Pos Pred Value : 0.9565
## Neg Pred Value : 0.9630
## Prevalence : 0.3480
## Detection Rate : 0.3235
## Detection Prevalence : 0.3382
## Balanced Accuracy : 0.9535
##
## 'Positive' Class : malignant
##
# A7. Fungsi evaluasi: confusion matrix dan lima ukuran evaluasi
# Kelas positif = malignant
hitung_evaluasi <- function(model, data) {
pred <- factor(predict(model, newdata = data)$class, levels = levels(data$Class))
tab <- table(Aktual = data$Class, Prediksi = pred)
TN <- tab["benign", "benign"]
FP <- tab["benign", "malignant"]
FN <- tab["malignant", "benign"]
TP <- tab["malignant", "malignant"]
Accuracy <- (TP + TN) / (TP + TN + FP + FN)
Precision <- TP / (TP + FP)
Recall <- TP / (TP + FN)
Specificity <- TN / (TN + FP)
F1 <- 2 * (Precision * Recall) / (Precision + Recall)
list(
cm = tab,
metrik = data.frame(TN = as.numeric(TN), FP = as.numeric(FP),
FN = as.numeric(FN), TP = as.numeric(TP),
Accuracy = Accuracy, Precision = Precision,
Recall = Recall, Specificity = Specificity, F1 = F1)
)
}
hasil_test <- lapply(model_ada, hitung_evaluasi, data = bc.test)
for (m in names(hasil_test)) {
cat("=============== Tabel Aktual vs Prediksi (data testing), mfinal =", m, "===============\n")
print(hasil_test[[m]]$cm)
cat("\n")
}## =============== Tabel Aktual vs Prediksi (data testing), mfinal = 50 ===============
## Prediksi
## Aktual benign malignant
## benign 130 3
## malignant 4 67
##
## =============== Tabel Aktual vs Prediksi (data testing), mfinal = 100 ===============
## Prediksi
## Aktual benign malignant
## benign 130 3
## malignant 4 67
##
## =============== Tabel Aktual vs Prediksi (data testing), mfinal = 200 ===============
## Prediksi
## Aktual benign malignant
## benign 130 3
## malignant 5 66
Dari 204 data testing, hasil prediksi masing-masing model adalah sebagai berikut. Pada mfinal = 50, model memprediksi benar 67 observasi ganas dan 130 observasi jinak, dengan 3 false positive dan 4 false negative (total kesalahan 7). Pada mfinal = 100, model memprediksi benar 67 observasi ganas dan 130 observasi jinak, dengan 3 false positive dan 4 false negative (total kesalahan 7). Pada mfinal = 200, model memprediksi benar 66 observasi ganas dan 130 observasi jinak, dengan 3 false positive dan 5 false negative (total kesalahan 8). False negative (sel ganas yang diprediksi jinak) menjadi kesalahan yang paling perlu diperhatikan karena berarti kasus ganas terlewat, sedangkan false positive berarti sel jinak diprediksi ganas.
Dari confusion matrix, dihitung lima metrik evaluasi, yaitu
accuracy, precision, recall,
specificity, dan F1-Score (perhitungannya terdapat
pada fungsi hitung_evaluasi di atas). Hasil pada data
testing disajikan berikut.
tabel_test <- do.call(rbind, lapply(names(hasil_test), function(m) {
cbind(mfinal = as.numeric(m), hasil_test[[m]]$metrik)
}))
rownames(tabel_test) <- NULL
knitr::kable(tabel_test, digits = 4, align = "c",
caption = "Metrik evaluasi model AdaBoost pada data testing")| mfinal | TN | FP | FN | TP | Accuracy | Precision | Recall | Specificity | F1 |
|---|---|---|---|---|---|---|---|---|---|
| 50 | 130 | 3 | 4 | 67 | 0.9657 | 0.9571 | 0.9437 | 0.9774 | 0.9504 |
| 100 | 130 | 3 | 4 | 67 | 0.9657 | 0.9571 | 0.9437 | 0.9774 | 0.9504 |
| 200 | 130 | 3 | 5 | 66 | 0.9608 | 0.9565 | 0.9296 | 0.9774 | 0.9429 |
metrik_long <- tabel_test %>%
dplyr::select(mfinal, Accuracy, Precision, Recall, Specificity, F1) %>%
pivot_longer(-mfinal, names_to = "Metrik", values_to = "Nilai")
ymin <- max(0, floor(min(metrik_long$Nilai) * 20) / 20)
ggplot(metrik_long, aes(x = factor(mfinal), y = Nilai, color = Metrik, group = Metrik)) +
geom_line(linewidth = 1) +
geom_point(size = 2.5) +
coord_cartesian(ylim = c(ymin, 1)) +
labs(title = "Metrik Evaluasi AdaBoost pada Data Testing",
x = "Jumlah learner (mfinal)", y = "Nilai metrik") +
theme_minimal()Pada data testing, ketiga model menghasilkan akurasi 96,57%
(mfinal = 50), 96,57% (mfinal = 100), dan
96,08% (mfinal = 200). Recall (sensitivitas
terhadap kelas ganas) berturut-turut sebesar 94,37%, 94,37%, dan 92,96%,
artinya sebesar itulah proporsi sel ganas yang berhasil terdeteksi.
Specificity sebesar 97,74%, 97,74%, dan 97,74% menunjukkan
proporsi sel jinak yang dikenali dengan benar, sedangkan
precision sebesar 95,71%, 95,71%, dan 95,65% menunjukkan
ketepatan prediksi ganas. F1-Score, sebagai rata-rata harmonik
precision dan recall, berada pada 0,9504, 0,9504, dan
0,9429. Seluruh metrik berada pada tingkat yang tinggi (di atas 90%),
yang menunjukkan bahwa karakteristik sel dapat digunakan untuk
membedakan kondisi jinak dan ganas dengan sangat baik oleh model
AdaBoost.
Fungsi errorevol() menghitung kesalahan klasifikasi
ensemble pada setiap penambahan learner, mulai dari satu
learner hingga mfinal learner. Dengan
membandingkan error pada data training dan
testing, dapat dilihat bagaimana penambahan learner
memengaruhi kinerja model serta apakah terjadi overfitting.
# A8. Perkembangan error AdaBoost
err_train <- lapply(model_ada, function(md) errorevol(md, newdata = bc.train))
err_test <- lapply(model_ada, function(md) errorevol(md, newdata = bc.test))
# Membandingkan training dan testing error
par(mfrow = c(1, 3))
for (m in names(model_ada)) {
plot.errorevol(err_test[[m]], err_train[[m]])
title(sub = paste("mfinal =", m))
}par(mfrow = c(1, 1))
# Ringkasan nilai error
ringkas_err <- do.call(rbind, lapply(names(model_ada), function(m) {
et <- err_test[[m]]$error
etr <- err_train[[m]]$error
data.frame(mfinal = as.numeric(m),
Error_Test_Learner1 = et[1],
Error_Test_Minimum = min(et),
Learner_Error_Minimum = which.min(et),
Error_Test_Akhir = et[length(et)],
Error_Train_Akhir = etr[length(etr)])
}))
knitr::kable(ringkas_err, digits = 4, align = "c",
caption = "Ringkasan perkembangan error AdaBoost")| mfinal | Error_Test_Learner1 | Error_Test_Minimum | Learner_Error_Minimum | Error_Test_Akhir | Error_Train_Akhir |
|---|---|---|---|---|---|
| 50 | 0.0784 | 0.0343 | 25 | 0.0343 | 0.0230 |
| 100 | 0.0784 | 0.0343 | 25 | 0.0343 | 0.0146 |
| 200 | 0.0784 | 0.0343 | 25 | 0.0392 | 0.0125 |
Pada satu learner (satu stump), error data
testing sebesar 7,84%. Setelah seluruh learner
digabungkan, error data testing menjadi 3,43%
(mfinal = 50), 3,43% (mfinal = 100), dan 3,92%
(mfinal = 200), sedangkan error data
training akhir sebesar 2,3%, 1,46%, dan 1,25%. Penurunan error
ini menggambarkan prinsip Boosting, yaitu satu weak learner memiliki
kemampuan terbatas tetapi gabungan banyak learner secara bertahap
menghasilkan strong learner yang lebih baik. Error data
testing terendah pada masing-masing model adalah 3,43%, 3,43%,
dan 3,43%, yang pertama kali dicapai pada learner ke-25, ke-25,
dan ke-25. Error data testing pada akhir iterasi berada sangat
dekat dengan nilai minimumnya, sehingga penambahan learner
hingga mfinal terbesar tidak menimbulkan peningkatan error yang
berarti (tidak terlihat gejala overfitting yang jelas).
Variable importance pada AdaBoost menunjukkan seberapa besar kontribusi setiap prediktor dalam mengurangi kesalahan klasifikasi di seluruh learner. Nilai yang lebih besar menandakan prediktor tersebut lebih sering dan lebih efektif dipakai sebagai pemisah.
# A9. Variable importance
importance_ada <- lapply(model_ada, function(md) sort(md$importance, decreasing = TRUE))
tabel_imp <- data.frame(
Peringkat = 1:9,
mfinal_50 = paste0(names(importance_ada[["50"]]), " (", round(importance_ada[["50"]], 2), ")"),
mfinal_100 = paste0(names(importance_ada[["100"]]), " (", round(importance_ada[["100"]], 2), ")"),
mfinal_200 = paste0(names(importance_ada[["200"]]), " (", round(importance_ada[["200"]], 2), ")")
)
knitr::kable(tabel_imp, align = "c",
caption = "Urutan variable importance AdaBoost (nilai importance dalam kurung)")| Peringkat | mfinal_50 | mfinal_100 | mfinal_200 |
|---|---|---|---|
| 1 | Cell.size (41.86) | Cell.size (39.43) | Cell.size (37.36) |
| 2 | Bare.nuclei (30.64) | Bare.nuclei (29.38) | Bare.nuclei (28.17) |
| 3 | Cl.thickness (8.95) | Cl.thickness (9.22) | Cl.thickness (9.84) |
| 4 | Marg.adhesion (7.33) | Marg.adhesion (7.4) | Marg.adhesion (7.32) |
| 5 | Normal.nucleoli (4.74) | Normal.nucleoli (5.52) | Normal.nucleoli (5.93) |
| 6 | Mitoses (2.57) | Mitoses (2.92) | Mitoses (3.17) |
| 7 | Bl.cromatin (1.74) | Bl.cromatin (2.15) | Epith.c.size (2.97) |
| 8 | Epith.c.size (1.37) | Cell.shape (2.06) | Cell.shape (2.74) |
| 9 | Cell.shape (0.81) | Epith.c.size (1.91) | Bl.cromatin (2.51) |
# Plot variable importance
par(mfrow = c(1, 3), mar = c(8, 4, 3, 1))
for (m in names(importance_ada)) {
barplot(importance_ada[[m]], las = 2,
main = paste("Variable Importance - AdaBoost (mfinal =", m, ")"),
ylab = "Importance", col = "#008080", cex.main = 0.9)
}Pada model dengan mfinal = 100, tiga prediktor
terpenting adalah Cell.size (39,43), Bare.nuclei (29,38), dan
Cl.thickness (9,22). Ketiga prediktor ini paling berperan dalam
membedakan sel jinak dan ganas. Tiga prediktor teratas tersebut
konsisten pada ketiga nilai mfinal, sehingga kesimpulan mengenai
variabel yang paling berpengaruh tidak bergantung pada jumlah learner.
Karena setiap learner hanya berupa satu pemisahan, prediktor
dengan nilai importance kecil atau nol berarti jarang atau
tidak pernah dipilih sebagai pemisah, yaitu 9 sampai 9 dari sembilan
prediktor yang dipakai oleh model.
mfinal)Untuk melihat apakah model mengalami overfitting, metrik yang sama dihitung pada data training dan dibandingkan dengan data testing.
hasil_train <- lapply(model_ada, hitung_evaluasi, data = bc.train)
tabel_train <- do.call(rbind, lapply(names(hasil_train), function(m) {
cbind(mfinal = as.numeric(m), hasil_train[[m]]$metrik)
}))
rownames(tabel_train) <- NULL
tabel_banding <- rbind(
cbind(Data = "Training", tabel_train[, c("mfinal", "Accuracy", "Recall", "Specificity", "F1")]),
cbind(Data = "Testing", tabel_test[, c("mfinal", "Accuracy", "Recall", "Specificity", "F1")])
)
knitr::kable(tabel_banding, digits = 4, align = "c",
caption = "Perbandingan metrik pada data training dan testing")| Data | mfinal | Accuracy | Recall | Specificity | F1 |
|---|---|---|---|---|---|
| Training | 50 | 0.9770 | 0.9643 | 0.9839 | 0.9672 |
| Training | 100 | 0.9854 | 0.9821 | 0.9871 | 0.9792 |
| Training | 200 | 0.9875 | 0.9881 | 0.9871 | 0.9822 |
| Testing | 50 | 0.9657 | 0.9437 | 0.9774 | 0.9504 |
| Testing | 100 | 0.9657 | 0.9437 | 0.9774 | 0.9504 |
| Testing | 200 | 0.9608 | 0.9296 | 0.9774 | 0.9429 |
Akurasi pada data training sebesar 97,7% sampai 98,75%, sedangkan pada data testing sebesar 96,08% sampai 96,57%. Selisih akurasi training terhadap testing berkisar antara 1,13 dan 2,67 poin persentase. Selisih yang kecil ini menunjukkan model tidak mengalami overfitting yang berarti dan mampu menggeneralisasi dengan baik pada data baru. Akurasi pada data training tidak dapat dijadikan ukuran utama karena model sudah melihat data tersebut, sehingga perbandingan antarmodel difokuskan pada data testing.
mfinalknitr::kable(
tabel_test[, c("mfinal", "TN", "FP", "FN", "TP", "Accuracy", "Precision", "Recall", "Specificity", "F1")],
digits = 4, align = "c",
caption = "Ringkasan perbandingan model AdaBoost (data testing)"
)| mfinal | TN | FP | FN | TP | Accuracy | Precision | Recall | Specificity | F1 |
|---|---|---|---|---|---|---|---|---|---|
| 50 | 130 | 3 | 4 | 67 | 0.9657 | 0.9571 | 0.9437 | 0.9774 | 0.9504 |
| 100 | 130 | 3 | 4 | 67 | 0.9657 | 0.9571 | 0.9437 | 0.9774 | 0.9504 |
| 200 | 130 | 3 | 5 | 66 | 0.9608 | 0.9565 | 0.9296 | 0.9774 | 0.9429 |
Berdasarkan akurasi pada data testing (dengan recall sebagai pertimbangan berikutnya), model terbaik adalah model dengan mfinal = 50, yang menghasilkan akurasi 96,57%, recall 94,37%, specificity 97,74%, dan F1-Score 0,9504.
Selisih akurasi antara model terbaik dan terendah hanya 0,49 poin
persentase. Perbedaan yang sangat kecil ini menunjukkan bahwa menambah
jumlah learner dari 50 menjadi 100 dan 200 tidak memberikan peningkatan
kinerja yang berarti pada data ini. Hal ini dapat dipahami karena pada
Boosting setiap learner baru berfokus pada observasi
yang masih salah diklasifikasikan. Setelah sebagian besar observasi
terklasifikasi dengan benar, learner tambahan hanya memberi
perbaikan yang semakin kecil (diminishing returns), sementara
waktu komputasi terus bertambah karena proses pembentukannya bersifat
sequential dan tidak dapat diparalelkan (Fransiska, 2026).
Berbeda dengan Bagging yang terutama mengurangi
variance, Boosting memperbaiki kesalahan secara
bertahap sehingga mampu menurunkan bias dari weak learner yang
sederhana, tetapi bobot yang terus meningkat pada observasi sulit
membuat metode ini lebih sensitif terhadap pencilan dan noise.
Perlu diingat pula bahwa data pengujian relatif kecil (204 observasi),
sehingga selisih satu observasi saja sudah dapat mengubah akurasi
sekitar 0,49 poin persentase dan perbedaan antarmodel perlu ditafsirkan
dengan hati-hati. Dari sudut pandang klinis, jumlah false
negative pada model terbaik adalah 4 observasi, sehingga model
mfinal = 50 masih melewatkan sebagian kecil sel ganas pada
data testing.
Boosting merupakan metode ensemble yang membentuk
serangkaian weak learner secara berurutan, dengan setiap
learner baru berfokus memperbaiki kesalahan learner
sebelumnya. Pada AdaBoost, hal ini dilakukan dengan
meningkatkan bobot observasi yang salah diklasifikasikan, kemudian
menggabungkan seluruh learner melalui weighted voting.
Berdasarkan hasil penerapan AdaBoost pada dataset
BreastCancer, dapat disimpulkan sebagai berikut:
Class. Missing value hanya ditemukan pada
Bare.nuclei sebanyak 16 observasi dan ditangani dengan
na.omit() sehingga tersisa 683 observasi dengan 65,01%
kelas jinak dan 34,99% kelas ganas.boosting() pada paket adabag
menggunakan decision stump sebagai weak learner dan
tiga jumlah learner, yaitu mfinal = 50,
100, dan 200.mfinal = 50), 96,57% (mfinal = 100), dan
96,08% (mfinal = 200), dengan recall terhadap
kelas ganas sebesar 94,37%, 94,37%, dan 92,96%, serta
specificity sebesar 97,74%, 97,74%, dan 97,74%.
F1-Score masing-masing sebesar 0,9504, 0,9504, dan 0,9429.mfinal (misalnya 10, 25, atau 500) untuk melihat kapan
kinerja model berhenti membaik.coeflearn (“Breiman” dan “Zhu”), kedalaman pohon
(maxdepth) yang lebih besar, serta penggunaan
boos = TRUE, untuk melihat pengaruhnya terhadap kinerja
model.Ahn, J. M., Kim, J., & Kim, K. (2023). Ensemble Machine Learning of Gradient Boosting (XGBoost, LightGBM, CatBoost) and Attention-Based CNN-LSTM for Harmful Algal Blooms Forecasting. Toxins, 15(10). https://doi.org/10.3390/toxins15100608
Fransiska, H. (2026). Modul Praktikum Machine Learning. Universitas Bengkulu
Fawcett, T. (2006). An introduction to ROC analysis. Pattern Recognition Letters, 27(8), 861–874. https://doi.org/10.1016/j.patrec.2005.10.010
Mienye, I. D., & Sun, Y. (2022). A Survey of Ensemble Learning: Concepts, Algorithms, Applications, and Prospects. In IEEE Access (Vol. 10). https://doi.org/10.1109/ACCESS.2022.3207287
Nguyen, N., & Ngo, D. (2025). Comparative analysis of boosting algorithms for predicting personal default. Cogent Economics and Finance, 13(1). https://doi.org/10.1080/23322039.2025.2465971
Ptr, A. F. L., Siregar, M. M., & Daniel, I. (2024). Analysis of Gradient Boosting, XGBoost, and CatBoost on Mobile Phone Classification. Journal of Computer Networks, Architecture and High Performance Computing, 6(2). https://doi.org/10.47709/cnahpc.v6i2.3790
Qiu, R., Yin, Y., Su, Q., & Guan, T. (2025). Func-Bagging: An Ensemble Learning Strategy for Improving the Performance of Heterogeneous Anomaly Detection Models. Applied Sciences (Switzerland), 15(2). https://doi.org/10.3390/app15020905
Tusher, E. H., Ismail, M. A., Akib, A., Gabralla, L. A., Ibrahim, A. O., Som, H. M., & Remli, M. A. (2025). Comparative investigation of bagging enhanced machine learning for early detection of HCV infections using class imbalance technique with feature selection. PLOS ONE, 20(6 June). https://doi.org/10.1371/journal.pone.0326488
Zhang, Y., Liu, J., & Shen, W. (2022). A Review of Ensemble Learning Algorithms Used in Remote Sensing Applications. In Applied Sciences (Switzerland) (Vol. 12, Number 17). https://doi.org/10.3390/app12178654
Zhao, H., Liu, W., Wang, Y., & Wu, L. (2025). Comparative analysis of algorithmic approaches in ensemble learning: bagging vs. boosting. Scientific Reports, 15(1). https://doi.org/10.1038/s41598-025-15971-0