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².
gbm()?shrinkage?shrinkage mana yang menghasilkan kinerja terbaik
pada data uji?shrinkage sebesar 0,01, 0,05, dan
0,10.Praktikum ini diharapkan membantu memahami penerapan Gradient Boosting Regression, fungsi cross-validation dalam memilih jumlah iterasi, serta penggunaan metrik evaluasi untuk membandingkan model regresi.
mlbench.friedman1() pada paket mlbench.y, sedangkan variabel prediktor
adalah x1 sampai x10.gbm() dengan
distribusi Gaussian.shrinkage yang dibandingkan adalah 0,01, 0,05,
dan 0,10.Laporan ini terdiri dari pendahuluan, tinjauan pustaka, metode penelitian, hasil dan pembahasan, kesimpulan dan saran, daftar pustaka, serta lampiran kode program.
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.
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.
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.
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.
Metrik yang digunakan untuk membandingkan prediksi pada data uji adalah:
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} \]
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.
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")
| 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 |
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.
Gambar 3.1. Diagram alir penerapan Gradient Boosting Regression.
# 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")
| 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")
| 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.
# 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"
)
| 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.
# 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.
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.
# 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"
)
| 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.
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"
)
| 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.
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.
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.
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.
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.