BAB I PENDAHULUAN

1.1 Latar Belakang Masalah

Model prediktif yang baik harus mampu menggeneralisasi data baru, bukan sekadar cocok pada data yang digunakan untuk membangunnya. Salah satu masalah utama dalam pembelajaran mesin adalah variance yang tinggi, yaitu hasil model berubah cukup besar ketika data latih berubah sedikit saja. Model pohon keputusan (decision tree) merupakan contoh klasik model dengan variance tinggi: pohon yang dibangun dari dua sampel data yang sedikit berbeda dapat memiliki struktur yang sangat berbeda, sehingga prediksinya tidak stabil.

Bootstrap Aggregating atau Bagging diperkenalkan oleh Breiman (1996) untuk menurunkan variance tersebut. Idenya sederhana: dibangun banyak model dari sampel bootstrap (pengambilan sampel acak dengan pengembalian) data latih, kemudian prediksi semua model digabungkan. Untuk kasus regresi, prediksi akhir adalah rata-rata prediksi seluruh model. Karena rata-rata dari banyak prediksi yang tidak terlalu berkorelasi memiliki variance lebih kecil, prediksi gabungan umumnya lebih stabil dan akurat dibandingkan satu model tunggal.

Parameter penting pada bagging adalah jumlah bootstrap replicate atau jumlah model yang digabungkan (nbagg). Jumlah yang terlalu sedikit membuat penurunan variance belum optimal, sedangkan jumlah yang besar menambah waktu komputasi. Oleh karena itu perlu dikaji bagaimana performa bagging pada beberapa nilai nbagg.

Pada praktikum ini digunakan data Friedman, yaitu data simulasi yang banyak dipakai untuk menguji metode regresi nonlinear karena bentuk hubungan sebenarnya antara prediktor dan respons diketahui. Bagging regresi dengan pohon sebagai model dasar diterapkan menggunakan R dengan membandingkan nbagg = 25, 50, dan 100, kemudian performanya dievaluasi menggunakan beberapa metrik evaluasi.

1.2 Rumusan Masalah

  1. Bagaimana cara memahami konsep dasar dan prinsip kerja metode Bagging?
  2. Bagaimana cara mengimplementasikan metode bagging dengan menggunakan R?
  3. Bagaimana cara mengevaluasi performa Bagging?

1.3 Batasan Masalah

Praktikum ini dibatasi pada penggunaan data simulasi Friedman dengan metode bagging regresi berbasis pohon keputusan. Jumlah bootstrap replicate yang dibandingkan adalah nbagg = 25, 50, dan 100. Evaluasi dilakukan menggunakan data uji dengan metrik MSE, RMSE, MAE, dan \(R^2\), serta membandingkan estimasi galat OOB dari setiap model.

1.4 Tujuan

  1. Mahasiswa dapat memahami konsep dasar dan prinsip kerja metode bagging.
  2. Mahasiswa dapat mengimplementasikan metode bagging dengan menggunakan R.
  3. Mengevaluasi performa bagging.

BAB II TINJAUAN PUSTAKA

2.1 Bootstrap

Bootstrap adalah teknik pengambilan sampel acak dengan pengembalian dari data yang ada, dengan ukuran sampel sama dengan ukuran data asli (Efron & Tibshirani, 1993). Karena pengambilan dilakukan dengan pengembalian, sebagian observasi dapat muncul lebih dari sekali dan sebagian lain tidak terambil sama sekali. Peluang sebuah observasi tidak terambil dalam satu sampel bootstrap berukuran \(n\) adalah:

\[ \left(1 - \frac{1}{n}\right)^n \xrightarrow{n \to \infty} e^{-1} \approx 0{,}368 \]

Artinya, rata-rata sekitar 36,8% observasi tidak terpilih pada setiap sampel bootstrap. Observasi yang tidak terpilih ini disebut data out-of-bag (OOB) dan dapat dimanfaatkan sebagai data uji internal.

2.2 Bagging (Bootstrap Aggregating)

Bagging adalah metode ensemble yang membangun \(B\) model dasar (base learner) dari \(B\) sampel bootstrap yang berbeda, lalu menggabungkan prediksinya (Breiman, 1996). Prinsip kerjanya adalah sebagai berikut.

  1. Ambil \(B\) sampel bootstrap dari data latih.
  2. Bangun satu model dasar \(\hat{f}^{*b}(x)\) pada setiap sampel bootstrap ke-\(b\).
  3. Gabungkan prediksi seluruh model. Pada regresi, prediksi akhir adalah rata-rata:

\[ \hat{f}_{bag}(x) = \frac{1}{B} \sum_{b=1}^{B} \hat{f}^{*b}(x) \]

Pada klasifikasi, prediksi akhir ditentukan melalui suara terbanyak (majority vote) dari seluruh model.

Alasan bagging menurunkan variance: apabila \(B\) prediksi masing-masing memiliki variance \(\sigma^2\) dan korelasi antarpasangan \(\rho\), maka variance rata-ratanya adalah

\[ Var\left(\frac{1}{B}\sum_{b=1}^{B}\hat{f}^{*b}\right) = \rho\,\sigma^2 + \frac{1-\rho}{B}\,\sigma^2 \]

Suku kedua mengecil saat \(B\) membesar, sedangkan suku pertama tidak berubah. Dengan demikian, menambah jumlah model menurunkan variance hanya sampai batas tertentu, dan penurunannya makin kecil seiring bertambahnya \(B\) (Hastie et al., 2009). Bagging paling bermanfaat untuk model yang tidak stabil (variance tinggi, bias rendah) seperti pohon keputusan yang dibiarkan tumbuh dalam, dan tidak terlalu bermanfaat untuk model yang sudah stabil.

2.3 Pohon Regresi sebagai Model Dasar

Model dasar pada praktikum ini adalah pohon regresi (regression tree) dari metode CART (Breiman et al., 1984). Pohon regresi membagi ruang prediktor secara rekursif menjadi wilayah-wilayah \(R_1, \ldots, R_J\) dengan meminimalkan jumlah kuadrat galat (residual sum of squares, RSS), dan prediksi pada setiap wilayah adalah rata-rata respons di wilayah tersebut:

\[ RSS = \sum_{j=1}^{J} \sum_{i \in R_j} \left( y_i - \hat{y}_{R_j} \right)^2 \]

Pada R, bagging dengan pohon regresi tersedia melalui fungsi bagging() dari package ipred yang menggunakan rpart sebagai model dasar (Peters & Hothorn, 2023). Argumen nbagg menentukan jumlah bootstrap replicate dan coob = TRUE menghitung estimasi galat out-of-bag (OOB). Pada kasus regresi, galat OOB yang dilaporkan berupa RMSE.

2.4 Data Friedman

Data Friedman adalah data simulasi dari Friedman (1991) yang tersedia di package mlbench melalui fungsi mlbench.friedman1(). Prediktor \(x_1, \ldots, x_{10}\) masing-masing berdistribusi seragam \(U(0,1)\) dan independen, sedangkan respons dibangkitkan dari persamaan nonlinear berikut:

\[ y = 10 \sin(\pi x_1 x_2) + 20 (x_3 - 0{,}5)^2 + 10 x_4 + 5 x_5 + \varepsilon, \qquad \varepsilon \sim N(0, \sigma^2) \]

Hanya lima prediktor pertama (\(x_1\) sampai \(x_5\)) yang benar-benar memengaruhi \(y\), sedangkan \(x_6\) sampai \(x_{10}\) merupakan variabel noise yang tidak berhubungan dengan respons. Struktur yang diketahui ini membuat data Friedman cocok untuk menguji kemampuan model menangkap hubungan nonlinear sekaligus mengabaikan variabel yang tidak relevan.

2.5 Metrik Evaluasi Regresi

Misalkan \(y_i\) nilai aktual, \(\hat{y}_i\) nilai prediksi, dan \(n\) jumlah observasi pada data uji. Metrik yang digunakan adalah sebagai berikut.

\[ MSE = \frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2, \qquad RMSE = \sqrt{MSE}, \qquad MAE = \frac{1}{n}\sum_{i=1}^{n}|y_i - \hat{y}_i| \]

\[ R^2 = 1 - \frac{\sum_{i=1}^{n}(y_i - \hat{y}_i)^2}{\sum_{i=1}^{n}(y_i - \bar{y})^2} \]

MSE, RMSE, dan MAE menyatakan besarnya galat sehingga semakin kecil semakin baik. RMSE dan MAE memiliki satuan yang sama dengan respons sehingga lebih mudah diinterpretasi, dan RMSE lebih sensitif terhadap galat besar dibandingkan MAE. \(R^2\) menyatakan proporsi variasi respons yang dapat dijelaskan model, dan semakin mendekati 1 semakin baik.

BAB III METODE PENELITIAN

3.1 Sumber Data

Data yang digunakan adalah data Friedman hasil simulasi dengan fungsi mlbench.friedman1() dari package mlbench di R, dengan jumlah observasi \(n = 500\) dan simpangan baku galat \(\sigma = 1\). Pembangkitan data dilakukan dengan set.seed(123) agar hasil dapat direproduksi.

3.2 Variabel Penelitian

Variabel Peran Keterangan
X1 sampai X5 X Prediktor yang memengaruhi respons, berdistribusi \(U(0,1)\)
X6 sampai X10 X Prediktor noise yang tidak memengaruhi respons, berdistribusi \(U(0,1)\)
Y Y Respons numerik, dibangkitkan dari persamaan Friedman #1 ditambah galat \(N(0,1)\)

3.3 Langkah-langkah Analisis

  1. Membangkitkan data Friedman, memeriksa strukturnya, dan menyajikan statistik deskriptif.
  2. Memeriksa keberadaan missing value.
  3. Membagi data menjadi data latih (70%) dan data uji (30%) secara acak.
  4. Membangun model pohon regresi tunggal sebagai pembanding (baseline).
  5. Membangun model bagging regresi dengan nbagg = 25, 50, dan 100 pada data latih.
  6. Memprediksi data uji dan menghitung metrik evaluasi (MSE, RMSE, MAE, dan \(R^2\)), serta galat OOB.
  7. Membandingkan performa ketiga model bagging dan model pohon tunggal, kemudian menarik kesimpulan.

BAB IV HASIL DAN PEMBAHASAN

4.1 Library

library(mlbench)
library(ipred)
library(rpart)
library(dplyr)
library(tidyr)
library(ggplot2)
library(knitr)

4.2 Data Friedman

set.seed(123)
fr <- mlbench.friedman1(n = 500, sd = 1)

df <- data.frame(fr$x, Y = fr$y)
colnames(df) <- c(paste0("X", 1:10), "Y")

dim(df)
## [1] 500  11
head(df)
##          X1         X2        X3        X4        X5        X6        X7
## 1 0.2875775 0.35360608 0.2736227 0.9380283 0.1596740 0.8535317 0.2058269
## 2 0.7883051 0.36644144 0.5938669 0.9880033 0.1445159 0.6660066 0.9425390
## 3 0.4089769 0.28710013 0.1601848 0.4563196 0.1491804 0.7333267 0.3793238
## 4 0.8830174 0.07997291 0.8534302 0.2306149 0.5144343 0.3147403 0.6262401
## 5 0.9404673 0.36545427 0.8477392 0.6954893 0.4928273 0.6677179 0.1835024
## 6 0.0455565 0.17801381 0.4778868 0.5566323 0.6163428 0.4638867 0.6592076
##          X8        X9        X10         Y
## 1 0.2414939 0.3044642 0.10504174 13.665374
## 2 0.4107782 0.8328188 0.40250560 19.232842
## 3 0.8111750 0.5936475 0.45567659 10.519756
## 4 0.3791412 0.8071966 0.62464525  9.042955
## 5 0.4469502 0.2940508 0.07885528 21.430304
## 6 0.5705078 0.1410852 0.34198272  8.436942
str(df)
## 'data.frame':    500 obs. of  11 variables:
##  $ X1 : num  0.288 0.788 0.409 0.883 0.94 ...
##  $ X2 : num  0.354 0.366 0.287 0.08 0.365 ...
##  $ X3 : num  0.274 0.594 0.16 0.853 0.848 ...
##  $ X4 : num  0.938 0.988 0.456 0.231 0.695 ...
##  $ X5 : num  0.16 0.145 0.149 0.514 0.493 ...
##  $ X6 : num  0.854 0.666 0.733 0.315 0.668 ...
##  $ X7 : num  0.206 0.943 0.379 0.626 0.184 ...
##  $ X8 : num  0.241 0.411 0.811 0.379 0.447 ...
##  $ X9 : num  0.304 0.833 0.594 0.807 0.294 ...
##  $ X10: num  0.105 0.4025 0.4557 0.6246 0.0789 ...
##  $ Y  : num  13.67 19.23 10.52 9.04 21.43 ...
summary(df)
##        X1                  X2                 X3                 X4          
##  Min.   :0.0004654   Min.   :0.001192   Min.   :0.001156   Min.   :0.004609  
##  1st Qu.:0.2459967   1st Qu.:0.259956   1st Qu.:0.244262   1st Qu.:0.257612  
##  Median :0.4765563   Median :0.512548   Median :0.497739   Median :0.498742  
##  Mean   :0.4952837   Mean   :0.499272   Mean   :0.493893   Mean   :0.502620  
##  3rd Qu.:0.7328975   3rd Qu.:0.755200   3rd Qu.:0.736291   3rd Qu.:0.752761  
##  Max.   :0.9994045   Max.   :0.994936   Max.   :0.999524   Max.   :0.996372  
##        X5                 X6                 X7                 X8           
##  Min.   :0.003535   Min.   :0.003516   Min.   :0.001152   Min.   :6.534e-05  
##  1st Qu.:0.224011   1st Qu.:0.251830   1st Qu.:0.250753   1st Qu.:2.305e-01  
##  Median :0.478116   Median :0.505159   Median :0.504392   Median :5.084e-01  
##  Mean   :0.490842   Mean   :0.506365   Mean   :0.500691   Mean   :5.073e-01  
##  3rd Qu.:0.737981   3rd Qu.:0.758920   3rd Qu.:0.754159   3rd Qu.:7.764e-01  
##  Max.   :0.999274   Max.   :0.999651   Max.   :0.999500   Max.   :9.976e-01  
##        X9                X10                 Y         
##  Min.   :0.000829   Min.   :0.001713   Min.   : 2.717  
##  1st Qu.:0.262310   1st Qu.:0.239892   1st Qu.:10.857  
##  Median :0.493432   Median :0.484538   Median :14.313  
##  Mean   :0.490993   Mean   :0.487265   Mean   :14.340  
##  3rd Qu.:0.723352   3rd Qu.:0.736136   3rd Qu.:17.738  
##  Max.   :0.999941   Max.   :0.998745   Max.   :27.775
# Cek missing value
colSums(is.na(df))
##  X1  X2  X3  X4  X5  X6  X7  X8  X9 X10   Y 
##   0   0   0   0   0   0   0   0   0   0   0
cat("Total missing value :", sum(is.na(df)), "\n")
## Total missing value : 0

Data terdiri atas 500 observasi dan 11 variabel (10 prediktor dan 1 respons). Statistik deskriptif menunjukkan setiap prediktor berkisar antara 0 sampai 1 sesuai distribusi seragam yang dibangkitkan, sedangkan respons Y memiliki rata-rata 14.34 dan rentang 2.72 sampai 27.78. Karena data dibangkitkan melalui simulasi, jumlah missing value adalah 0 sehingga tidak diperlukan penanganan missing value. Seluruh prediktor sudah berada pada skala yang sama (0 sampai 1) dan model berbasis pohon tidak sensitif terhadap skala, sehingga tahap scaling dan encoding juga tidak diperlukan. Berdasarkan mekanisme pembangkitan data Friedman, X1 sampai X5 merupakan prediktor yang berkontribusi terhadap Y, sedangkan X6 sampai X10 sengaja disertakan sebagai variabel noise. Dengan demikian, keberadaan sepuluh prediktor tidak berarti semuanya memiliki hubungan dengan respons.

ggplot(df, aes(x = Y)) +
  geom_histogram(bins = 30, fill = "#008080", color = "black") +
  labs(x = "Y", y = "Frekuensi", title = "Distribusi Respons Y") +
  theme_minimal()
Gambar 1. Distribusi respons Y

Gambar 1. Distribusi respons Y

Histogram pada Gambar 1 digunakan untuk melihat bentuk sebaran respons Y, rentang nilai, dan bagian rentang yang memiliki frekuensi relatif tinggi. Bentuk sebaran perlu disimpulkan berdasarkan histogram yang muncul setelah dokumen dijalankan. Grafik ini tidak dengan sendirinya menjadi uji normalitas; Y dibangkitkan dari kombinasi fungsi nonlinear dan galat acak, sehingga sebarannya ditentukan oleh gabungan komponen tersebut.

4.3 Splitting Data

set.seed(123)
idx   <- sample(seq_len(nrow(df)), size = round(0.7 * nrow(df)))
train <- df[idx, ]
test  <- df[-idx, ]

cat("Jumlah data latih :", nrow(train), "\n")
## Jumlah data latih : 350
cat("Jumlah data uji   :", nrow(test), "\n")
## Jumlah data uji   : 150

Data dibagi menjadi data latih (70%, 350 observasi) dan data uji (30%, 150 observasi) secara acak. Data latih digunakan untuk membangun model, sedangkan data uji digunakan untuk menilai kemampuan model memprediksi data baru.

4.4 Fungsi Evaluasi dan Model Pembanding

evaluasi <- function(aktual, prediksi) {
  mse <- mean((aktual - prediksi)^2)
  c(
    MSE  = mse,
    RMSE = sqrt(mse),
    MAE  = mean(abs(aktual - prediksi)),
    R2   = 1 - sum((aktual - prediksi)^2) / sum((aktual - mean(aktual))^2)
  )
}

Sebagai pembanding, dibangun satu pohon regresi tunggal dengan rpart. Hasil ini menunjukkan seberapa besar perbaikan yang diberikan bagging dibandingkan satu pohon.

tree_single <- rpart(Y ~ ., data = train, method = "anova")

pred_tree <- predict(tree_single, newdata = test)
ev_tree   <- evaluasi(test$Y, pred_tree)
ev_tree
##      MSE     RMSE      MAE       R2 
## 9.969993 3.157530 2.476308 0.582609

4.5 Bagging Regression dengan nbagg = 25, 50, dan 100

nbagg_set <- c(25, 50, 100)

model_bag <- list()
pred_bag  <- list()
hasil_uji <- data.frame()

for (B in nbagg_set) {
  set.seed(123)
  m <- bagging(Y ~ ., data = train, nbagg = B, coob = TRUE)

  p <- predict(m, newdata = test)
  e <- evaluasi(test$Y, p)

  model_bag[[as.character(B)]] <- m
  pred_bag[[as.character(B)]]  <- p

  hasil_uji <- rbind(
    hasil_uji,
    data.frame(Model = paste0("Bagging (nbagg = ", B, ")"),
               nbagg = B,
               OOB_RMSE = m$err,
               MSE = e["MSE"], RMSE = e["RMSE"], MAE = e["MAE"], R2 = e["R2"])
  )
}

model_bag[["25"]]
## 
## Bagging regression trees with 25 bootstrap replications 
## 
## Call: bagging.data.frame(formula = Y ~ ., data = train, nbagg = B, 
##     coob = TRUE)
## 
## Out-of-bag estimate of root mean squared error:  2.6578
model_bag[["50"]]
## 
## Bagging regression trees with 50 bootstrap replications 
## 
## Call: bagging.data.frame(formula = Y ~ ., data = train, nbagg = B, 
##     coob = TRUE)
## 
## Out-of-bag estimate of root mean squared error:  2.5959
model_bag[["100"]]
## 
## Bagging regression trees with 100 bootstrap replications 
## 
## Call: bagging.data.frame(formula = Y ~ ., data = train, nbagg = B, 
##     coob = TRUE)
## 
## Out-of-bag estimate of root mean squared error:  2.5797

Pada setiap nilai nbagg, fungsi bagging() membangun sebanyak nbagg pohon regresi, masing-masing dari satu sampel bootstrap data latih, dan prediksinya dirata-ratakan. Argumen coob = TRUE menghasilkan estimasi galat out-of-bag (OOB RMSE) yang dihitung dari observasi yang tidak ikut terambil pada pembentukan setiap pohon. Pada setiap iterasi digunakan set.seed(123) agar hasil dapat direproduksi dan perbedaan antarmodel tidak berasal dari perbedaan seed.

4.6 Evaluasi Performa Model

hasil_semua <- rbind(
  data.frame(Model = "Pohon tunggal (rpart)", nbagg = NA, OOB_RMSE = NA,
             MSE = ev_tree["MSE"], RMSE = ev_tree["RMSE"],
             MAE = ev_tree["MAE"], R2 = ev_tree["R2"]),
  hasil_uji
)
rownames(hasil_semua) <- NULL

kable(hasil_semua[, c("Model", "OOB_RMSE", "MSE", "RMSE", "MAE", "R2")],
      digits = 4,
      caption = "Tabel 1. Metrik evaluasi pada data uji")
Tabel 1. Metrik evaluasi pada data uji
Model OOB_RMSE MSE RMSE MAE R2
Pohon tunggal (rpart) NA 9.9700 3.1575 2.4763 0.5826
Bagging (nbagg = 25) 2.6578 7.5918 2.7553 2.2025 0.6822
Bagging (nbagg = 50) 2.5959 7.1647 2.6767 2.1588 0.7001
Bagging (nbagg = 100) 2.5797 7.1910 2.6816 2.1604 0.6989

MSE, RMSE, dan MAE mengukur besar kesalahan prediksi, sehingga nilai yang lebih kecil menunjukkan prediksi yang lebih dekat dengan nilai aktual. MSE memberi penalti lebih besar pada kesalahan yang besar karena galat dikuadratkan, sedangkan MAE merangkum rata-rata nilai absolut galat. RMSE berada pada satuan yang sama dengan Y. Sementara itu, nilai R² yang lebih tinggi umumnya menunjukkan kecocokan prediksi yang lebih baik; R² dapat bernilai negatif apabila prediksi lebih buruk daripada menggunakan rata-rata Y pada data uji sebagai prediksi.

hasil_long <- hasil_semua %>%
  select(Model, MSE, RMSE, MAE, R2) %>%
  pivot_longer(-Model, names_to = "Metrik", values_to = "Nilai") %>%
  mutate(Metrik = factor(Metrik, levels = c("MSE", "RMSE", "MAE", "R2")),
         Model  = factor(Model, levels = hasil_semua$Model))

ggplot(hasil_long, aes(x = Model, y = Nilai, fill = Model)) +
  geom_col(color = "black", show.legend = FALSE) +
  geom_text(aes(label = round(Nilai, 3)), vjust = -0.3, size = 3) +
  facet_wrap(~ Metrik, scales = "free_y") +
  labs(x = NULL, y = "Nilai", title = "Perbandingan Metrik Evaluasi (Data Uji)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 25, hjust = 1))
Gambar 2. Perbandingan metrik evaluasi pada data uji

Gambar 2. Perbandingan metrik evaluasi pada data uji

df_pred <- rbind(
  data.frame(Model = "Pohon tunggal (rpart)", Aktual = test$Y, Prediksi = pred_tree),
  data.frame(Model = "Bagging (nbagg = 25)",  Aktual = test$Y, Prediksi = pred_bag[["25"]]),
  data.frame(Model = "Bagging (nbagg = 50)",  Aktual = test$Y, Prediksi = pred_bag[["50"]]),
  data.frame(Model = "Bagging (nbagg = 100)", Aktual = test$Y, Prediksi = pred_bag[["100"]])
)
df_pred$Model <- factor(df_pred$Model, levels = unique(df_pred$Model))

ggplot(df_pred, aes(x = Aktual, y = Prediksi)) +
  geom_point(color = "#008080", alpha = 0.7) +
  geom_abline(slope = 1, intercept = 0, linetype = "dashed") +
  facet_wrap(~ Model) +
  labs(x = "Y aktual", y = "Y prediksi", title = "Aktual vs Prediksi (Data Uji)") +
  theme_minimal()
Gambar 3. Nilai aktual vs prediksi pada data uji

Gambar 3. Nilai aktual vs prediksi pada data uji

idx_best   <- which.min(hasil_uji$RMSE)
best_model <- hasil_uji[idx_best, ]
selisih_rmse <- (ev_tree["RMSE"] - best_model$RMSE) / ev_tree["RMSE"] * 100

Tabel 1 merangkum metrik evaluasi pada data uji. Di antara ketiga model bagging, model dengan RMSE data uji terkecil adalah Bagging (nbagg = 50) dengan MSE 7.1647, RMSE 2.6767, MAE 2.1588, dan \(R^2\) 0.7001. Dibandingkan pohon tunggal (RMSE 3.1575, \(R^2\) 0.5826), model bagging terbaik menurunkan RMSE sebesar 15.23%, sehingga penggabungan banyak pohon memberikan prediksi yang lebih akurat daripada satu pohon.

Pada Gambar 2, bandingkan metrik secara terpisah karena setiap panel menggunakan skala sumbu-y tersendiri. Model yang memiliki MSE, RMSE, dan MAE lebih rendah serta R² lebih tinggi menunjukkan kinerja yang relatif lebih baik pada data uji. Penentuan model terbaik di bagian ini didasarkan pada RMSE terkecil di antara model bagging, tetapi nilai metrik lainnya tetap diperiksa agar kesimpulan tidak bergantung pada satu ukuran saja.

Pada Gambar 3, semakin dekat titik-titik prediksi ke garis putus-putus (garis 45 derajat), semakin dekat prediksi dengan nilai aktual. Titik yang berada di atas garis menunjukkan prediksi lebih tinggi daripada nilai aktual, sedangkan titik di bawah garis menunjukkan prediksi lebih rendah. Pola baris horizontal dapat muncul pada pohon tunggal karena pohon regresi memberikan nilai prediksi konstan pada setiap simpul daun. Prediksi bagging cenderung lebih beragam karena merupakan rata-rata prediksi dari banyak pohon. Pola-pola tersebut perlu dinilai berdasarkan grafik yang dihasilkan, bukan diasumsikan selalu menunjukkan model tertentu lebih baik.

4.7 Pengaruh Jumlah Bootstrap Replicate (nbagg)

plot_nbagg <- hasil_uji %>%
  select(nbagg, `RMSE data uji` = RMSE, `RMSE OOB` = OOB_RMSE) %>%
  pivot_longer(-nbagg, names_to = "Jenis", values_to = "RMSE")

ggplot(plot_nbagg, aes(x = factor(nbagg), y = RMSE, group = Jenis, color = Jenis)) +
  geom_line(linewidth = 1) +
  geom_point(size = 3) +
  geom_hline(yintercept = ev_tree["RMSE"], linetype = "dashed", color = "grey40") +
  annotate("text", x = 1, y = ev_tree["RMSE"], label = "RMSE pohon tunggal",
           vjust = -0.6, hjust = 0, size = 3.2) +
  labs(x = "nbagg", y = "RMSE", title = "RMSE terhadap Jumlah Bootstrap Replicate") +
  theme_minimal()
Gambar 4. RMSE data uji dan OOB terhadap nbagg

Gambar 4. RMSE data uji dan OOB terhadap nbagg

rmse_25  <- hasil_uji$RMSE[hasil_uji$nbagg == 25]
rmse_50  <- hasil_uji$RMSE[hasil_uji$nbagg == 50]
rmse_100 <- hasil_uji$RMSE[hasil_uji$nbagg == 100]

RMSE data uji untuk nbagg = 25, 50, dan 100 berturut-turut adalah 2.7553, 2.6767, dan 2.6816. Secara teori (Bab II), penambahan jumlah pohon membuat rata-rata prediksi lebih stabil, tetapi perbaikan tambahan cenderung mengecil ketika jumlah pohon semakin besar. Karena itu, RMSE tidak harus turun secara ketat pada setiap kenaikan nbagg; hasil juga dipengaruhi proses bootstrap dan pembagian data.

Rentang RMSE data uji antar ketiga nilai nbagg kurang dari 5% dari rata-ratanya. Pada pembagian data ini, perbedaan kinerja ketiganya relatif kecil, sehingga penggunaan nbagg lebih kecil dapat dipertimbangkan jika efisiensi komputasi menjadi prioritas.

Nilai OOB RMSE untuk nbagg = 25, 50, dan 100 berturut-turut adalah 2.6578, 2.5959, 2.5797, sedangkan RMSE data uji adalah 2.7553, 2.6767, 2.6816. OOB RMSE dan RMSE data uji berasal dari mekanisme evaluasi yang berbeda, sehingga nilainya tidak harus sama. Jika keduanya relatif berdekatan, estimasi OOB pada hasil ini memberi gambaran yang sejalan dengan performa data uji; jika berbeda cukup jauh, perbedaan tersebut perlu disebutkan dan tidak sebaiknya menyatakan OOB selalu mewakili kinerja data uji. Data uji tetap dipertahankan sebagai evaluasi eksternal model.

BAB V KESIMPULAN

5.1 Kesimpulan

Bagging (Bootstrap Aggregating) adalah metode ensemble yang membangun banyak model dasar dari sampel bootstrap data latih, lalu menggabungkan prediksinya, yaitu dengan rata-rata pada regresi dan suara terbanyak pada klasifikasi. Prinsip ini menurunkan variance sehingga prediksi lebih stabil, terutama untuk model tidak stabil seperti pohon keputusan. Bagging regresi berhasil diimplementasikan pada data Friedman (\(n\) = 500, 350 data latih dan 150 data uji) di R menggunakan fungsi bagging() dari package ipred dengan nbagg = 25, 50, dan 100. Berdasarkan evaluasi pada data uji, model bagging dengan RMSE terkecil adalah Bagging (nbagg = 50) dengan RMSE 2.6767, MAE 2.1588, dan \(R^2\) 0.7001, sedangkan pohon tunggal memiliki RMSE 3.1575 dan \(R^2\) 0.5826. Perbandingan ini menunjukkan kinerja pada satu pembagian data; hasilnya tidak serta-merta menjamin model yang sama selalu terbaik pada pembagian data lain. Besar perbedaan kinerja antar nilai nbagg perlu ditentukan dari hasil RMSE yang diperoleh, bukan diasumsikan selalu kecil.

DAFTAR PUSTAKA

Breiman, L. (1996). Bagging predictors. Machine Learning, 24(2), 123–140.

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

Efron, B., & Tibshirani, R. J. (1993). An Introduction to the Bootstrap. Chapman & Hall.

Friedman, J. H. (1991). Multivariate adaptive regression splines. The Annals of Statistics, 19(1), 1–67.

Hastie, T., Tibshirani, R., & Friedman, J. (2009). The Elements of Statistical Learning: Data Mining, Inference, and Prediction (2nd ed.). Springer.

Peters, A., & Hothorn, T. (2023). ipred: Improved Predictors (R package). https://CRAN.R-project.org/package=ipred