Analisis regresi digunakan untuk memprediksi respons yang bersifat numerik kontinu, dan penerapannya sangat luas, antara lain pada prediksi harga rumah (Lisnawati & Nugroho, 2024), harga beras (Andriyani dkk., 2024), penjualan daerah (Rahmah dkk., 2026), hingga curah hujan harian (Syukur dkk., 2026). Hubungan antara respons dan prediktor pada data nyata umumnya tidak linear dan sering melibatkan interaksi antarvariabel. Syukur dkk. (2026) menyebutkan bahwa varian Gradient Boosting konsisten memberikan kinerja yang sebanding atau lebih baik daripada model konvensional pada kasus yang melibatkan variabel dengan interaksi nonlinear. Kondisi tersebut mendorong penggunaan metode berbasis ensemble.
Ensemble learning adalah pendekatan yang menggabungkan beberapa model dasar (base learner) agar diperoleh model gabungan dengan kemampuan prediksi yang lebih baik. Boosting merupakan salah satu metode ensemble yang membentuk serangkaian model sederhana secara berurutan (sequential), dengan setiap model baru dibangun berdasarkan kesalahan yang masih tersisa dari model sebelumnya (Fransiska, 2026). Pada kasus regresi, metode ini dikenal sebagai Gradient Boosting, yaitu weak learner berikutnya diarahkan untuk mempelajari residual dari model yang telah terbentuk (Fransiska, 2026).
Sejumlah penelitian di Indonesia melaporkan kinerja Gradient Boosting yang baik. Lisnawati dan Nugroho (2024) menerapkan decision tree-based gradient boosting pada data harga rumah Jabodetabek dan memperoleh RMSE sebesar Rp277.369.397 dengan MAPE 17,3%, sehingga metode ini dinilai cukup kompetitif dibandingkan metode lain. Andriyani dkk. (2024) memprediksi harga beras premium dengan Gradient Boosted Trees Regression dan memperoleh \(R^2\) sebesar 0,9047 serta RMSE sebesar 0,0473 pada pembagian data latih dan uji 80:20. Rahmah dkk. (2026) membandingkan SVR, Gradient Boosting Regressor, Random Forest Regressor, dan XGBoost, dan melaporkan bahwa Gradient Boosting Regressor memberikan galat terendah (MAE = 127,98 dan RMSE = 185,63) dengan \(R^2\) tertinggi sebesar 0,94 setelah dilakukan tuning parameter.
Kinerja Boosting sangat dipengaruhi oleh parameter model, yaitu jumlah iterasi, learning rate (shrinkage), dan kedalaman pohon (Fransiska, 2026). Jumlah iterasi yang terlalu sedikit dapat menyebabkan underfitting, sedangkan model yang terlalu kompleks berpotensi mengalami overfitting (Fransiska, 2026). Oleh karena itu, penentuan parameter secara hati-hati melalui optimasi hiperparameter menjadi bagian penting dalam penerapan Gradient Boosting (Syukur dkk., 2026). Pada praktikum ini, Gradient Boosting diterapkan pada data simulasi Friedman dengan membandingkan tiga nilai learning rate, yaitu 0,01; 0,05; dan 0,10, serta menggunakan cross-validation untuk menentukan jumlah iterasi optimal pada masing-masing model.
Berdasarkan latar belakang, rumusan masalah yang dapat disimpulkan adalah sebagai berikut:
gbm() dengan nilai learning
rate 0,01; 0,05; dan 0,10, serta menentukan jumlah iterasi optimal
melalui cross-validation?Berdasarkan rumusan masalah tersebut, tujuan yang dapat disimpulkan adalah sebagai berikut:
Ensemble learning merupakan pendekatan yang menggabungkan beberapa model dasar (base learner) agar diperoleh model gabungan dengan kemampuan prediksi yang lebih baik. Bagging membentuk banyak model dari sampel bootstrap kemudian menggabungkan hasil prediksinya, sedangkan Boosting memiliki tujuan yang sama tetapi dengan cara pembentukan model yang berbeda secara mendasar (Fransiska, 2026).
Boosting adalah metode ensemble yang membentuk serangkaian model sederhana secara berurutan. Model berikutnya dibangun dengan memperhatikan kesalahan yang masih dilakukan oleh model sebelumnya. Model sederhana pada setiap tahap disebut weak learner, yaitu model dengan kemampuan prediksi terbatas bila digunakan sendiri. Setelah sejumlah weak learner digabungkan, diperoleh model akhir yang lebih kuat, yang disebut strong learner. Pada Boosting berbasis pohon, decision tree dengan kedalaman terbatas sering digunakan sebagai base learner (Fransiska, 2026).
Tabel 1. Perbedaan Bagging dan Boosting
| Aspek | Bagging | Boosting |
|---|---|---|
| Cara membangun model | Paralel/relatif independen | Sequential; learner berikutnya bergantung pada hasil sebelumnya |
| Data tiap learner | Umumnya sampel bootstrap | Data, bobot, atau target disesuaikan berdasarkan kesalahan sebelumnya |
| Fokus utama | Mengurangi variance melalui agregasi | Memperbaiki kesalahan secara bertahap |
| Base learner | Sering menggunakan pohon yang relatif besar | Umumnya learner sederhana/pohon dangkal |
| Komputasi | Mudah diparalelkan | Lebih sulit diparalelkan karena bersifat sequential |
| Parameter penting | Jumlah model/bootstrap | Jumlah iterasi, learning rate, dan kompleksitas learner |
Pada kasus regresi, kesalahan model dapat dilihat melalui residual, yaitu selisih antara nilai aktual dan nilai prediksi (Fransiska, 2026):
\[e_i = y_i - \hat{y}_i\]
Gradient Boosting membangun weak learner berikutnya untuk mempelajari bagian kesalahan tersebut. Proses Gradient Boosting secara sederhana adalah sebagai berikut (Fransiska, 2026):
Model diperbarui secara bertahap menurut:
\[f_m(x) = f_{m-1}(x) + \nu \, h_m(x)\]
dengan \(f_{m-1}(x)\) adalah model pada iterasi sebelumnya, \(h_m(x)\) adalah weak learner pada iterasi ke-\(m\), dan \(\nu\) adalah learning rate atau shrinkage. Model akhir yang terbentuk adalah:
\[f_M(x) = f_0(x) + \nu \sum_{m=1}^{M} h_m(x)\]
Nilai learning rate mengatur seberapa besar kontribusi learner baru terhadap model. Nilai yang lebih kecil membuat proses pembelajaran berlangsung lebih perlahan dan biasanya membutuhkan lebih banyak iterasi (Fransiska, 2026).
Tabel 2. Parameter pada Gradient Boosting
(gbm)
| Parameter | Argumen gbm() |
Peran |
|---|---|---|
| Jumlah iterasi / learner | n.trees |
Menentukan banyaknya pohon yang ditambahkan |
| Learning rate (\(\nu\)) | shrinkage |
Mengatur besar kontribusi setiap learner baru |
| Kedalaman pohon | interaction.depth |
Mengatur kompleksitas setiap weak learner |
| Jumlah observasi minimum pada simpul | n.minobsinnode |
Membatasi pemisahan pada simpul yang terlalu kecil |
| Proporsi subsampel | bag.fraction |
Proporsi data yang digunakan pada tiap iterasi (1 berarti seluruh data latih) |
| Jumlah lipatan validasi silang | cv.folds |
Menentukan banyaknya lipatan pada cross-validation |
Jumlah iterasi yang terlalu sedikit dapat menyebabkan underfitting, sedangkan model yang terlalu kompleks berpotensi mengalami overfitting. Oleh karena itu, jumlah iterasi dan learning rate perlu dipilih dengan hati-hati (Fransiska, 2026).
Pada k-fold cross-validation, data latih dibagi menjadi \(k\) lipatan. Model dilatih pada \(k-1\) lipatan dan diuji pada satu lipatan sisanya, proses ini diulang sebanyak \(k\) kali sehingga setiap lipatan menjadi data uji satu kali. Pada Gradient Boosting, galat hasil validasi silang dihitung pada setiap iterasi \(m = 1, 2, \dots, M\). Jumlah iterasi optimal dipilih pada iterasi dengan galat validasi silang terkecil:
\[M^{*} = \arg\min_{m} \; CV(m)\]
Setelah \(M^{*}\) diperoleh, prediksi dilakukan hanya dengan \(M^{*}\) pohon pertama sehingga model tidak terus menyesuaikan diri terhadap data latih secara berlebihan.
Relative influence pada gbm mengukur kontribusi
setiap variabel prediktor berdasarkan besarnya penurunan galat kuadrat
yang dihasilkan oleh pemisahan pada variabel tersebut, yang
dirata-ratakan pada seluruh pohon, kemudian dinormalisasi sehingga
totalnya sama dengan 100. Semakin besar nilainya, semakin besar peran
variabel tersebut dalam model.
Evaluasi dilakukan dengan membandingkan nilai aktual dan nilai hasil prediksi pada data testing. Ukuran yang digunakan adalah sebagai berikut (Fransiska, 2026):
\[MSE = \frac{1}{n}\sum_{i=1}^{n}\left(y_i - \hat{y}_i\right)^2\]
\[RMSE = \sqrt{MSE}\]
\[MAE = \frac{1}{n}\sum_{i=1}^{n}\left|y_i - \hat{y}_i\right|\]
\[R^2 = 1 - \frac{\sum_{i=1}^{n}\left(y_i - \hat{y}_i\right)^2}{\sum_{i=1}^{n}\left(y_i - \bar{y}\right)^2}\]
MSE, RMSE, dan MAE semakin baik jika nilainya semakin kecil, sedangkan \(R^2\) semakin baik jika semakin mendekati 1.
Jenis data yang digunakan dalam penelitian ini adalah data
kuantitatif, yaitu data berbentuk angka yang dapat diolah dan dianalisis
secara statistik. Data yang digunakan merupakan data simulasi Friedman
#1 yang dibangkitkan menggunakan fungsi mlbench.friedman1()
pada package mlbench dalam perangkat lunak R, dengan jumlah
observasi sebanyak 200 dan set.seed(234) agar data dapat
direproduksi. Data terdiri atas 10 variabel prediktor \(x_1, x_2, \dots, x_{10}\) yang
masing-masing berdistribusi seragam pada selang \((0,1)\) dan satu variabel respons \(y\) yang dibangkitkan dari fungsi:
\[y = 10\sin(\pi x_1 x_2) + 20(x_3 - 0.5)^2 + 10x_4 + 5x_5 + \varepsilon, \qquad \varepsilon \sim N(0, 1)\]
Dengan demikian, hanya lima variabel pertama (\(x_1\) sampai \(x_5\)) yang benar-benar memengaruhi \(y\), sedangkan \(x_6\) sampai \(x_{10}\) merupakan variabel noise. Struktur data yang diketahui ini memungkinkan penilaian apakah model Gradient Boosting mampu mengenali variabel yang berpengaruh.
| No | Variabel | Keterangan | Tipe Data | Peran |
|---|---|---|---|---|
| 1 | y | Respons hasil fungsi Friedman #1 ditambah noise \(N(0,1)\) | Numerik | Respons |
| 2 | x.1 | Prediktor \(U(0,1)\), masuk pada komponen \(10\sin(\pi x_1 x_2)\) | Numerik | Prediktor (informatif) |
| 3 | x.2 | Prediktor \(U(0,1)\), masuk pada komponen \(10\sin(\pi x_1 x_2)\) | Numerik | Prediktor (informatif) |
| 4 | x.3 | Prediktor \(U(0,1)\), masuk pada komponen \(20(x_3 - 0.5)^2\) | Numerik | Prediktor (informatif) |
| 5 | x.4 | Prediktor \(U(0,1)\), masuk pada komponen \(10x_4\) | Numerik | Prediktor (informatif) |
| 6 | x.5 | Prediktor \(U(0,1)\), masuk pada komponen \(5x_5\) | Numerik | Prediktor (informatif) |
| 7 | x.6 s.d. x.10 | Prediktor \(U(0,1)\) yang tidak masuk pada fungsi respons | Numerik | Prediktor (noise) |
Langkah-langkah yang digunakan pada penelitian ini adalah sebagai berikut:
mlbench.friedman1(200) dengan set.seed(234),
lalu memeriksa struktur, ringkasan, dan ukuran data.set.seed(234).gbm()
dengan distribution = "gaussian",
interaction.depth = 2, n.minobsinnode = 5,
bag.fraction = 1, dan cv.folds = 10 untuk
masing-masing learning rate 0,01; 0,05; dan 0,10.gbm.perf() dengan metode
cross-validation.Pada batasan masalah diminta melakukan analisis Boosting secara
lengkap mulai dari persiapan data, pembentukan model, prediksi,
evaluasi, visualisasi, dan interpretasi dengan menggunakan
set.seed(234) agar hasil pembagian data dapat direproduksi.
Analisis dilakukan untuk kasus regresi menggunakan Gradient Boosting
pada data Friedman dengan fungsi gbm(). Dibandingkan tiga
nilai learning rate (shrinkage) \(\nu\) = 0,01; 0,05; dan 0,10, dan
cross-validation digunakan untuk menentukan jumlah iterasi
optimal pada masing-masing model. Performa dibandingkan berdasarkan MSE,
RMSE, MAE, dan \(R^2\), kemudian
hasilnya diinterpretasikan.
Berikut adalah package yang digunakan pada penelitian. Package
gbm digunakan untuk membentuk model Gradient Boosting,
mlbench untuk membangkitkan data Friedman,
caret untuk membagi data training dan testing, serta
ggplot2 dan dplyr untuk visualisasi dan
pengolahan data.
## x.1 x.2 x.3 x.4 x.5 x.6 x.7
## 1 0.74562000 0.5754994 0.02885590 0.7201653 0.8748022 0.2761835 0.93319087
## 2 0.78171242 0.3157821 0.93745388 0.1849746 0.7039934 0.6426889 0.40177800
## 3 0.02003711 0.7646459 0.79777294 0.5338609 0.9515834 0.9873938 0.08742998
## 4 0.77608539 0.2289793 0.66797951 0.5534984 0.4780999 0.8425175 0.89302195
## 5 0.06691009 0.1715219 0.59740948 0.7547957 0.5332404 0.7327976 0.10244557
## 6 0.64479512 0.6473963 0.01351334 0.7894812 0.2376348 0.4302338 0.88236742
## x.8 x.9 x.10 y
## 1 0.607462891 0.7560942 0.7179672 24.349507
## 2 0.003687496 0.4046106 0.5338439 18.046792
## 3 0.010598118 0.2473974 0.6669937 12.018651
## 4 0.446393069 0.1443539 0.6802987 12.101870
## 5 0.834936006 0.1874371 0.5950115 9.911772
## 6 0.843509237 0.6166422 0.1081932 21.874286
## 'data.frame': 200 obs. of 11 variables:
## $ x.1 : num 0.7456 0.7817 0.02 0.7761 0.0669 ...
## $ x.2 : num 0.575 0.316 0.765 0.229 0.172 ...
## $ x.3 : num 0.0289 0.9375 0.7978 0.668 0.5974 ...
## $ x.4 : num 0.72 0.185 0.534 0.553 0.755 ...
## $ x.5 : num 0.875 0.704 0.952 0.478 0.533 ...
## $ x.6 : num 0.276 0.643 0.987 0.843 0.733 ...
## $ x.7 : num 0.9332 0.4018 0.0874 0.893 0.1024 ...
## $ x.8 : num 0.60746 0.00369 0.0106 0.44639 0.83494 ...
## $ x.9 : num 0.756 0.405 0.247 0.144 0.187 ...
## $ x.10: num 0.718 0.534 0.667 0.68 0.595 ...
## $ y : num 24.35 18.05 12.02 12.1 9.91 ...
## [1] 200 11
## x.1 x.2 x.3 x.4
## Min. :0.001198 Min. :0.004583 Min. :0.01021 Min. :0.00707
## 1st Qu.:0.274097 1st Qu.:0.255644 1st Qu.:0.24506 1st Qu.:0.20772
## Median :0.541847 Median :0.436813 Median :0.48965 Median :0.50295
## Mean :0.509759 Mean :0.465323 Mean :0.48570 Mean :0.48821
## 3rd Qu.:0.741416 3rd Qu.:0.651439 3rd Qu.:0.73476 3rd Qu.:0.76599
## Max. :0.993590 Max. :0.999850 Max. :0.99985 Max. :0.99761
## x.5 x.6 x.7 x.8
## Min. :0.008246 Min. :0.005504 Min. :0.001884 Min. :0.002496
## 1st Qu.:0.267523 1st Qu.:0.194431 1st Qu.:0.226788 1st Qu.:0.249826
## Median :0.522081 Median :0.446060 Median :0.491332 Median :0.480306
## Mean :0.503282 Mean :0.468544 Mean :0.503754 Mean :0.482050
## 3rd Qu.:0.751688 3rd Qu.:0.746035 3rd Qu.:0.780325 3rd Qu.:0.696675
## Max. :0.994604 Max. :0.999021 Max. :0.993044 Max. :0.995613
## x.9 x.10 y
## Min. :0.004483 Min. :0.005544 Min. : 3.082
## 1st Qu.:0.203254 1st Qu.:0.329160 1st Qu.:10.593
## Median :0.453476 Median :0.592614 Median :13.810
## Mean :0.471873 Mean :0.540708 Mean :14.270
## 3rd Qu.:0.742412 3rd Qu.:0.765353 3rd Qu.:18.063
## Max. :0.997436 Max. :0.998141 Max. :26.146
Data Friedman yang dibangkitkan terdiri atas 200 observasi dan 11 variabel, yaitu 1 variabel respons (y) dan 10 variabel prediktor (x.1 sampai x.10), seluruhnya bertipe numerik. Berdasarkan ringkasan respons y, nilai minimum sebesar 3,08, median sebesar 13,81, rata-rata sebesar 14,27, dan maksimum sebesar 26,15. Seluruh prediktor memiliki nilai pada selang 0 sampai 1 sesuai dengan distribusi seragam yang digunakan saat pembangkitan data.
## x.1 x.2 x.3 x.4 x.5 x.6 x.7 x.8 x.9 x.10 y
## 0 0 0 0 0 0 0 0 0 0 0
## [1] 0
Berdasarkan hasil pengecekan, jumlah missing value pada seluruh variabel adalah 0. Hal ini wajar karena data dibangkitkan secara simulasi sehingga tidak diperlukan penanganan data hilang dan seluruh observasi dapat digunakan.
set.seed(234)
idx.reg <- createDataPartition(reg.data$y, p = 0.70, list = FALSE)
reg.train <- reg.data[idx.reg, ]
reg.test <- reg.data[-idx.reg, ]
dim(reg.train)## [1] 140 11
## [1] 60 11
Berdasarkan hasil pembagian data dengan proporsi 70:30, data training terdiri atas 140 observasi (sekitar 70,0%) yang digunakan untuk membentuk model, sedangkan data testing terdiri atas 60 observasi (sekitar 30,0%) yang digunakan untuk menguji kemampuan model pada data yang tidak digunakan dalam pelatihan. Jumlah keduanya sama dengan 200 observasi pada data awal.
nu.values <- c(0.01, 0.05, 0.10) # learning rate (shrinkage)
lab.nu <- c("0.01", "0.05", "0.10") # label untuk grafik
lab.nu.id <- c("0,01", "0,05", "0,10") # label untuk teks
n.pohon <- 3000 # batas maksimum iterasi
boost.list <- vector("list", length(nu.values))
names(boost.list) <- paste0("shrinkage_", lab.nu)
for (i in seq_along(nu.values)) {
set.seed(234)
boost.list[[i]] <- gbm(formula = y ~ ., data = reg.train,
distribution = "gaussian", n.trees = n.pohon,
interaction.depth = 2, shrinkage = nu.values[i],
bag.fraction = 1, cv.folds = 10,
n.minobsinnode = 5, verbose = FALSE)
}
boost.list## $shrinkage_0.01
## gbm(formula = y ~ ., distribution = "gaussian", data = reg.train,
## n.trees = n.pohon, interaction.depth = 2, n.minobsinnode = 5,
## shrinkage = nu.values[i], bag.fraction = 1, cv.folds = 10,
## verbose = FALSE)
## A gradient boosted model with gaussian loss function.
## 3000 iterations were performed.
## The best cross-validation iteration was 2038.
## There were 10 predictors of which 10 had non-zero influence.
##
## $shrinkage_0.05
## gbm(formula = y ~ ., distribution = "gaussian", data = reg.train,
## n.trees = n.pohon, interaction.depth = 2, n.minobsinnode = 5,
## shrinkage = nu.values[i], bag.fraction = 1, cv.folds = 10,
## verbose = FALSE)
## A gradient boosted model with gaussian loss function.
## 3000 iterations were performed.
## The best cross-validation iteration was 458.
## There were 10 predictors of which 10 had non-zero influence.
##
## $shrinkage_0.10
## gbm(formula = y ~ ., distribution = "gaussian", data = reg.train,
## n.trees = n.pohon, interaction.depth = 2, n.minobsinnode = 5,
## shrinkage = nu.values[i], bag.fraction = 1, cv.folds = 10,
## verbose = FALSE)
## A gradient boosted model with gaussian loss function.
## 3000 iterations were performed.
## The best cross-validation iteration was 212.
## There were 10 predictors of which 10 had non-zero influence.
Tiga model Gradient Boosting dibentuk dengan
distribution = "gaussian" karena respons berupa numerik
kontinu dan fungsi kerugian yang digunakan adalah galat kuadrat.
Kompleksitas setiap weak learner dibatasi dengan
interaction.depth = 2 dan n.minobsinnode = 5,
sedangkan bag.fraction = 1 berarti seluruh data training
digunakan pada setiap iterasi sehingga proses pembelajaran bersifat
deterministik. Ketiga model hanya berbeda pada nilai shrinkage,
yaitu 0,01; 0,05; dan 0,10, sehingga perbedaan kinerja yang muncul dapat
dikaitkan dengan learning rate. Setiap model dilatih dengan
batas maksimum 3000 pohon, lebih besar daripada contoh pada modul (1000
pohon), agar model dengan learning rate kecil memiliki ruang
iterasi yang cukup untuk mencapai titik optimumnya. Validasi silang
dilakukan dengan cv.folds = 10.
best.iter <- numeric(length(nu.values))
par(mfrow = c(1, 3))
for (i in seq_along(nu.values)) {
best.iter[i] <- gbm.perf(boost.list[[i]], method = "cv", plot.it = TRUE)
title(main = paste("shrinkage =", lab.nu[i]))
}par(mfrow = c(1, 1))
iter.df <- data.frame(
Shrinkage = nu.values,
Maks_Iterasi = n.pohon,
Iterasi_Optimal = best.iter,
CV_MSE_Minimum = sapply(boost.list, function(m) min(m$cv.error))
)
rownames(iter.df) <- NULL
kable(iter.df, digits = 4)| Shrinkage | Maks_Iterasi | Iterasi_Optimal | CV_MSE_Minimum |
|---|---|---|---|
| 0.01 | 3000 | 2038 | 4.0047 |
| 0.05 | 3000 | 458 | 4.0046 |
| 0.10 | 3000 | 212 | 3.9630 |
cv.df <- do.call(rbind, lapply(seq_along(nu.values), function(i) {
data.frame(Iterasi = seq_len(n.pohon),
CV_Error = boost.list[[i]]$cv.error,
Shrinkage = lab.nu[i])
}))
titik.opt <- data.frame(Iterasi = best.iter,
CV_Error = iter.df$CV_MSE_Minimum,
Shrinkage = lab.nu)
ggplot(cv.df, aes(x = Iterasi, y = CV_Error, color = Shrinkage)) +
geom_line(linewidth = 0.8) +
geom_point(data = titik.opt, size = 3.5) +
coord_cartesian(ylim = c(0, quantile(cv.df$CV_Error, 0.95))) +
theme_minimal() +
labs(title = "Kurva Cross-Validation Error Gradient Boosting",
subtitle = "Titik menunjukkan jumlah iterasi optimal",
x = "Jumlah Iterasi (Pohon)", y = "CV Error (MSE)")Berdasarkan hasil cross-validation 10 lipatan, jumlah iterasi optimal untuk \(\nu\) = 0,01 sebesar 2038 pohon, untuk \(\nu\) = 0,05 sebesar 458 pohon, dan untuk \(\nu\) = 0,10 sebesar 212 pohon. Semakin besar nilai ν, semakin sedikit iterasi optimal yang diperlukan. Pola ini sesuai dengan teori karena ν yang kecil membuat setiap pohon hanya memberikan kontribusi kecil sehingga model perlu menambahkan lebih banyak pohon untuk mencapai titik galat minimum. Seluruh iterasi optimal berada di bawah batas maksimum (3000 pohon), sehingga kurva CV error setiap model telah mencapai titik minimum sebelum iterasi maksimum.
Nilai CV error (MSE) minimum masing-masing model adalah 4,0047 untuk \(\nu\) = 0,01, 4,0046 untuk \(\nu\) = 0,05, dan 3,9630 untuk \(\nu\) = 0,10. Pada data training, CV error terendah dicapai oleh model dengan \(\nu\) = 0,10. Pada grafik, setiap kurva turun tajam pada iterasi awal ketika model masih memperbaiki kesalahan besar, kemudian melandai menuju titik minimum. Iterasi setelah titik minimum tidak lagi memperbaiki prediksi pada data validasi sehingga pemilihan iterasi melalui cross-validation membantu mencegah overfitting.
actual <- reg.test$y
pred.list <- lapply(seq_along(nu.values), function(i) {
as.numeric(predict(boost.list[[i]], newdata = reg.test,
n.trees = best.iter[i], type = "response"))
})
names(pred.list) <- lab.nu
hasil.reg <- data.frame(
Aktual = actual,
Prediksi_0.01 = pred.list[["0.01"]],
Prediksi_0.05 = pred.list[["0.05"]],
Prediksi_0.10 = pred.list[["0.10"]]
)
head(hasil.reg, 10)## Aktual Prediksi_0.01 Prediksi_0.05 Prediksi_0.10
## 1 10.232309 10.32266 10.46850 10.40406
## 2 11.845301 11.02738 11.01535 10.82324
## 3 10.335689 11.57048 11.91667 11.92377
## 4 16.727262 15.47287 15.48904 15.54978
## 5 25.077119 23.60350 23.78820 23.89650
## 6 15.446886 16.14900 16.16480 16.00467
## 7 15.642915 14.87591 14.65071 14.82544
## 8 7.110835 11.94504 11.97079 12.16898
## 9 13.351277 16.12859 15.78174 15.89434
## 10 12.871960 14.45813 14.64838 14.49979
hitung.eval <- function(aktual, prediksi) {
MSE <- mean((aktual - prediksi)^2)
data.frame(
MSE = MSE,
RMSE = sqrt(MSE),
MAE = mean(abs(aktual - prediksi)),
R2 = 1 - sum((aktual - prediksi)^2) / sum((aktual - mean(aktual))^2)
)
}
evaluasi.reg <- cbind(
Shrinkage = nu.values,
Iterasi_Optimal = best.iter,
do.call(rbind, lapply(pred.list, function(p) hitung.eval(actual, p)))
)
rownames(evaluasi.reg) <- NULL
kable(evaluasi.reg, digits = 4)| Shrinkage | Iterasi_Optimal | MSE | RMSE | MAE | R2 |
|---|---|---|---|---|---|
| 0.01 | 2038 | 4.2550 | 2.0628 | 1.5951 | 0.8225 |
| 0.05 | 458 | 4.2639 | 2.0649 | 1.6008 | 0.8221 |
| 0.10 | 212 | 4.0312 | 2.0078 | 1.5579 | 0.8318 |
Hasil prediksi menunjukkan perbandingan nilai aktual dengan prediksi dari ketiga model, dan residual yang kecil menandakan prediksi yang dekat dengan nilai aktual. Berdasarkan evaluasi pada data testing:
Nilai RMSE menunjukkan rata-rata besarnya kesalahan prediksi dalam satuan yang sama dengan y, sedangkan nilai \(R^2\) menunjukkan proporsi keragaman y pada data testing yang dapat dijelaskan model. Sebagai acuan, noise pada data Friedman #1 memiliki simpangan baku 1, sehingga RMSE terendah yang secara teori dapat dicapai oleh model yang sempurna mendekati 1,00, dan \(R^2\) maksimum teoretis diperkirakan sekitar 0,96. RMSE model terbaik adalah 2,0078, yaitu sekitar 2,01 kali batas teoretis tersebut.
rmse.train <- sapply(seq_along(nu.values), function(i) {
p <- predict(boost.list[[i]], newdata = reg.train,
n.trees = best.iter[i], type = "response")
sqrt(mean((reg.train$y - p)^2))
})
perbandingan <- data.frame(
Shrinkage = nu.values,
Iterasi_Optimal = best.iter,
MSE = evaluasi.reg$MSE,
RMSE = evaluasi.reg$RMSE,
MAE = evaluasi.reg$MAE,
R2 = evaluasi.reg$R2,
RMSE_Train = rmse.train,
Selisih_RMSE = evaluasi.reg$RMSE - rmse.train
)
kable(perbandingan, digits = 4)| Shrinkage | Iterasi_Optimal | MSE | RMSE | MAE | R2 | RMSE_Train | Selisih_RMSE |
|---|---|---|---|---|---|---|---|
| 0.01 | 2038 | 4.2550 | 2.0628 | 1.5951 | 0.8225 | 0.6212 | 1.4415 |
| 0.05 | 458 | 4.2639 | 2.0649 | 1.6008 | 0.8221 | 0.5726 | 1.4923 |
| 0.10 | 212 | 4.0312 | 2.0078 | 1.5579 | 0.8318 | 0.6033 | 1.4045 |
Berdasarkan tabel perbandingan, model terbaik pada data testing adalah model dengan \(\nu\) = 0,10 karena menghasilkan MSE terkecil (4,0312), RMSE terkecil (2,0078), dan \(R^2\) tertinggi (0,8318). Nilai \(R^2\) tersebut berarti model mampu menjelaskan sekitar 83,18% keragaman respons pada data testing. Keempat ukuran evaluasi menunjuk model yang sama sebagai yang terbaik, yaitu ν = 0,10, sehingga pemilihan model terbaik bersifat konsisten.
Selisih RMSE antara model terbaik dan model terburuk adalah sekitar 2,77% dari RMSE model terburuk. Selisih RMSE antarmodel tergolong kecil sehingga ketiga nilai ν menghasilkan kinerja yang hampir setara pada data ini. Dalam kondisi tersebut, pemilihan ν juga dapat mempertimbangkan waktu komputasi karena ν kecil membutuhkan lebih banyak iterasi.
Selain itu terdapat, RMSE pada data training lebih kecil daripada RMSE pada data testing untuk setiap model, yang wajar karena model dibentuk dari data training. Selisih RMSE testing terhadap training terbesar terdapat pada model dengan \(\nu\) = 0,05 (1,4923). Semakin besar selisih ini, semakin besar indikasi model menyesuaikan diri dengan data training dibandingkan data baru. Penggunaan jumlah iterasi optimal dari cross-validation berfungsi membatasi selisih tersebut.
plot.df <- do.call(rbind, lapply(seq_along(nu.values), function(i) {
data.frame(Aktual = actual,
Prediksi = pred.list[[i]],
Residual = actual - pred.list[[i]],
Shrinkage = paste("shrinkage =", lab.nu[i]))
}))
ggplot(plot.df, aes(x = Aktual, y = Prediksi)) +
geom_point(color = "steelblue", alpha = 0.8, size = 2) +
geom_abline(intercept = 0, slope = 1, linetype = "dashed", linewidth = 0.8) +
facet_wrap(~ Shrinkage) +
theme_minimal() +
labs(title = "Aktual vs Prediksi: Gradient Boosting",
x = "Nilai Aktual", y = "Nilai Prediksi")Pada plot aktual terhadap prediksi, semakin dekat titik-titik dengan garis diagonal putus-putus (\(y = x\)), semakin akurat prediksi model. Koefisien korelasi antara nilai aktual dan prediksi pada data testing sebesar 0,9163 untuk \(\nu\) = 0,01, 0,9168 untuk \(\nu\) = 0,05, dan 0,9215 untuk \(\nu\) = 0,10. Nilai korelasi yang tinggi menunjukkan bahwa besaran prediksi mengikuti nilai aktual dengan baik pada ketiga model.
ggplot(plot.df, aes(x = Prediksi, y = Residual)) +
geom_point(color = "tomato", alpha = 0.8, size = 2) +
geom_hline(yintercept = 0, linetype = "dashed", linewidth = 0.8) +
facet_wrap(~ Shrinkage) +
theme_minimal() +
labs(title = "Residual Plot: Gradient Boosting",
x = "Nilai Prediksi", y = "Residual")Residual dihitung sebagai selisih nilai aktual dan prediksi. Rata-rata residual masing-masing model adalah -0,3604 (\(\nu\) = 0,01), -0,3986 (\(\nu\) = 0,05), dan -0,3976 (\(\nu\) = 0,10), dengan simpangan baku residual berturut-turut 2,0482, 2,0432, dan 1,9846. Rata-rata residual pada seluruh model sangat kecil dibandingkan simpangan bakunya, sehingga tidak terdapat indikasi bias sistematis berupa overestimasi atau underestimasi yang besar. Pada residual plot, sebaran titik yang acak di sekitar garis nol tanpa pola melengkung atau melebar menandakan bahwa model telah menangkap pola hubungan pada data.
imp.list <- lapply(seq_along(nu.values), function(i) {
s <- summary(boost.list[[i]], n.trees = best.iter[i], plotit = FALSE)
data.frame(Variabel = as.character(s$var),
Rel_Inf = s$rel.inf,
Shrinkage = paste("shrinkage =", lab.nu[i]))
})
# Variable importance model terbaik
imp.best <- imp.list[[i.best]][, c("Variabel", "Rel_Inf")]
kable(imp.best, digits = 4, row.names = FALSE)| Variabel | Rel_Inf |
|---|---|
| x.4 | 38.4746 |
| x.1 | 28.2478 |
| x.2 | 13.8418 |
| x.3 | 11.7264 |
| x.5 | 5.4518 |
| x.6 | 1.0221 |
| x.7 | 0.4197 |
| x.10 | 0.4045 |
| x.9 | 0.2587 |
| x.8 | 0.1526 |
# Visualisasi untuk ketiga model
imp.df <- do.call(rbind, imp.list)
ggplot(imp.df, aes(x = reorder(Variabel, Rel_Inf), y = Rel_Inf)) +
geom_col(fill = "green4") +
coord_flip() +
facet_wrap(~ Shrinkage) +
theme_minimal() +
labs(title = "Variable Importance - Gradient Boosting",
x = "Variabel Prediktor", y = "Relative Influence")Pada model terbaik (\(\nu\) = 0,10), variabel dengan relative influence terbesar berturut-turut adalah x.4, x.1, x.2, x.3, x.5, dengan variabel teratas (x.4) memiliki kontribusi 38,47%. Lima variabel dengan pengaruh terbesar sama dengan lima variabel informatif pada fungsi Friedman #1 (x.1 sampai x.5), sehingga model berhasil mengenali struktur data yang sebenarnya. Total relative influence variabel informatif (x.1 sampai x.5) sebesar 97,74%, sedangkan total pengaruh lima variabel noise (x.6 sampai x.10) hanya 2,26%. Hasil ini sejalan dengan struktur fungsi Friedman #1 yang hanya memuat lima variabel informatif. Pola urutan kepentingan antarmodel pada grafik juga dapat dibandingkan untuk menilai apakah pemilihan learning rate mengubah variabel yang dianggap penting.
Boosting adalah metode ensemble yang membangun model sederhana secara berurutan, dengan setiap model baru diarahkan untuk memperbaiki kesalahan model sebelumnya. Pada kasus regresi, Gradient Boosting memperbarui model secara bertahap melalui \(f_m(x) = f_{m-1}(x) + \nu h_m(x)\), yaitu weak learner baru mempelajari residual dan kontribusinya diatur oleh learning rate \(\nu\).
Model dibangun melalui beberapa tahap. Pertama, data Friedman
dibangkitkan (200 observasi, 10 prediktor) dan dipastikan tidak memiliki
missing value. Kedua, data dibagi menjadi 140 observasi training dan 60
observasi testing dengan set.seed(234). Ketiga, tiga model
Gradient Boosting dibentuk menggunakan gbm() dengan
learning rate 0,01; 0,05; dan 0,10. Keempat, jumlah iterasi
optimal ditentukan melalui cross-validation 10 lipatan, yaitu
2038, 458, dan 212 pohon. Kelima, kinerja model dievaluasi pada data
testing menggunakan MSE, RMSE, MAE, dan \(R^2\).
Berdasarkan hasil yang diperoleh, model dengan learning rate \(\nu\) = 0,10 memiliki kinerja terbaik pada data testing dengan MSE sebesar 4,0312, RMSE sebesar 2,0078, MAE sebesar 1,5579, dan \(R^2\) sebesar 0,8318. Selisih RMSE antarmodel tergolong kecil sehingga ketiga nilai ν menghasilkan kinerja yang hampir setara pada data ini. Dalam kondisi tersebut, pemilihan ν juga dapat mempertimbangkan waktu komputasi karena ν kecil membutuhkan lebih banyak iterasi. Variabel yang paling berpengaruh dalam model terbaik adalah x.4, x.1, x.2, x.3, x.5, dengan total relative influence variabel informatif (x.1 sampai x.5) sebesar 97,74%.
Praktikan disarankan untuk mempelajari lebih lanjut mengenai program
RStudio dan package gbm melalui berbagai sumber
pembelajaran, seperti buku, jurnal, modul praktikum, maupun sumber
belajar lainnya agar semakin memahami penerapan Boosting. Pada
penelitian selanjutnya, dapat dilakukan pencarian kombinasi parameter
yang lebih luas (misalnya interaction.depth,
n.minobsinnode, dan bag.fraction) menggunakan
grid search, serta pengulangan pembagian data atau repeated
cross-validation agar perbandingan antar nilai learning
rate lebih stabil. Praktikan juga diharapkan lebih teliti dalam
melakukan pengolahan data dan penulisan kode program agar dapat
meminimalkan kesalahan selama praktikum.
Andriyani, M., Nurwilda, S., Haq, D. Z., & Novitasari, D. C. R. (2024). Prediksi harga beras premium tahun 2024 menggunakan metode Gradient Boosted Trees Regression. Jurnal Teknologi Informasi: Jurnal Keilmuan dan Aplikasi Bidang Teknik Informatika, 18(2), 75–84. https://doi.org/10.47111/jti.v18i2.14859
Fransiska, H. (2026). Modul Praktikum Machine Learning dan Model Prediction. Universitas Bengkulu: Bengkulu.
Lisnawati, I., & Nugroho, A. A. (2024). Decision tree-based gradient boosting: Algorithm to approach house price prediction in Jakarta, Bogor, Depok, Tangerang, Bekasi (Jabodetabek). Jurnal Statistika Universitas Muhammadiyah Semarang, 12(2), 60–70. https://doi.org/10.26714/jsunimus.12.2.2024.60-70
Rahmah, M., Ramadanti, K., & Aulia, I. F. (2026). Perbandingan algoritma regresi dalam memprediksi penjualan berdasarkan indikator sosial ekonomi Kabupaten Cirebon (2010-2023). Jurnal FASILKOM, 16(1), 1–9. https://doi.org/10.37859/jf.v16i1.9729
Syukur, M. A. A., Suhartono, & Imamudin, M. (2026). Hyperparameter-optimized gradient boosting for daily rainfall prediction using BMKG meteorological data in Malang Regency, Indonesia. Jambura Journal of Mathematics, 8(2), 188–201. https://doi.org/10.37905/jjom.v8i2.38554