BAB I PENDAHULUAN

1.1 Latar Belakang

Gradient Boosting merupakan metode ensemble learning yang membangun model secara bertahap. Setiap model baru berusaha memperbaiki kesalahan prediksi model sebelumnya. Pada kasus regresi, metode ini dapat digunakan untuk mempelajari hubungan antara variabel prediktor dan variabel respons yang bersifat numerik.

Salah satu parameter penting pada Gradient Boosting adalah learning rate atau shrinkage. Parameter ini mengatur besarnya kontribusi setiap pohon terhadap model akhir. Nilai learning rate yang berbeda dapat menghasilkan kinerja prediksi yang berbeda pula. Oleh karena itu, praktikum ini membandingkan nilai shrinkage sebesar 0,01, 0,05, dan 0,10 pada data Friedman. Jumlah iterasi optimal ditentukan menggunakan cross-validation, sedangkan kinerja model dievaluasi dengan MSE, RMSE, MAE, dan R².

1.2 Rumusan Masalah

  1. Bagaimana menerapkan Gradient Boosting Regression pada data Friedman menggunakan fungsi gbm()?
  2. Bagaimana menentukan jumlah iterasi optimal menggunakan cross-validation untuk setiap nilai shrinkage?
  3. Bagaimana perbandingan kinerja model berdasarkan MSE, RMSE, MAE, dan R²?
  4. Nilai shrinkage mana yang menghasilkan kinerja terbaik pada data uji?

1.3 Tujuan

  1. Menerapkan Gradient Boosting Regression pada data Friedman.
  2. Membandingkan nilai shrinkage sebesar 0,01, 0,05, dan 0,10.
  3. Menentukan jumlah iterasi optimal berdasarkan cross-validation.
  4. Mengevaluasi dan membandingkan model menggunakan MSE, RMSE, MAE, dan R².
  5. Menentukan model terbaik berdasarkan hasil evaluasi data uji.

1.4 Manfaat

Praktikum ini diharapkan membantu memahami penerapan Gradient Boosting Regression, fungsi cross-validation dalam memilih jumlah iterasi, serta penggunaan metrik evaluasi untuk membandingkan model regresi.

1.5 Batasan Masalah

  1. Data yang digunakan adalah data simulasi Friedman dari fungsi mlbench.friedman1() pada paket mlbench.
  2. Variabel respons adalah y, sedangkan variabel prediktor adalah x1 sampai x10.
  3. Data dibagi menjadi 70% data latih dan 30% data uji.
  4. Model dibangun menggunakan fungsi gbm() dengan distribusi Gaussian.
  5. Nilai shrinkage yang dibandingkan adalah 0,01, 0,05, dan 0,10.
  6. Jumlah iterasi optimal ditentukan menggunakan cross-validation dengan 5 lipatan.
  7. Evaluasi model pada data uji menggunakan MSE, RMSE, MAE, dan R².

1.6 Sistematika Penulisan

Laporan ini terdiri dari pendahuluan, tinjauan pustaka, metode penelitian, hasil dan pembahasan, kesimpulan dan saran, daftar pustaka, serta lampiran kode program.

BAB II TINJAUAN PUSTAKA

2.1 Regresi

Regresi merupakan metode statistik untuk mempelajari hubungan antara variabel respons dan satu atau lebih variabel prediktor. Pada regresi, variabel respons umumnya berupa data numerik. Model yang terbentuk digunakan untuk memperkirakan nilai respons berdasarkan informasi dari variabel prediktor.

2.2 Gradient Boosting

Gradient Boosting adalah metode ensemble yang membangun model secara berurutan. Model berikutnya berusaha mengurangi kesalahan yang belum dapat dijelaskan oleh model sebelumnya. Pada regresi, model ini menggabungkan banyak pohon regresi menjadi satu model prediksi.

2.3 Learning Rate (Shrinkage)

Parameter shrinkage mengatur kontribusi setiap pohon baru dalam proses pembentukan model. Nilai yang lebih kecil membuat pembaruan model berlangsung lebih bertahap dan biasanya membutuhkan lebih banyak iterasi. Nilai yang lebih besar memperbarui model lebih cepat, tetapi tidak selalu menghasilkan prediksi yang lebih baik. Karena itu, nilai shrinkage perlu dibandingkan menggunakan prosedur evaluasi yang konsisten.

2.4 Cross-Validation dan Jumlah Iterasi Optimal

Cross-validation membagi data latih menjadi beberapa bagian. Model dilatih pada sebagian bagian dan dievaluasi pada bagian yang tidak digunakan untuk pelatihan. Proses tersebut diulang sehingga setiap bagian memperoleh giliran sebagai data validasi. Pada praktikum ini digunakan 5-fold cross-validation. Jumlah iterasi optimal dipilih dari hasil validasi silang menggunakan fungsi gbm.perf() dengan metode cv.

2.5 Metrik Evaluasi Regresi

Metrik yang digunakan untuk membandingkan prediksi pada data uji adalah:

  • MSE (Mean Squared Error): rata-rata kuadrat selisih nilai aktual dan prediksi. Nilai yang lebih kecil menunjukkan kesalahan kuadrat yang lebih rendah.
  • RMSE (Root Mean Squared Error): akar kuadrat MSE dan memiliki satuan yang sama dengan respons.
  • MAE (Mean Absolute Error): rata-rata nilai absolut selisih nilai aktual dan prediksi. Nilai yang lebih kecil menunjukkan kesalahan absolut yang lebih rendah.
  • R² (Koefisien Determinasi): mengukur proporsi variasi respons yang dapat dijelaskan oleh prediksi model relatif terhadap rata-rata respons. Nilai yang lebih besar umumnya menunjukkan hasil yang lebih baik; R² pada data uji dapat bernilai negatif apabila model lebih buruk daripada prediksi menggunakan rata-rata aktual.

Rumus metrik yang digunakan:

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

\[ RMSE = \sqrt{MSE} \]

\[ 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} \]

BAB III METODE PENELITIAN

3.1 Jenis dan Sumber Data

Data yang digunakan adalah data simulasi Friedman yang dibuat menggunakan fungsi mlbench.friedman1() dari paket mlbench. Data terdiri dari satu variabel respons numerik (y) dan sepuluh variabel prediktor (x1 sampai x10). Data simulasi ini digunakan untuk mempelajari kinerja model regresi pada hubungan yang tidak sepenuhnya linear.

3.2 Variabel Penelitian

var_tab <- data.frame(
  Variabel = c("y", paste0("x", 1:10)),
  Peran = c("Respons", rep("Prediktor", 10)),
  Keterangan = c(
    "Nilai respons numerik yang diprediksi model",
    rep("Variabel prediktor pada data Friedman", 10)
  )
)
knitr::kable(var_tab, caption = "Tabel 3.1 Variabel penelitian")
Tabel 3.1 Variabel penelitian
Variabel Peran Keterangan
y Respons Nilai respons numerik yang diprediksi model
x1 Prediktor Variabel prediktor pada data Friedman
x2 Prediktor Variabel prediktor pada data Friedman
x3 Prediktor Variabel prediktor pada data Friedman
x4 Prediktor Variabel prediktor pada data Friedman
x5 Prediktor Variabel prediktor pada data Friedman
x6 Prediktor Variabel prediktor pada data Friedman
x7 Prediktor Variabel prediktor pada data Friedman
x8 Prediktor Variabel prediktor pada data Friedman
x9 Prediktor Variabel prediktor pada data Friedman
x10 Prediktor Variabel prediktor pada data Friedman

3.3 Tahapan Analisis

Tahapan analisis meliputi pembuatan data Friedman, pemeriksaan data, pembagian data menjadi data latih dan data uji, pembangunan model Gradient Boosting dengan tiga nilai shrinkage, penentuan jumlah iterasi optimal menggunakan 5-fold cross-validation, prediksi pada data uji, perhitungan metrik evaluasi, serta perbandingan hasil model.

3.4 Diagram Alir Penelitian

Gambar 3.1. Diagram alir penerapan Gradient Boosting Regression.

BAB IV HASIL DAN PEMBAHASAN

4.1 Pembuatan dan Pembagian Data

# Membuat data simulasi Friedman dengan 1000 pengamatan dan 10 prediktor
set.seed(234)
data_friedman <- mlbench::mlbench.friedman1(
   n = 1000,
  sd = 1
)
data_friedman <- as.data.frame(data_friedman)
names(data_friedman) <- c(paste0("x", 1:10), "y")

# Memeriksa struktur dan ringkasan data
cat("Jumlah pengamatan:", nrow(data_friedman), "\n")
## Jumlah pengamatan: 1000
cat("Jumlah variabel:", ncol(data_friedman), "\n")
## Jumlah variabel: 11
cat("Jumlah data hilang:", sum(is.na(data_friedman)), "\n")
## Jumlah data hilang: 0
ringkasan_data <- data.frame(
  Keterangan = c("Jumlah pengamatan", "Jumlah prediktor", "Jumlah respons", "Data hilang"),
  Jumlah = c(nrow(data_friedman), 10, 1, sum(is.na(data_friedman)))
)
knitr::kable(ringkasan_data, caption = "Tabel 4.1 Ringkasan data Friedman")
Tabel 4.1 Ringkasan data Friedman
Keterangan Jumlah
Jumlah pengamatan 1000
Jumlah prediktor 10
Jumlah respons 1
Data hilang 0
# Membagi data secara acak menjadi 70% data latih dan 30% data uji
set.seed(234)
indeks_train <- sample(
  seq_len(nrow(data_friedman)),
  size = floor(0.70 * nrow(data_friedman))
)
data_train <- data_friedman[indeks_train, , drop = FALSE]
data_test <- data_friedman[-indeks_train, , drop = FALSE]

pembagian <- data.frame(
  Jenis = c("Data latih", "Data uji", "Total"),
  Jumlah = c(nrow(data_train), nrow(data_test), nrow(data_friedman)),
  Persentase = round(
    100 * c(nrow(data_train), nrow(data_test), nrow(data_friedman)) /
      nrow(data_friedman), 2
  )
)
knitr::kable(pembagian, caption = "Tabel 4.2 Pembagian data")
Tabel 4.2 Pembagian data
Jenis Jumlah Persentase
Data latih 700 70
Data uji 300 30
Total 1000 100

Data Friedman dibuat dengan 1.000 pengamatan dan sepuluh variabel prediktor. Data kemudian dibagi menjadi 70% data latih dan 30% data uji. Data latih digunakan untuk membangun model dan menentukan jumlah iterasi optimal melalui cross-validation, sedangkan data uji digunakan untuk mengevaluasi kemampuan prediksi model pada data yang tidak digunakan saat pelatihan.

4.2 Pemodelan Gradient Boosting dan Cross-Validation

# Nilai learning rate yang akan dibandingkan
nilai_shrinkage <- c(0.01, 0.05, 0.10)

# Menentukan jumlah maksimum iterasi dan jumlah fold cross-validation
jumlah_iterasi_maks <- 3000
jumlah_fold <- 5

model_list <- list()
prediksi_list <- list()
hasil_model <- list()
iterasi_optimal <- numeric(length(nilai_shrinkage))

for (i in seq_along(nilai_shrinkage)) {
  lr <- nilai_shrinkage[i]
  nama_model <- paste0("Shrinkage_", format(lr, nsmall = 2))

  # Membuat model dengan 5-fold cross-validation
  set.seed(234)
  model <- gbm::gbm(
    formula = y ~ .,
    data = data_train,
    distribution = "gaussian",
    n.trees = jumlah_iterasi_maks,
    interaction.depth = 3,
    shrinkage = lr,
    n.minobsinnode = 10,
    cv.folds = jumlah_fold,
    bag.fraction = 0.5,
    train.fraction = 1.0,
    verbose = FALSE
  )

  # Menentukan jumlah pohon optimal berdasarkan hasil cross-validation
  best_iter <- gbm::gbm.perf(
    model,
    method = "cv",
    plot.it = FALSE
  )
  if (length(best_iter) == 0 || is.na(best_iter) || best_iter < 1) {
    best_iter <- which.min(model$cv.error)
  }
  best_iter <- as.integer(best_iter)
  iterasi_optimal[i] <- best_iter

  # Prediksi pada data uji menggunakan jumlah iterasi optimal
  prediksi <- predict(
    model,
    newdata = data_test,
    n.trees = best_iter,
    type = "response"
  )

  # Menghitung metrik evaluasi
  aktual <- data_test$y
  mse <- mean((aktual - prediksi)^2)
  rmse <- sqrt(mse)
  mae <- mean(abs(aktual - prediksi))
  r2 <- 1 - sum((aktual - prediksi)^2) /
    sum((aktual - mean(aktual))^2)

  model_list[[nama_model]] <- model
  prediksi_list[[nama_model]] <- prediksi
  hasil_model[[i]] <- data.frame(
    Model = nama_model,
    Shrinkage = lr,
    Iterasi_Optimal = best_iter,
    CV_Error_Minimum = min(model$cv.error, na.rm = TRUE),
    MSE = mse,
    RMSE = rmse,
    MAE = mae,
    R2 = r2
  )
}

tabel_metrik <- do.call(rbind, hasil_model)
rownames(tabel_metrik) <- NULL

tabel_tampil <- tabel_metrik
kolom_bulat <- c("CV_Error_Minimum", "MSE", "RMSE", "MAE", "R2")
tabel_tampil[kolom_bulat] <- lapply(tabel_tampil[kolom_bulat], round, digits = 4)

knitr::kable(
  tabel_tampil,
  caption = "Tabel 4.3 Perbandingan kinerja Gradient Boosting pada data uji"
)
Tabel 4.3 Perbandingan kinerja Gradient Boosting pada data uji
Model Shrinkage Iterasi_Optimal CV_Error_Minimum MSE RMSE MAE R2
Shrinkage_0.01 0.01 3000 1.9450 1.9466 1.3952 1.0919 0.9273
Shrinkage_0.05 0.05 991 1.9584 1.8777 1.3703 1.0683 0.9299
Shrinkage_0.10 0.10 418 2.0980 1.9527 1.3974 1.0744 0.9271

Fungsi gbm() membangun model untuk setiap nilai shrinkage. Parameter cv.folds = 5 mengaktifkan validasi silang lima lipatan. Jumlah iterasi optimal dipilih dari hasil cross-validation melalui gbm.perf(). Seluruh model menggunakan pembagian data dan pengaturan dasar yang sama agar perbandingan lebih adil. Nilai metrik pada Tabel 4.3 dihitung dari prediksi terhadap data uji.

4.3 Grafik Perbandingan Metrik

# Mengubah tabel menjadi format panjang untuk visualisasi
data_plot <- rbind(
  data.frame(Model = tabel_metrik$Model, Metrik = "MSE", Nilai = tabel_metrik$MSE),
  data.frame(Model = tabel_metrik$Model, Metrik = "RMSE", Nilai = tabel_metrik$RMSE),
  data.frame(Model = tabel_metrik$Model, Metrik = "MAE", Nilai = tabel_metrik$MAE)
)

ggplot(data_plot, aes(x = Model, y = Nilai, fill = Metrik)) +
  geom_col(position = position_dodge(width = 0.8), width = 0.7) +
  scale_fill_brewer(palette = "Set2") +
  labs(
    title = "Perbandingan MSE, RMSE, dan MAE",
    x = "Model",
    y = "Nilai kesalahan",
    fill = "Metrik"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    legend.position = "bottom"
  )

Grafik membandingkan nilai kesalahan prediksi dari ketiga model. Untuk MSE, RMSE, dan MAE, nilai yang lebih kecil menunjukkan kesalahan prediksi yang lebih rendah. Perbedaan nilai pada grafik menunjukkan bahwa perubahan shrinkage dapat memengaruhi kinerja model.

ggplot(tabel_metrik, aes(x = Model, y = R2, fill = Model)) +
  geom_col(width = 0.65, show.legend = FALSE) +
  geom_text(aes(label = round(R2, 4)), vjust = -0.4, size = 4) +
  labs(
    title = "Perbandingan R-squared pada Data Uji",
    x = "Model",
    y = "R-squared (R²)"
  ) +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", hjust = 0.5))

Grafik R² menunjukkan proporsi variasi respons yang dapat dijelaskan oleh prediksi model relatif terhadap rata-rata nilai aktual pada data uji. Nilai R² yang lebih besar umumnya lebih baik. R² negatif menunjukkan bahwa model memiliki kesalahan kuadrat lebih besar dibandingkan prediksi sederhana yang selalu menggunakan rata-rata respons data uji.

4.4 Perbandingan Jumlah Iterasi Optimal

ggplot(tabel_metrik, aes(x = Model, y = Iterasi_Optimal, fill = Model)) +
  geom_col(width = 0.65, show.legend = FALSE) +
  geom_text(aes(label = Iterasi_Optimal), vjust = -0.4, size = 4) +
  labs(
    title = "Jumlah Iterasi Optimal Berdasarkan Cross-Validation",
    x = "Model",
    y = "Jumlah iterasi optimal"
  ) +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold", hjust = 0.5))

Jumlah iterasi optimal dapat berbeda pada setiap nilai shrinkage. Nilai shrinkage yang lebih kecil sering memerlukan lebih banyak iterasi karena kontribusi setiap pohon lebih kecil. Namun, jumlah iterasi terbaik tetap ditentukan berdasarkan hasil cross-validation, bukan hanya berdasarkan besar kecilnya nilai shrinkage.

4.5 Penentuan Model Terbaik dan Interpretasi Otomatis

# Model terbaik ditentukan terutama dari MSE terendah pada data uji
peringkat <- tabel_metrik[order(tabel_metrik$MSE), ]
rownames(peringkat) <- NULL

peringkat_tampil <- peringkat
peringkat_tampil[c("CV_Error_Minimum", "MSE", "RMSE", "MAE", "R2")] <-
  lapply(peringkat_tampil[c("CV_Error_Minimum", "MSE", "RMSE", "MAE", "R2")],
         round, digits = 4)

knitr::kable(
  peringkat_tampil,
  caption = "Tabel 4.4 Peringkat model berdasarkan MSE data uji"
)
Tabel 4.4 Peringkat model berdasarkan MSE data uji
Model Shrinkage Iterasi_Optimal CV_Error_Minimum MSE RMSE MAE R2
Shrinkage_0.05 0.05 991 1.9584 1.8777 1.3703 1.0683 0.9299
Shrinkage_0.01 0.01 3000 1.9450 1.9466 1.3952 1.0919 0.9273
Shrinkage_0.10 0.10 418 2.0980 1.9527 1.3974 1.0744 0.9271
model_terbaik <- peringkat[1, ]
cat(
  "\nModel terbaik berdasarkan MSE terendah pada data uji adalah",
  model_terbaik$Model,
  "dengan shrinkage =", model_terbaik$Shrinkage,
  ", jumlah iterasi optimal =", model_terbaik$Iterasi_Optimal,
  ", MSE =", round(model_terbaik$MSE, 4),
  ", RMSE =", round(model_terbaik$RMSE, 4),
  ", MAE =", round(model_terbaik$MAE, 4),
  ", dan R-squared =", round(model_terbaik$R2, 4), ".\n"
)
## 
## Model terbaik berdasarkan MSE terendah pada data uji adalah Shrinkage_0.05 dengan shrinkage = 0.05 , jumlah iterasi optimal = 991 , MSE = 1.8777 , RMSE = 1.3703 , MAE = 1.0683 , dan R-squared = 0.9299 .
cat("\nInterpretasi otomatis:\n")
## 
## Interpretasi otomatis:
cat(
  "Model", model_terbaik$Model,
  "memiliki MSE paling rendah pada data uji di antara model yang dibandingkan. ",
  "Nilai RMSE sebesar", round(model_terbaik$RMSE, 4),
  "menunjukkan besarnya kesalahan prediksi dalam satuan respons. ",
  "Nilai MAE sebesar", round(model_terbaik$MAE, 4),
  "menunjukkan rata-rata kesalahan absolut prediksi. ",
  "Nilai R-squared sebesar", round(model_terbaik$R2, 4),
  "merangkum kemampuan prediksi model relatif terhadap rata-rata respons data uji.\n"
)
## Model Shrinkage_0.05 memiliki MSE paling rendah pada data uji di antara model yang dibandingkan.  Nilai RMSE sebesar 1.3703 menunjukkan besarnya kesalahan prediksi dalam satuan respons.  Nilai MAE sebesar 1.0683 menunjukkan rata-rata kesalahan absolut prediksi.  Nilai R-squared sebesar 0.9299 merangkum kemampuan prediksi model relatif terhadap rata-rata respons data uji.
cat(
  "\nCatatan: model terbaik dipilih berdasarkan MSE pada data uji. ",
  "Perhatikan juga RMSE, MAE, R-squared, dan CV error sebelum menarik kesimpulan akhir.\n"
)
## 
## Catatan: model terbaik dipilih berdasarkan MSE pada data uji.  Perhatikan juga RMSE, MAE, R-squared, dan CV error sebelum menarik kesimpulan akhir.

Model dengan MSE terendah dipilih sebagai model terbaik berdasarkan kriteria utama praktikum. RMSE dan MAE digunakan untuk melihat besar kesalahan prediksi dari sudut pandang yang berbeda, sedangkan R² digunakan untuk melihat kemampuan model menjelaskan variasi respons. Interpretasi akhir perlu merujuk pada nilai yang muncul dari hasil eksekusi kode, bukan menggunakan angka perkiraan.

4.6 Contoh Prediksi Aktual dan Prediksi Model Terbaik

nama_terbaik <- model_terbaik$Model
prediksi_terbaik <- prediksi_list[[nama_terbaik]]

tabel_prediksi <- data.frame(
  Aktual = data_test$y,
  Prediksi = as.numeric(prediksi_terbaik),
  Residual = data_test$y - as.numeric(prediksi_terbaik)
)

knitr::kable(
  head(tabel_prediksi, 10) |> transform(
    Aktual = round(Aktual, 4),
    Prediksi = round(Prediksi, 4),
    Residual = round(Residual, 4)
  ),
  caption = "Tabel 4.5 Sepuluh contoh hasil prediksi model terbaik"
)
Tabel 4.5 Sepuluh contoh hasil prediksi model terbaik
Aktual Prediksi Residual
14.9072 17.0836 -2.1764
6.6383 6.6221 0.0161
25.1894 23.3888 1.8006
17.3630 16.5839 0.7791
19.5181 21.0723 -1.5542
10.4566 9.4074 1.0492
21.2201 19.8800 1.3401
8.4469 8.6774 -0.2304
23.8722 21.7406 2.1316
6.3153 7.4710 -1.1557

Tabel tersebut menampilkan sepuluh pengamatan pertama pada data uji, yang memuat nilai aktual, nilai prediksi, dan residual. Residual merupakan selisih antara nilai aktual dan prediksi. Residual yang semakin dekat dengan nol menunjukkan prediksi yang semakin dekat dengan nilai aktual untuk pengamatan tersebut.

BAB V KESIMPULAN DAN SARAN

5.1 Kesimpulan

Gradient Boosting Regression diterapkan pada data simulasi Friedman menggunakan fungsi gbm() dengan nilai shrinkage sebesar 0,01, 0,05, dan 0,10. Jumlah iterasi optimal ditentukan menggunakan 5-fold cross-validation. Kinerja model dievaluasi pada data uji menggunakan MSE, RMSE, MAE, dan R².

Model terbaik ditentukan berdasarkan MSE terendah pada data uji. Nilai shrinkage, jumlah iterasi optimal, dan nilai metrik model terbaik ditampilkan secara otomatis pada bagian hasil. Dengan demikian, kesimpulan akhir mengikuti hasil perhitungan yang diperoleh saat kode dijalankan di RStudio.

5.2 Saran

Analisis berikutnya dapat membandingkan pengaturan lain, seperti kedalaman interaksi (interaction.depth), jumlah minimum pengamatan pada simpul akhir (n.minobsinnode), dan proporsi sampel (bag.fraction). Penggunaan beberapa random seed atau pembagian data yang berbeda juga dapat dilakukan untuk memeriksa kestabilan hasil. Pemilihan model sebaiknya tidak hanya mempertimbangkan satu metrik, tetapi juga melihat RMSE, MAE, R², dan kesalahan validasi silang.

DAFTAR PUSTAKA

Friedman, J. H. (2001). Greedy function approximation: A gradient boosting machine. The Annals of Statistics, 29(5), 1189–1232.

Ridgeway, G. (2024). gbm: Generalized Boosted Regression Models. R package documentation.

R Core Team. (2026). R: A language and environment for statistical computing. R Foundation for Statistical Computing.

LAMPIRAN

Seluruh kode program disertakan pada setiap bagian laporan. Buka berkas .Rmd di RStudio, pastikan koneksi internet tersedia saat paket perlu dipasang, kemudian klik Knit untuk menghasilkan laporan HTML yang memuat tabel, grafik, evaluasi model, dan interpretasi berdasarkan hasil aktual.