BAB I PENDAHULUAN

1.1 Latar Belakang

Pada praktikum sebelumnya, kondisi kanker payudara diklasifikasikan menggunakan Bagging, yaitu menggabungkan banyak pohon keputusan yang dibangun secara paralel dari sampel bootstrap. Bagging efektif untuk menurunkan variance, tetapi setiap pohonnya dibangun tanpa memperhatikan kesalahan pohon lain (Breiman, 1996). Pendekatan ensemble lain yang bekerja dengan cara berbeda adalah Boosting. Pada Boosting, model dibangun secara berurutan (sequential), dan setiap model baru diarahkan untuk memperbaiki kesalahan yang masih dilakukan oleh model-model sebelumnya (Zhou, 2012; Hastie dkk., 2009).

Gagasan Boosting berawal dari pertanyaan apakah sekumpulan weak learner, yaitu model yang hanya sedikit lebih baik daripada tebakan acak, dapat digabungkan menjadi satu strong learner yang akurat. Schapire (1990) membuktikan bahwa hal tersebut mungkin dilakukan, kemudian Freund dan Schapire (1997) mengembangkan Adaptive Boosting (AdaBoost). AdaBoost memberikan bobot yang lebih besar kepada observasi yang salah diklasifikasikan sehingga learner berikutnya lebih fokus pada observasi yang sulit. Setiap learner juga diberi bobot sesuai performanya, lalu prediksi akhir ditentukan melalui voting terbobot. Weak learner yang paling sering digunakan pada AdaBoost adalah decision stump, yaitu pohon keputusan dengan satu pemisahan (Hastie dkk., 2009).

Kanker payudara merupakan kanker yang paling banyak didiagnosis di dunia pada tahun 2020 dengan sekitar 2,3 juta kasus baru (Sung dkk., 2021), sehingga model yang mampu membedakan tumor jinak (benign) dan ganas (malignant) dengan baik tetap penting untuk dikaji. Dataset BreastCancer pada paket mlbench yang digunakan pada Pertemuan 2 dan 3 kembali digunakan pada praktikum ini. Pada AdaBoost, banyaknya learner (mfinal) menentukan seberapa lama proses perbaikan dilakukan. Jumlah yang terlalu sedikit dapat membuat model belum belajar dengan cukup, sedangkan jumlah yang terlalu banyak dapat membuat model terlalu menyesuaikan diri dengan data training. Oleh karena itu, pada praktikum ini dibandingkan tiga nilai mfinal, yaitu 50, 100, dan 200. Kemampuan model dievaluasi menggunakan confusion matrix, accuracy, precision, recall, specificity, dan F1-Score (Sokolova & Lapalme, 2009). Berdasarkan hal tersebut, pada praktikum Pertemuan 4 ini dilakukan klasifikasi kondisi kanker payudara menggunakan AdaBoost dengan bantuan paket adabag di RStudio (Alfaro dkk., 2013).

1.2 Rumusan Masalah

Berdasarkan latar belakang di atas, rumusan masalah dalam praktikum ini adalah sebagai berikut:

  1. Bagaimana konsep dasar Boosting sebagai metode ensemble learning?
  2. Bagaimana mengimplementasikan Boosting untuk kasus klasifikasi menggunakan R?
  3. Bagaimana performa model AdaBoost dengan 50, 100, dan 200 learner berdasarkan ukuran evaluasi yang sesuai?

1.3 Tujuan Penelitian

Berdasarkan rumusan masalah di atas, tujuan praktikum ini adalah sebagai berikut:

  1. Mahasiswa dapat memahami Boosting sebagai metode ensemble learning.
  2. Mahasiswa dapat mengimplementasikan Boosting untuk kasus klasifikasi menggunakan R.
  3. Mahasiswa dapat mengevaluasi performa model menggunakan ukuran evaluasi yang sesuai.

1.4 Manfaat Penelitian

Adapun manfaat pada penelitian ini yaitu:

  1. Bagi penulis
    1. Memberikan informasi serta pengetahuan tentang metode Boosting dalam Machine Learning.
    2. Mengembangkan dan menerapkan wawasan ilmu yang telah diperoleh dalam bidang statistika khususnya tentang AdaBoost untuk klasifikasi dengan RStudio.
  2. Bagi pembaca
    Menambah ilmu pengetahuan dan pemahaman yang berkaitan tentang Boosting dan AdaBoost dengan RStudio.

1.5 Batasan Masalah

Adapun batasan masalah pada praktikum ini adalah lakukan klasifikasi menggunakan AdaBoost pada data BreastCancer dengan adabag::boosting() dan decision stump sebagai weak learner. Bandingkan untuk 50, 100, dan 200 jumlah learner, kemudian bandingkan pula performa model berdasarkan confusion matrix, accuracy, precision, recall, specificity, dan F1-Score. Gunakan set.seed(234) agar hasil pembagian data dapat direproduksi.

1.6 Sistematika Penulisan

Adapun sistematika penulisan dari praktikum ini adalah:

BAB IPENDAHULUAN

Bab I terdiri dari latar belakang, rumusan masalah, tujuan penelitian, manfaat penelitian, batasan masalah, dan sistematika penulisan.

BAB IITINJAUAN PUSTAKA

Bab ini berisi kajian pustaka dari jurnal, buku, dan modul praktikum tentang Boosting, AdaBoost, decision stump, dan evaluasi model klasifikasi.

BAB IIIMETODE PENELITIAN

Bab ini terdiri dari sumber data, variabel penelitian, langkah-langkah analisis, dan diagram alir.

BAB IVHASIL DAN PEMBAHASAN

Bab ini merupakan tahapan pencapaian hasil yang diperoleh dari analisis data yang dilakukan serta penjelasan dari hasil tersebut di bagian pembahasan.

BAB VKESIMPULAN DAN SARAN

Bab ini merupakan bagian penutup dalam laporan ini berupa penarikan kesimpulan mengenai hasil analisis dari penelitian serta penyampaian saran oleh penulis.

DAFTAR PUSTAKA

LAMPIRAN

BAB II TINJAUAN PUSTAKA

2.1 Ensemble Learning

Ensemble learning adalah pendekatan yang menggabungkan beberapa model dasar (base learner) agar diperoleh model gabungan yang memiliki kemampuan prediksi lebih baik daripada satu model saja (Dietterich, 2000). Berdasarkan cara pembentukannya, metode ensemble dibedakan menjadi metode paralel dan metode sekuensial. Pada metode paralel, seperti Bagging, model-model dibangun secara independen lalu hasilnya diagregasi. Pada metode sekuensial, seperti Boosting, model dibangun satu per satu dan setiap model baru bergantung pada hasil model sebelumnya (Zhou, 2012).

2.2 Boosting

Boosting adalah metode ensemble yang membentuk serangkaian model sederhana secara berurutan. Setiap model berikutnya dibangun dengan memperhatikan kesalahan yang masih dilakukan oleh model sebelumnya. Kekuatan Boosting tidak berasal dari satu model yang sangat kompleks, melainkan dari gabungan banyak model sederhana yang secara bertahap memperbaiki hasil prediksi (Laboratorium Matematika FMIPA Universitas Bengkulu, 2026). Model sederhana tersebut disebut weak learner, yaitu model yang kemampuan prediksinya terbatas jika digunakan sendiri, tetapi masih lebih baik daripada tebakan acak. Setelah sejumlah weak learner digabungkan, diperoleh model akhir yang lebih kuat, yang disebut strong learner (Schapire, 1990). Untuk kasus klasifikasi, salah satu algoritma Boosting yang paling banyak digunakan adalah AdaBoost (Freund & Schapire, 1997), sedangkan untuk kasus regresi umumnya digunakan Gradient Boosting (Friedman, 2001). Perbedaan Bagging dan Boosting dapat dilihat pada Tabel 1.

Tabel 1. Perbedaan Bagging dan Boosting
Aspek Bagging Boosting
Cara membangun model Paralel atau relatif independen Sekuensial, learner berikutnya bergantung pada hasil sebelumnya
Data tiap learner Umumnya sampel bootstrap Bobot data disesuaikan berdasarkan kesalahan sebelumnya
Fokus utama Mengurangi variance melalui agregasi Memperbaiki kesalahan secara bertahap
Kontribusi learner Umumnya setara Berbeda, misalnya pada AdaBoost melalui \(\alpha_m\)
Base learner Sering menggunakan pohon yang relatif besar Umumnya pohon sederhana atau pohon dangkal
Komputasi Mudah diparalelkan Lebih sulit diparalelkan karena bersifat sekuensial
Parameter penting Jumlah model atau sampel bootstrap Jumlah iterasi, learning rate, dan kompleksitas learner

Berdasarkan Tabel 1, Bagging membangun banyak learner secara independen kemudian menggabungkan hasilnya, sedangkan Boosting membangun learner secara berurutan agar setiap learner baru membantu memperbaiki kesalahan yang masih tersisa.

2.3 Adaptive Boosting (AdaBoost)

AdaBoost merupakan algoritma Boosting untuk kasus klasifikasi yang diperkenalkan oleh Freund dan Schapire (1997). Prinsip utama AdaBoost adalah memberikan perhatian lebih besar pada observasi yang masih salah diklasifikasikan. Untuk data training \((x_i, y_i)\) dengan \(i = 1, 2, \ldots, n\), langkah-langkah AdaBoost adalah sebagai berikut (Hastie dkk., 2009; Alfaro dkk., 2013).

  1. Memberikan bobot awal yang sama pada setiap observasi, yaitu \[ w_i^{(1)} = \frac{1}{n}, \qquad i = 1, 2, \ldots, n \tag{2.1} \] dengan \(w_i^{(1)}\) adalah bobot observasi ke-\(i\) pada iterasi pertama.
  2. Pada setiap iterasi \(m = 1, 2, \ldots, M\), membentuk weak learner \(G_m(x)\) menggunakan data training berbobot, kemudian menghitung kesalahan klasifikasi terbobot \[ err_m = \frac{\sum_{i=1}^{n} w_i^{(m)} I\left(y_i \neq G_m(x_i)\right)}{\sum_{i=1}^{n} w_i^{(m)}} \tag{2.2} \] dengan \(I(\cdot)\) adalah fungsi indikator yang bernilai 1 jika observasi ke-\(i\) salah diklasifikasikan dan 0 jika benar.
  3. Menghitung bobot learner berdasarkan performanya, yaitu \[ \alpha_m = \log\left(\frac{1 - err_m}{err_m}\right) \tag{2.3} \] Nilai \(\alpha_m\) semakin besar ketika \(err_m\) semakin kecil, sehingga learner yang lebih akurat memiliki kontribusi yang lebih besar terhadap prediksi akhir. Persamaan (2.3) merupakan rumus Freund dan Schapire (1997) yang digunakan pada argumen coeflearn = “Freund”. Pada paket adabag juga tersedia pilihan “Breiman” yang menggunakan \(\alpha_m = \frac{1}{2}\log\left(\frac{1 - err_m}{err_m}\right)\) (Alfaro dkk., 2013).
  4. Memperbarui bobot observasi sehingga observasi yang salah diklasifikasikan memperoleh bobot lebih besar, yaitu \[ w_i^{(m+1)} = \frac{w_i^{(m)} \exp\left[\alpha_m I\left(y_i \neq G_m(x_i)\right)\right]}{\sum_{j=1}^{n} w_j^{(m)} \exp\left[\alpha_m I\left(y_j \neq G_m(x_j)\right)\right]} \tag{2.4} \] Penyebut pada Persamaan (2.4) membuat jumlah seluruh bobot kembali bernilai satu. Pada fungsi boosting() di paket adabag, jika \(err_m \geq 0{,}5\), bobot observasi dikembalikan menjadi \(1/n\).
  5. Menggabungkan seluruh learner melalui voting terbobot. Kelas prediksi akhir untuk observasi \(x\) adalah kelas dengan jumlah bobot \(\alpha_m\) terbesar, yaitu \[ \hat{C}(x) = \underset{k}{\arg\max} \sum_{m=1}^{M} \alpha_m I\left(G_m(x) = k\right) \tag{2.5} \] Pada klasifikasi biner, Persamaan (2.5) setara dengan \(G(x) = \text{sign}\left[\sum_{m=1}^{M} \alpha_m G_m(x)\right]\) jika kelas dikodekan sebagai \(-1\) dan \(+1\). Paket adabag juga menghitung proporsi suara terbobot untuk setiap kelas sebagai berikut. \[ \hat{p}_k(x) = \frac{\sum_{m=1}^{M} \alpha_m I\left(G_m(x) = k\right)}{\sum_{m=1}^{M} \alpha_m} \tag{2.6} \]

Dengan demikian, AdaBoost memiliki dua jenis bobot, yaitu bobot observasi \(w_i^{(m)}\) yang mengatur perhatian terhadap data training dan bobot learner \(\alpha_m\) yang mengatur kontribusi setiap learner terhadap prediksi akhir. Alur kerja AdaBoost dapat dilihat pada Gambar 1.

Gambar 1. Alur kerja AdaBoost

Gambar 1. Alur kerja AdaBoost

Pada Gambar 1, stump pertama dibangun dari data training dengan bobot yang sama. Setelah itu, bobot observasi yang salah diklasifikasikan dinaikkan menjadi \(w^{(2)}\) sehingga stump kedua lebih memperhatikan observasi tersebut. Proses ini diulang sampai terbentuk \(M\) stump. Setiap stump memperoleh bobot \(\alpha_m\), kemudian prediksi akhir ditentukan berdasarkan voting terbobot dari seluruh stump.

2.4 Decision Stump

Decision stump adalah pohon keputusan dengan kedalaman satu, yaitu hanya memiliki satu simpul akar, satu pemisahan, dan dua simpul akhir. Karena hanya menggunakan satu variabel untuk memisahkan data, decision stump tergolong weak learner yang sederhana dan memiliki bias tinggi. Model seperti ini sangat cocok untuk Boosting karena kelemahannya akan diperbaiki secara bertahap oleh stump-stump berikutnya (Hastie dkk., 2009). Pada R, decision stump dapat dibentuk melalui argumen control = rpart.control(maxdepth = 1). Pemisahan terbaik pada rpart untuk kasus klasifikasi dipilih berdasarkan penurunan indeks Gini (Breiman dkk., 1984), yaitu \[ \text{Gini}(t) = 1 - \sum_{k=1}^{K} p(k \mid t)^2 \tag{2.7} \] dengan \(p(k \mid t)\) adalah proporsi (terbobot) observasi kelas ke-\(k\) pada simpul \(t\). Nilai Gini semakin kecil ketika simpul semakin murni, yaitu didominasi oleh satu kelas.

2.5 Parameter Penting pada Fungsi boosting()

AdaBoost pada praktikum ini dijalankan menggunakan fungsi boosting() dari paket adabag (Alfaro dkk., 2013). Argumen yang digunakan dan perannya dapat dilihat pada Tabel 2.

Tabel 2. Argumen fungsi boosting() yang digunakan
Argumen Nilai Peran
mfinal 50, 100, 200 Banyaknya iterasi atau banyaknya learner yang dibangun
coeflearn “Freund” Rumus bobot learner \(\alpha_m\) sesuai Persamaan (2.3)
boos FALSE Setiap learner dilatih pada seluruh data training dengan bobot \(w_i^{(m)}\), bukan pada sampel bootstrap
maxdepth 1 Membatasi kedalaman pohon sehingga setiap learner berupa decision stump
minsplit 10 Banyaknya observasi minimum pada suatu simpul agar simpul tersebut dapat dipisah
cp 0 Complexity parameter, pemisahan tidak dibatasi oleh besarnya penurunan galat

Jumlah iterasi yang terlalu sedikit dapat menyebabkan underfitting, sedangkan model yang terlalu kompleks atau iterasi yang terlalu banyak berpotensi mengalami overfitting (Laboratorium Matematika FMIPA Universitas Bengkulu, 2026). Jika boos = TRUE, setiap learner dilatih pada sampel bootstrap yang diambil dengan peluang sebanding dengan bobot observasi, sehingga hasilnya dipengaruhi pengacakan (Alfaro dkk., 2013). Karena boos = FALSE, proses pembentukan model bersifat deterministik.

2.6 Variable Importance

Variable importance pada paket adabag mengukur kontribusi relatif setiap variabel prediktor dalam klasifikasi. Ukuran ini menjumlahkan penurunan indeks Gini yang dihasilkan suatu variabel pada setiap pohon, kemudian memberikan bobot sesuai bobot pohon \(\alpha_m\), lalu dinyatakan dalam persen sehingga jumlah seluruhnya 100 (Alfaro dkk., 2013). Variabel yang sering digunakan oleh stump dengan \(\alpha_m\) besar dan menghasilkan pemisahan yang baik akan memiliki importance yang tinggi.

2.7 Penanganan Missing Value dan Splitting Data

Salah satu cara sederhana untuk menangani missing value adalah listwise deletion, yaitu menghapus observasi yang memiliki data kosong pada salah satu variabel (van Buuren, 2018). Cara ini mudah dilakukan, tetapi mengurangi ukuran data sehingga sebaiknya digunakan ketika jumlah data kosong relatif sedikit. Setelah data lengkap, data dibagi menjadi data training untuk melatih model dan data testing untuk menguji model pada data yang belum pernah dilihat (Muraina, 2022). Pembagian dilakukan secara stratified menggunakan fungsi createDataPartition() dari paket caret agar proporsi kelas pada data training dan testing sama dengan data awal (Kuhn, 2008).

2.8 Evaluasi Model Klasifikasi

Evaluasi model klasifikasi dilakukan dengan membandingkan kelas aktual dan kelas hasil prediksi dalam confusion matrix (Sokolova & Lapalme, 2009) seperti pada Tabel 3.

Tabel 3. Confusion matrix
Predicted Positive Predicted Negative
Actual Positive True Positive (TP) False Negative (FN)
Actual Negative False Positive (FP) True Negative (TN)

Ukuran evaluasi yang digunakan adalah sebagai berikut. \[ \text{Accuracy} = \frac{TP + TN}{TP + TN + FP + FN} \tag{2.8} \] \[ \text{Precision} = \frac{TP}{TP + FP} \tag{2.9} \] \[ \text{Recall} = \frac{TP}{TP + FN} \tag{2.10} \] \[ \text{Specificity} = \frac{TN}{TN + FP} \tag{2.11} \] \[ \text{F1-Score} = 2\left(\frac{\text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}}\right) \tag{2.12} \]

Accuracy adalah proporsi prediksi yang benar, precision adalah proporsi prediksi positif yang benar-benar positif, recall adalah kemampuan model mengenali kelas positif, specificity adalah kemampuan model mengenali kelas negatif, dan F1-Score adalah rata-rata harmonik dari precision dan recall. Kelas positif yang digunakan adalah malignant (ganas), sehingga False Negative berarti tumor ganas yang diprediksi jinak dan False Positive berarti tumor jinak yang diprediksi ganas.

BAB III METODE PENELITIAN

3.1 Sumber Data

Data yang digunakan adalah data sekunder berupa dataset BreastCancer yang tersedia pada paket mlbench di R (Leisch & Dimitriadou, 2010). Data ini berasal dari penelitian Wolberg dan Mangasarian (1990) yang dikumpulkan di University of Wisconsin Hospitals, Madison. Data terdiri dari 699 observasi dan 11 variabel, yaitu satu variabel pengenal, sembilan variabel karakteristik sel, dan satu variabel kelas.

3.2 Variabel Penelitian

Variabel yang digunakan terdiri dari satu variabel target dan sembilan variabel prediktor. Variabel target (Y) adalah Class yang terdiri dari dua kategori, yaitu benign (jinak) dan malignant (ganas). Variabel prediktor (X) berupa hasil penilaian karakteristik sel dengan skor 1 sampai 10 yang pada R terbaca sebagai data kategorik (factor). Variabel Id hanya berupa kode pengenal sampel sehingga tidak digunakan dalam analisis. Rincian variabel dapat dilihat pada Tabel 4.

Tabel 4. Variabel penelitian
Variabel Keterangan Peran
Id Kode sampel Tidak digunakan
Cl.thickness Ketebalan gumpalan sel (clump thickness) Prediktor (X1)
Cell.size Keseragaman ukuran sel Prediktor (X2)
Cell.shape Keseragaman bentuk sel Prediktor (X3)
Marg.adhesion Adhesi marginal (marginal adhesion) Prediktor (X4)
Epith.c.size Ukuran sel epitel tunggal Prediktor (X5)
Bare.nuclei Inti sel telanjang (bare nuclei) Prediktor (X6)
Bl.cromatin Kromatin halus (bland chromatin) Prediktor (X7)
Normal.nucleoli Nukleolus normal Prediktor (X8)
Mitoses Mitosis Prediktor (X9)
Class Kondisi tumor: benign atau malignant Target (Y)

3.3 Langkah-langkah Analisis

Langkah-langkah analisis yang dilakukan adalah sebagai berikut.

  1. Mengimpor dataset BreastCancer dari paket mlbench.
  2. Menghapus variabel Id, menghapus observasi yang mengandung missing value, dan memastikan variabel Class bertipe factor.
  3. Membagi data menjadi 70% data training dan 30% data testing secara stratified berdasarkan variabel Class dengan set.seed(234).
  4. Membangun model AdaBoost menggunakan boosting() dengan decision stump sebagai weak learner untuk mfinal = 50, 100, dan 200.
  5. Melihat bobot learner (\(\alpha_m\)) dan variabel pemisah pada stump yang terbentuk.
  6. Melakukan prediksi pada data testing.
  7. Menghitung confusion matrix, accuracy, precision, recall, specificity, dan F1-Score untuk ketiga model.
  8. Melihat perkembangan error pada data training dan testing serta variable importance.
  9. Membandingkan hasil mfinal = 50, 100, dan 200 untuk menentukan model terbaik.
  10. Menginterpretasikan setiap output dan menarik kesimpulan.

3.4 Diagram Alir Penelitian

Gambar 2. Diagram alir penelitian

Gambar 2. Diagram alir penelitian

BAB IV HASIL DAN PEMBAHASAN

4.1 Library dan Import Data

Library yang digunakan adalah adabag, mlbench, caret, rpart, dan ggplot2. Paket adabag digunakan untuk membangun model AdaBoost, mlbench untuk mengambil dataset, caret untuk membagi data dan membuat confusion matrix, rpart untuk membentuk decision stump, serta ggplot2 untuk visualisasi.

library(adabag)
library(mlbench)
library(caret)
library(rpart)
library(ggplot2)
data(BreastCancer, package = "mlbench")
bc <- BreastCancer
str(bc)
## '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 ...
colSums(is.na(bc))
##              Id    Cl.thickness       Cell.size      Cell.shape   Marg.adhesion 
##               0               0               0               0               0 
##    Epith.c.size     Bare.nuclei     Bl.cromatin Normal.nucleoli         Mitoses 
##               0              16               0               0               0 
##           Class 
##               0

Data terdiri dari 699 observasi dan 11 variabel. Variabel Id bertipe karakter, sembilan variabel karakteristik sel bertipe kategorik (Ord.factor atau Factor) dengan skor 1 sampai 10, dan Class memiliki dua level, yaitu benign dan malignant. Missing value hanya terdapat pada variabel Bare.nuclei sebanyak 16 data.

4.2 Persiapan Data

Persiapan data dilakukan sesuai sintaks modul, yaitu menghapus variabel Id, menghapus observasi yang mengandung missing value, dan memastikan variabel respon bertipe factor.

bc$Id <- NULL
bc <- na.omit(bc)
bc$Class <- droplevels(as.factor(bc$Class))
dim(bc)
## [1] 683  10
levels(bc$Class)
## [1] "benign"    "malignant"
table(bc$Class)
## 
##    benign malignant 
##       444       239
round(prop.table(table(bc$Class)) * 100, 2)
## 
##    benign malignant 
##     65.01     34.99

Setelah variabel Id dan 16 observasi yang mengandung missing value dihapus, data tersisa 683 observasi dan 10 variabel. Observasi yang dihapus hanya sekitar 2,29% dari data awal, sehingga pengurangan ukuran data akibat listwise deletion tergolong kecil. Data terdiri dari 444 observasi benign (65,01%) dan 239 observasi malignant (34,99%), sehingga kelas benign hampir dua kali lebih banyak daripada kelas malignant.

4.3 Splitting Data

set.seed(234)
idx.cls <- createDataPartition(bc$Class, p = 0.70, list = FALSE)
bc.train <- bc[idx.cls, ]
bc.test <- bc[-idx.cls, ]

dim(bc.train)
## [1] 479  10
dim(bc.test)
## [1] 204  10
table(bc.train$Class)
## 
##    benign malignant 
##       311       168
table(bc.test$Class)
## 
##    benign malignant 
##       133        71
round(prop.table(table(bc.train$Class)) * 100, 2)
## 
##    benign malignant 
##     64.93     35.07
round(prop.table(table(bc.test$Class)) * 100, 2)
## 
##    benign malignant 
##      65.2      34.8

Data dibagi menjadi 479 data training (311 benign dan 168 malignant) dan 204 data testing (133 benign dan 71 malignant). Proporsi kelas pada data training (64,93% dan 35,07%) dan data testing (65,20% dan 34,80%) hampir sama dengan data awal, sehingga pembagian secara stratified berhasil menjaga komposisi kelas. Ketiga model AdaBoost dilatih dan diuji menggunakan data yang sama, sehingga perbedaan hasilnya hanya berasal dari banyaknya learner.

4.4 Membangun Model AdaBoost

Model dibangun menggunakan fungsi boosting() dengan pengaturan yang sama seperti sintaks modul. Decision stump dibentuk melalui maxdepth = 1, kemudian banyaknya learner diatur melalui mfinal = 50, 100, dan 200.

set.seed(234)
ada50 <- boosting(Class ~ ., data = bc.train, boos = FALSE, mfinal = 50, coeflearn = "Freund",
                  control = rpart.control(maxdepth = 1, minsplit = 10, cp = 0))
set.seed(234)
ada100 <- boosting(Class ~ ., data = bc.train, boos = FALSE, mfinal = 100, coeflearn = "Freund",
                   control = rpart.control(maxdepth = 1, minsplit = 10, cp = 0))
set.seed(234)
ada200 <- boosting(Class ~ ., data = bc.train, boos = FALSE, mfinal = 200, coeflearn = "Freund",
                   control = rpart.control(maxdepth = 1, minsplit = 10, cp = 0))

# apakah 50 dan 100 stump pertama pada model 200 sama dengan model 50 dan 100?
all.equal(ada50$weights, ada200$weights[1:50])
## [1] TRUE
all.equal(ada100$weights, ada200$weights[1:100])
## [1] TRUE

Karena boos = FALSE, setiap stump dilatih pada seluruh data training dengan bobot observasi, sehingga tidak ada proses pengacakan. Akibatnya, 50 stump pertama pada model mfinal = 100 dan 200 sama persis dengan model mfinal = 50, dan 100 stump pertama pada model mfinal = 200 sama dengan model mfinal = 100. Jadi, ketiga model dapat dipandang sebagai satu proses Boosting yang dihentikan pada iterasi yang berbeda. Fungsi print() pada objek boosting akan menampilkan seluruh stump sehingga output-nya sangat panjang. Oleh karena itu, model dilihat secara ringkas melalui stump pertama, bobot \(\alpha_m\), dan variabel pemisah setiap stump.

ada200$trees[[1]]
## n= 479 
## 
## node), split, n, loss, yval, (yprob)
##       * denotes terminal node
## 
## 1) root 479 0.35073070 benign (0.77410861 0.22589139)  
##   2) Cell.size=1,2 291 0.01461378 benign (0.98686034 0.01313966) *
##   3) Cell.size=3,4,5,6,7,8,9,10 188 0.05636743 malignant (0.23690224 0.76309776) *
round(ada200$weights[1:10], 4)
##  [1] 2.5717 1.9856 1.5321 1.0065 1.0698 0.5802 0.5451 0.6917 0.6391 0.9349
sapply(ada200$trees[1:10], function(t) as.character(t$frame$var[1]))
##  [1] "Cell.size"       "Bare.nuclei"     "Bare.nuclei"     "Cell.size"      
##  [5] "Marg.adhesion"   "Cl.thickness"    "<leaf>"          "Normal.nucleoli"
##  [9] "Bare.nuclei"     "Cl.thickness"
# rata-rata bobot learner pada iterasi 1-50, 51-100, dan 101-200
round(c(mean(ada200$weights[1:50]), mean(ada200$weights[51:100]), mean(ada200$weights[101:200])), 4)
## [1] 0.4859 0.1793 0.1345
# variabel pemisah pada setiap stump
pemisah <- lapply(list(ada50, ada100, ada200), function(m) table(sapply(m$trees, function(t) as.character(t$frame$var[1]))))
pemisah
## [[1]]
## 
##          <leaf>     Bare.nuclei     Bl.cromatin      Cell.shape       Cell.size 
##               8               6               4               1               2 
##    Cl.thickness    Epith.c.size   Marg.adhesion         Mitoses Normal.nucleoli 
##               7               4               7               7               4 
## 
## [[2]]
## 
##          <leaf>     Bare.nuclei     Bl.cromatin      Cell.shape       Cell.size 
##              18              10               5              12               2 
##    Cl.thickness    Epith.c.size   Marg.adhesion         Mitoses Normal.nucleoli 
##              14               8               9              10              12 
## 
## [[3]]
## 
##          <leaf>     Bare.nuclei     Bl.cromatin      Cell.shape       Cell.size 
##              42              16              12              21               2 
##    Cl.thickness    Epith.c.size   Marg.adhesion         Mitoses Normal.nucleoli 
##              28              24              13              16              26

Stump pertama memisahkan data berdasarkan Cell.size. Observasi dengan skor Cell.size 1 atau 2 (291 observasi) diprediksi benign, sedangkan observasi dengan skor 3 sampai 10 (188 observasi) diprediksi malignant. Stump ini memperoleh bobot terbesar, yaitu \(\alpha_1\) = 2,5717. Berdasarkan Persamaan (2.3), nilai tersebut setara dengan kesalahan terbobot \(err_1 = 1/(1 + e^{2,5717}) \approx 0{,}0710\), yaitu 34 dari 479 data training salah diklasifikasikan. Stump kedua dan ketiga menggunakan Bare.nuclei dengan \(\alpha\) sebesar 1,9856 dan 1,5321. Bobot learner cenderung mengecil pada iterasi selanjutnya, dengan rata-rata 0,4859 pada iterasi 1–50, 0,1793 pada iterasi 51–100, dan 0,1345 pada iterasi 101–200. Hal ini terjadi karena observasi yang mudah sudah diklasifikasikan dengan benar oleh stump-stump awal, sehingga stump berikutnya hanya fokus pada observasi yang sulit dan kesalahan terbobotnya semakin mendekati 0,5.

Variabel pemisah juga berganti-ganti. Pada model mfinal = 50, Cl.thickness, Marg.adhesion, dan Mitoses masing-masing digunakan oleh 7 stump, sedangkan Cell.size hanya digunakan oleh 2 stump. Selain itu, terdapat stump yang tidak memiliki pemisahan (tertulis “”), yaitu 8 dari 50 stump, 18 dari 100 stump, dan 42 dari 200 stump. Pada iterasi tersebut, pemisahan terbaik menghasilkan dua simpul yang sama-sama memprediksi malignant, sehingga tidak menurunkan galat klasifikasi terbobot. Dengan cp = 0, rpart tidak mempertahankan pemisahan seperti ini, sehingga stump hanya berupa simpul akar yang memprediksi malignant untuk semua observasi. Perubahan bobot \(\alpha_m\) pada setiap iterasi dapat dilihat pada Gambar 3.

alpha <- data.frame(Iterasi = 1:200, Alpha = ada200$weights,
                    Stump = ifelse(sapply(ada200$trees, function(t) nrow(t$frame)) > 1,
                                   "Memiliki pemisahan", "Tanpa pemisahan (hanya simpul akar)"))

ggplot(alpha, aes(Iterasi, Alpha)) +
  geom_line(colour = "grey75") +
  geom_point(aes(colour = Stump), size = 1.6) +
  geom_vline(xintercept = c(50, 100), linetype = "dashed", colour = "grey50") +
  annotate("text", x = c(50, 100), y = 2.6, label = c("mfinal = 50", "mfinal = 100"), hjust = -0.1, size = 3.2) +
  scale_colour_manual(values = c("#008080", "#E07B00")) +
  labs(x = "Iterasi (m)", y = expression("Bobot learner " * alpha[m]), colour = "") +
  theme_minimal() +
  theme(legend.position = "bottom")
Gambar 3. Bobot learner (&alpha;) pada setiap iterasi model mfinal = 200

Gambar 3. Bobot learner (α) pada setiap iterasi model mfinal = 200

Pada Gambar 3, bobot \(\alpha_m\) sangat besar pada beberapa iterasi pertama, kemudian turun dengan cepat dan berfluktuasi di sekitar nilai yang kecil. Artinya, prediksi model terutama ditentukan oleh stump-stump awal, sedangkan stump yang ditambahkan setelah iterasi ke-50 hanya memberikan koreksi kecil. Stump tanpa pemisahan juga semakin sering muncul pada iterasi akhir, yang menunjukkan bahwa semakin sulit menemukan pemisahan yang masih dapat memperbaiki kesalahan klasifikasi.

4.5 Prediksi Data Testing

pred.obj <- lapply(list(ada50, ada100, ada200), predict, newdata = bc.test)
pred <- lapply(pred.obj, function(p) factor(p$class, levels = levels(bc.test$Class)))
names(pred) <- c("mfinal = 50", "mfinal = 100", "mfinal = 200")

hasil.ada <- data.frame(Aktual = bc.test$Class, pred, check.names = FALSE)
head(hasil.ada, 10)
##       Aktual mfinal = 50 mfinal = 100 mfinal = 200
## 1     benign   malignant    malignant    malignant
## 2     benign      benign       benign       benign
## 3     benign      benign       benign       benign
## 4     benign      benign       benign       benign
## 5     benign      benign       benign       benign
## 6  malignant   malignant    malignant    malignant
## 7     benign      benign       benign       benign
## 8     benign      benign       benign       benign
## 9     benign      benign       benign       benign
## 10 malignant   malignant    malignant    malignant
# banyaknya prediksi yang berbeda antarmodel
c("50 vs 100" = sum(pred[[1]] != pred[[2]]), "100 vs 200" = sum(pred[[2]] != pred[[3]]))
##  50 vs 100 100 vs 200 
##          0          1

Pada 10 observasi pertama data testing, ketiga model memberikan prediksi yang sama dan 9 observasi diprediksi dengan benar. Observasi pertama sebenarnya benign, tetapi diprediksi malignant oleh ketiga model. Secara keseluruhan, model mfinal = 50 dan 100 menghasilkan prediksi yang sama persis pada seluruh 204 data testing, sedangkan model mfinal = 200 berbeda pada satu observasi.

4.6 Confusion Matrix dan Ukuran Evaluasi

Confusion matrix dibentuk menggunakan fungsi confusionMatrix() dari paket caret dengan malignant sebagai kelas positif, sesuai sintaks modul. Output lengkap ditampilkan untuk model mfinal = 50 sebagai contoh.

cm <- lapply(pred, confusionMatrix, reference = bc.test$Class, positive = "malignant")
cm[["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       
## 

Pada output fungsi confusionMatrix(), baris menunjukkan kelas prediksi (Prediction) dan kolom menunjukkan kelas aktual (Reference). Model mfinal = 50 memiliki accuracy 0,9657 dengan selang kepercayaan 95% antara 0,9306 dan 0,9861, jauh di atas No Information Rate sebesar 0,652, yaitu akurasi jika semua observasi ditebak sebagai kelas mayoritas (benign). Sensitivity dan Pos Pred Value pada output ini sama dengan recall dan precision. Selanjutnya, ukuran evaluasi untuk ketiga model dihitung dengan cara yang sama seperti sintaks modul, yaitu mengambil nilai TN, FP, FN, dan TP dari tabel aktual dan prediksi.

evaluasi <- function(p) {
  tab <- table(Aktual = bc.test$Class, Prediksi = p)
  TN <- tab["benign", "benign"]; FP <- tab["benign", "malignant"]
  FN <- tab["malignant", "benign"]; TP <- tab["malignant", "malignant"]
  Precision <- TP / (TP + FP)
  Recall <- TP / (TP + FN)
  round(c(Accuracy = (TP + TN) / sum(tab), Precision = Precision, Recall = Recall,
          Specificity = TN / (TN + FP), F1_Score = 2 * Precision * Recall / (Precision + Recall)), 4)
}

lapply(pred, function(p) table(Aktual = bc.test$Class, Prediksi = p))
## $`mfinal = 50`
##            Prediksi
## Aktual      benign malignant
##   benign       130         3
##   malignant      4        67
## 
## $`mfinal = 100`
##            Prediksi
## Aktual      benign malignant
##   benign       130         3
##   malignant      4        67
## 
## $`mfinal = 200`
##            Prediksi
## Aktual      benign malignant
##   benign       130         3
##   malignant      5        66
evaluasi.ada <- t(sapply(pred, evaluasi))
evaluasi.ada
##              Accuracy Precision Recall Specificity F1_Score
## mfinal = 50    0.9657    0.9571 0.9437      0.9774   0.9504
## mfinal = 100   0.9657    0.9571 0.9437      0.9774   0.9504
## mfinal = 200   0.9608    0.9565 0.9296      0.9774   0.9429
# proporsi suara malignant pada observasi yang prediksinya berubah dari mfinal = 100 ke 200
beda <- which(pred[[2]] != pred[[3]])
sapply(pred.obj, function(p) round(p$prob[beda, 2], 4))
## [1] 0.5136 0.5058 0.4961
# observasi yang salah diklasifikasikan oleh model mfinal = 100
salah <- which(pred[[2]] != bc.test$Class)
data.frame(Aktual = bc.test$Class[salah], Prediksi = pred[[2]][salah],
           P_malignant = round(pred.obj[[2]]$prob[salah, 2], 4))
##      Aktual  Prediksi P_malignant
## 1    benign malignant      0.5918
## 2 malignant    benign      0.4451
## 3 malignant    benign      0.4028
## 4    benign malignant      0.7159
## 5 malignant    benign      0.4481
## 6 malignant    benign      0.4616
## 7    benign malignant      0.5430
cm.df <- do.call(rbind, lapply(names(pred), function(nm) {
  d <- as.data.frame(table(Aktual = bc.test$Class, Prediksi = pred[[nm]]))
  d$Model <- nm
  d
}))
cm.df$Model <- factor(cm.df$Model, levels = names(pred))
cm.df$Benar <- cm.df$Aktual == cm.df$Prediksi

ggplot(cm.df, aes(Prediksi, Aktual, fill = Benar)) +
  geom_tile(colour = "white", linewidth = 1) +
  geom_text(aes(label = Freq), size = 5, fontface = "bold") +
  facet_wrap(~ Model) +
  scale_fill_manual(values = c("TRUE" = "#A5D6A7", "FALSE" = "#F4B6B6"), labels = c("Salah", "Benar")) +
  scale_y_discrete(limits = rev(levels(bc.test$Class))) +
  labs(x = "Kelas prediksi", y = "Kelas aktual", fill = "") +
  theme_minimal() +
  theme(legend.position = "bottom", panel.grid = element_blank())
Gambar 4. Confusion matrix model AdaBoost pada data testing

Gambar 4. Confusion matrix model AdaBoost pada data testing

Berdasarkan Gambar 4, model mfinal = 50 dan 100 menghasilkan confusion matrix yang sama, yaitu 130 tumor jinak dan 67 tumor ganas diprediksi benar, 3 tumor jinak diprediksi ganas (False Positive), dan 4 tumor ganas diprediksi jinak (False Negative). Kedua model memiliki accuracy 0,9657, precision 0,9571, recall 0,9437, specificity 0,9774, dan F1-Score 0,9504. Pada model mfinal = 200, False Negative bertambah menjadi 5, sehingga accuracy turun menjadi 0,9608, recall menjadi 0,9296, precision menjadi 0,9565, dan F1-Score menjadi 0,9429, sedangkan specificity tetap 0,9774.

Observasi yang berubah prediksinya adalah satu tumor ganas dengan proporsi suara terbobot untuk malignant sebesar 0,5136 pada mfinal = 50, 0,5058 pada mfinal = 100, dan 0,4961 pada mfinal = 200. Penambahan stump sedikit demi sedikit menggeser suara observasi ini sampai melewati batas 0,5, sehingga observasi tersebut diprediksi benign. Ketujuh observasi yang salah diklasifikasikan pada model mfinal = 100 juga umumnya berada dekat batas keputusan. Empat tumor ganas yang diprediksi jinak memiliki proporsi suara malignant antara 0,4028 dan 0,4616, sedangkan tiga tumor jinak yang diprediksi ganas memiliki proporsi suara antara 0,5430 dan 0,7159. Jadi, kesalahan model sebagian besar terjadi pada observasi yang memang sulit dibedakan. Pada kasus kanker payudara, False Negative lebih berisiko daripada False Positive karena tumor ganas yang tidak terdeteksi dapat terlambat ditangani, sehingga turunnya recall pada mfinal = 200 perlu diperhatikan.

4.7 Perkembangan Error AdaBoost

Perkembangan error dihitung menggunakan fungsi errorevol(). Karena 50 dan 100 stump pertama pada model mfinal = 200 sama dengan model mfinal = 50 dan 100, perkembangan error model mfinal = 200 sudah mencakup ketiga model.

error.train <- errorevol(ada200, newdata = bc.train)$error
error.test <- errorevol(ada200, newdata = bc.test)$error
it <- c(1, 10, 25, 50, 100, 135, 136, 172, 200)
err.tab <- rbind(Training = error.train, Testing = error.test)[, it]
colnames(err.tab) <- paste0("m=", it)
round(err.tab, 4)
##             m=1   m=10   m=25   m=50  m=100  m=135  m=136  m=172  m=200
## Training 0.0710 0.0355 0.0292 0.0230 0.0146 0.0125 0.0146 0.0104 0.0125
## Testing  0.0784 0.0441 0.0343 0.0343 0.0343 0.0343 0.0392 0.0392 0.0392
# iterasi dengan error terkecil
data.frame(Data = c("Training", "Testing"), Iterasi = c(which.min(error.train), which.min(error.test)),
           Error = round(c(min(error.train), min(error.test)), 4))
##       Data Iterasi  Error
## 1 Training     172 0.0104
## 2  Testing      25 0.0343
err.df <- data.frame(Iterasi = rep(1:200, 2), Error = c(error.train, error.test),
                     Data = rep(c("Training", "Testing"), each = 200))

ggplot(err.df, aes(Iterasi, Error, colour = Data)) +
  geom_line(linewidth = 0.8) +
  geom_vline(xintercept = c(50, 100, 200), linetype = "dashed", colour = "grey55") +
  annotate("text", x = c(50, 100, 200), y = 0.075, label = c("50", "100", "200"), hjust = 1.2, size = 3.2) +
  scale_colour_manual(values = c("Training" = "#008080", "Testing" = "#E07B00")) +
  labs(x = "Banyaknya learner (iterasi)", y = "Error klasifikasi", colour = "") +
  theme_minimal() +
  theme(legend.position = "bottom")
Gambar 5. Perkembangan error training dan testing AdaBoost

Gambar 5. Perkembangan error training dan testing AdaBoost

Pada Gambar 5, error training cenderung terus turun, yaitu dari 0,0710 pada iterasi pertama menjadi 0,0230 pada iterasi ke-50, 0,0146 pada iterasi ke-100, dan 0,0125 pada iterasi ke-200, dengan nilai terkecil 0,0104 pada iterasi ke-172. Error testing juga turun dengan cepat dari 0,0784 pada iterasi pertama dan mencapai nilai terkecil 0,0343, yaitu 7 dari 204 data salah diklasifikasikan, sejak iterasi ke-25. Nilai ini bertahan sampai iterasi ke-135, kemudian naik menjadi 0,0392 (8 data salah) dari iterasi ke-136 sampai 200. Jadi, setelah sekitar 135 iterasi, error training masih cenderung turun tetapi error testing justru naik. Pola ini merupakan tanda awal overfitting, yaitu model mulai terlalu menyesuaikan diri dengan data training. Meskipun demikian, kenaikannya hanya satu observasi sehingga overfitting yang terjadi masih ringan.

4.8 Variable Importance

imp <- sapply(list(ada50, ada100, ada200), function(m) m$importance)
colnames(imp) <- names(pred)
round(imp[order(imp[, 3], decreasing = TRUE), ], 2)
##                 mfinal = 50 mfinal = 100 mfinal = 200
## Cell.size             41.86        39.43        37.36
## Bare.nuclei           30.64        29.38        28.17
## Cl.thickness           8.95         9.22         9.84
## Marg.adhesion          7.33         7.40         7.32
## Normal.nucleoli        4.74         5.52         5.93
## Mitoses                2.57         2.92         3.17
## Epith.c.size           1.37         1.91         2.97
## Cell.shape             0.81         2.06         2.74
## Bl.cromatin            1.74         2.15         2.51
imp.df <- data.frame(Variabel = rep(rownames(imp), 3), Importance = as.vector(imp),
                     Model = factor(rep(colnames(imp), each = nrow(imp)), levels = colnames(imp)))
imp.df$Variabel <- factor(imp.df$Variabel, levels = rownames(imp)[order(imp[, 3])])

ggplot(imp.df, aes(Importance, Variabel, fill = Model)) +
  geom_col(position = position_dodge(width = 0.8), width = 0.75) +
  scale_fill_manual(values = c("#BFE0F5", "#5DA9D6", "#1F5F8B")) +
  labs(x = "Importance (%)", y = NULL, fill = "") +
  theme_minimal() +
  theme(legend.position = "bottom")
Gambar 6. Variable importance model AdaBoost

Gambar 6. Variable importance model AdaBoost

Berdasarkan Gambar 6, Cell.size merupakan variabel paling penting pada ketiga model dengan importance 41,86% (mfinal = 50), 39,43% (mfinal = 100), dan 37,36% (mfinal = 200). Variabel kedua adalah Bare.nuclei dengan importance 30,64%, 29,38%, dan 28,17%. Kedua variabel ini bersama-sama menyumbang 72,50%, 68,81%, dan 65,53% dari total importance. Menariknya, Cell.size hanya menjadi pemisah pada 2 dari 50 stump, tetapi salah satunya adalah stump pertama dengan bobot \(\alpha\) terbesar dan penurunan indeks Gini yang besar. Hal ini sesuai dengan cara perhitungan pada subbab 2.6, yaitu importance ditimbang dengan bobot learner. Urutan lima variabel teratas sama pada ketiga model, yaitu Cell.size, Bare.nuclei, Cl.thickness, Marg.adhesion, dan Normal.nucleoli. Semakin banyak learner, importance sedikit lebih merata ke variabel lain karena stump tambahan menggunakan variabel yang lebih beragam, tetapi kontribusinya kecil karena bobot \(\alpha\)-nya juga kecil.

4.9 Perbandingan Hasil mfinal = 50, 100, dan 200

ringkasan <- data.frame(mfinal = c(50, 100, 200),
                        Akurasi_training = sapply(list(ada50, ada100, ada200), function(m) mean(m$class == bc.train$Class)),
                        evaluasi.ada, row.names = NULL)
knitr::kable(ringkasan, digits = 4, align = "c", format.args = list(decimal.mark = ","),
             col.names = c("mfinal", "Akurasi training", "Accuracy", "Precision", "Recall",
                           "Specificity", "F1-Score"),
             caption = "Tabel 5. Perbandingan hasil AdaBoost pada *mfinal* = 50, 100, dan 200")
Tabel 5. Perbandingan hasil AdaBoost pada mfinal = 50, 100, dan 200
mfinal Akurasi training Accuracy Precision Recall Specificity F1-Score
50 0,9770 0,9657 0,9571 0,9437 0,9774 0,9504
100 0,9854 0,9657 0,9571 0,9437 0,9774 0,9504
200 0,9875 0,9608 0,9565 0,9296 0,9774 0,9429

Berdasarkan Tabel 5, akurasi pada data training terus naik dari 0,9770 (mfinal = 50) menjadi 0,9854 (mfinal = 100) dan 0,9875 (mfinal = 200), tetapi kenaikan ini tidak diikuti oleh data testing. Model mfinal = 50 dan 100 memiliki performa yang sama pada data testing, sedangkan model mfinal = 200 sedikit lebih buruk pada accuracy, precision, recall, dan F1-Score. Penambahan learner dari 50 menjadi 100 tidak memperbaiki prediksi pada data baru, dan penambahan sampai 200 justru menambah satu False Negative. Hal ini menunjukkan bahwa model sudah cukup belajar pada sekitar 50 learner. Oleh karena itu, model mfinal = 50 dipilih sebagai model terbaik karena menghasilkan performa tertinggi yang sama dengan mfinal = 100, tetapi dengan model yang lebih sederhana dan waktu komputasi yang lebih singkat. Perlu diperhatikan bahwa perbedaan antarmodel hanya satu observasi dari 204 data testing, sehingga ketiga model sebenarnya memiliki kemampuan klasifikasi yang sangat baik dan hampir sama.

BAB V KESIMPULAN DAN SARAN

5.1 Kesimpulan

Boosting adalah metode ensemble learning yang membangun banyak weak learner secara berurutan, dengan setiap learner baru diarahkan untuk memperbaiki kesalahan learner sebelumnya, sehingga gabungannya membentuk strong learner. Pada AdaBoost, perbaikan dilakukan dengan menaikkan bobot observasi yang salah diklasifikasikan dan memberikan bobot \(\alpha_m\) yang lebih besar kepada learner yang lebih akurat, kemudian prediksi akhir ditentukan melalui voting terbobot.

AdaBoost untuk klasifikasi diimplementasikan di RStudio menggunakan fungsi boosting() dari paket adabag dengan decision stump sebagai weak learner melalui rpart.control(maxdepth = 1). Banyaknya learner diatur melalui argumen mfinal, bobot learner dihitung dengan coeflearn = “Freund”, dan prediksi diperoleh dengan predict(). Evaluasi dilakukan dengan confusionMatrix() serta menghitung nilai TN, FP, FN, dan TP, sedangkan perkembangan error dan variable importance diperoleh melalui errorevol() dan komponen importance pada objek model.

Berdasarkan hasil praktikum, model AdaBoost dengan mfinal = 50 dan 100 menghasilkan performa yang sama pada data testing, yaitu accuracy 0,9657, precision 0,9571, recall 0,9437, specificity 0,9774, dan F1-Score 0,9504. Model mfinal = 200 menghasilkan accuracy 0,9608, precision 0,9565, recall 0,9296, specificity 0,9774, dan F1-Score 0,9429 karena satu tumor ganas tambahan diprediksi jinak. Error training terus turun sampai iterasi ke-200, sedangkan error testing mencapai nilai terkecil 0,0343 pada iterasi ke-25 sampai 135 lalu naik menjadi 0,0392, yang menunjukkan overfitting ringan pada jumlah learner yang besar. Model terbaik adalah mfinal = 50 karena performanya setara dengan mfinal = 100 tetapi lebih sederhana. Variabel yang paling berpengaruh dalam klasifikasi adalah Cell.size dan Bare.nuclei.

5.2 Saran

Pada praktikum Machine Learning berikutnya, disarankan agar praktikan lebih teliti dalam penggunaan sintaks dan interpretasi output di RStudio, terutama dalam membaca output confusionMatrix() yang menempatkan kelas prediksi pada baris dan kelas aktual pada kolom. Jumlah learner sebaiknya tidak dipilih hanya berdasarkan akurasi pada data training, karena akurasi training terus naik meskipun akurasi testing tidak lagi membaik. Pemilihan mfinal dapat dilakukan dengan validasi silang, misalnya menggunakan boosting.cv(), agar tidak bergantung pada satu pembagian data testing. Selain itu, hasil AdaBoost dapat dibandingkan dengan Bagging atau Random Forest pada data yang sama, serta dicoba dengan pohon yang lebih dalam atau coeflearn yang berbeda untuk melihat pengaruhnya terhadap performa model.

DAFTAR PUSTAKA

Alfaro, E., Gámez, M., & García, N. (2013). adabag: An R package for classification with boosting and bagging. Journal of Statistical Software, 54(2), 1–35. https://doi.org/10.18637/jss.v054.i02

Breiman, L. (1996). Bagging predictors. Machine Learning, 24(2), 123–140. https://doi.org/10.1007/BF00058655

Breiman, L., Friedman, J. H., Olshen, R. A., & Stone, C. J. (1984). Classification and regression trees. Wadsworth.

Dietterich, T. G. (2000). Ensemble methods in machine learning. Dalam Multiple Classifier Systems (Lecture Notes in Computer Science, Vol. 1857, hlm. 1–15). Springer. https://doi.org/10.1007/3-540-45014-9_1

Freund, Y., & Schapire, R. E. (1997). A decision-theoretic generalization of on-line learning and an application to boosting. Journal of Computer and System Sciences, 55(1), 119–139. https://doi.org/10.1006/jcss.1997.1504

Friedman, J. H. (2001). Greedy function approximation: A gradient boosting machine. The Annals of Statistics, 29(5), 1189–1232. https://doi.org/10.1214/aos/1013203451

Hastie, T., Tibshirani, R., & Friedman, J. (2009). The elements of statistical learning: Data mining, inference, and prediction (2nd ed.). Springer.

Kuhn, M. (2008). Building predictive models in R using the caret package. Journal of Statistical Software, 28(5), 1–26. https://doi.org/10.18637/jss.v028.i05

Laboratorium Matematika FMIPA Universitas Bengkulu. (2026). Modul praktikum machine learning pertemuan IV: Boosting. Universitas Bengkulu.

Leisch, F., & Dimitriadou, E. (2010). mlbench: Machine learning benchmark problems [R package]. The Comprehensive R Archive Network.

Muraina, I. O. (2022). Ideal dataset splitting ratios in machine learning algorithms: General concerns for data scientists and data analysts. Dalam Proceedings of the 7th International Mardin Artuklu Scientific Research Conference (hlm. 496–504).

Schapire, R. E. (1990). The strength of weak learnability. Machine Learning, 5(2), 197–227. https://doi.org/10.1007/BF00116037

Sokolova, M., & Lapalme, G. (2009). A systematic analysis of performance measures for classification tasks. Information Processing & Management, 45(4), 427–437. https://doi.org/10.1016/j.ipm.2009.03.002

Sung, H., Ferlay, J., Siegel, R. L., Laversanne, M., Soerjomataram, I., Jemal, A., & Bray, F. (2021). Global cancer statistics 2020: GLOBOCAN estimates of incidence and mortality worldwide for 36 cancers in 185 countries. CA: A Cancer Journal for Clinicians, 71(3), 209–249. https://doi.org/10.3322/caac.21660

van Buuren, S. (2018). Flexible imputation of missing data (2nd ed.). CRC Press.

Wolberg, W. H., & Mangasarian, O. L. (1990). Multisurface method of pattern separation for medical diagnosis applied to breast cytology. Proceedings of the National Academy of Sciences, 87(23), 9193–9196. https://doi.org/10.1073/pnas.87.23.9193

Zhou, Z.-H. (2012). Ensemble methods: Foundations and algorithms. CRC Press.