Dalam machine learning, ensemble learning merupakan pendekatan yang menggabungkan beberapa model untuk menghasilkan prediksi yang lebih baik. Salah satu metode ensemble learning adalah Random Forest, yaitu metode yang membangun sejumlah pohon keputusan (decision trees) menggunakan sampel bootstrap dan pemilihan prediktor secara acak pada setiap node. Metode ini dikembangkan dari Bagging dengan tujuan mengurangi variansi model serta meningkatkan kemampuan generalisasi dalam permasalahan klasifikasi maupun regresi.
Penerapan Random Forest dalam permasalahan klasifikasi dan regresi dikaji oleh Ignatenko dkk. (2024) melalui penelitian berjudul Random Forests with Parametric Entropy-Based Information Gains for Classification and Regression Problems. Selain itu, Khairunnisa dkk. (2024) melakukan penelitian berjudul A Comparative Study of Random Forest and Double Random Forest Models from View Points of Their Interpretability yang membandingkan Random Forest dan Double Random Forest dari aspek interpretabilitas model. Pengembangan Random Forest menghasilkan metode Double Random Forest (DRF), yang menggunakan seluruh data latih untuk membangun setiap pohon, sedangkan proses bootstrap dilakukan pada setiap node untuk menentukan pemisahan terbaik.
Pada praktikum ini, Random Forest dan Double Random Forest diterapkan untuk permasalahan klasifikasi dan regresi menggunakan perangkat lunak R. Performa kedua metode dievaluasi menggunakan beberapa ukuran evaluasi, seperti Accuracy, Precision, Recall, Specificity, F1-Score, dan ROC-AUC untuk klasifikasi, serta MSE, RMSE, MAE, dan R-Square untuk regresi. Selain itu, dilakukan pengamatan terhadap nilai Out-of-Bag (OOB) error untuk mengetahui kemampuan prediksi model serta membandingkan kinerja Random Forest dan Double Random Forest.
Berdasarkan latar belakang di atas, rumusan masalah yang dapat disimpulkan yaitu:
Berdasarkan rumusan masalah di atas, tujuan yang dapat disimpulkan yaitu:
Adapun manfaat dari praktikum ini yaitu:
Adapun batasan masalah dari praktikum ini, yaitu lakukan Random Forest Regression pada data Friedman. Bandingkan mtry = 2, 3, dan 5 dengan num.trees = 200, 500, dan 1000. Bandingkan performa data testing berdasarkan MSE, RMSE, MAE, R2, residual plot, dan variable importance. Tampilkan pula OOB MSE sebagai evaluasi internal model.
Random Forest merupakan algoritma ensemble learning berbasis decision tree yang membangun banyak pohon keputusan dan menggabungkan hasil prediksinya untuk meningkatkan akurasi serta mengurangi overfitting. Menurut James, Witten, Hastie, dan Tibshirani dalam buku An Introduction to Statistical Learning (ISL), Random Forest merupakan pengembangan dari metode Bagging (Bootstrap Aggregating) yang menggunakan kumpulan pohon keputusan sebagai model dasar. Metode ini dirancang untuk mengurangi variansi model dan meningkatkan kemampuan generalisasi (Fransiska, 2026).
Seperti Bagging, Random Forest membentuk banyak pohon melalui proses resampling, kemudian menggabungkan hasil prediksinya. Perbedaannya terletak pada pengacakan pemilihan prediktor di setiap node. Dengan demikian, pohon-pohon dalam forest tidak hanya dibangun dari sampel yang berbeda, tetapi juga tidak selalu mempertimbangkan prediktor yang sama ketika mencari split terbaik. Pengacakan prediktor bertujuan untuk mengurangi korelasi antar-pohon. Dengan menghasilkan pohon yang kuat tetapi tidak terlalu berkorelasi, Random Forest dapat mengurangi variance tanpa harus memangkas setiap pohon secara agresif (Fransiska, 2026).
Konsep dasar Random Forest meliputi (Fransiska, 2026):
Bootstrap Sampling, yaitu dataset dilatih dengan mengambil sampel acak menggunakan pengembalian (with replacement), sehingga setiap pohon dibangun dari sampel yang berbeda.
Pembangunan Banyak Pohon (Ensemble Trees), yaitu setiap pohon dikembangkan hingga cukup dalam agar menghasilkan model dengan bias rendah dan variance tinggi.
Random Feature Selection, yaitu konsep yang membuat pada setiap node, hanya sejumlah kecil fitur yang dipilih secara acak untuk dipertimbangkan sebagai kandidat pemisahan (split). Pendekatan ini membuat pohon menjadi lebih tidak berkorelasi satu sama lain.
Agregasi Prediksi, yaitu hasil prediksi dari seluruh pohon digabungkan dengan ketentuan:
Tabel 1. Perbedaan Bagging dan Random Forest
| Aspek | Bagging | Random Forest |
|---|---|---|
| Data tiap pohon | Menggunakan sampel bootstrap | Menggunakan sampel bootstrap |
| Prediktor pada split | Semua prediktor dapat dipertimbangkan | Hanya sejumlah mtry prediktor yang dipilih
secara acak |
| Korelasi antar-pohon | Dapat relatif tinggi | Dikurangi melalui random feature selection |
| Agregasi klasifikasi | Majority voting | Majority voting |
| Agregasi regresi | Rata-rata prediksi | Rata-rata prediksi |
| Fokus utama | Mengurangi variance melalui agregasi | Mengurangi variance sekaligus mendekorelasi pohon |
Misalkan tersedia data latih \(D = \{(x_i,y_i), i=1,2,\ldots,n\}\) dan akan dibentuk sebanyak \(B\) pohon. Secara sederhana, proses Random Forest dilakukan sebagai berikut (Fransiska, 2026):
mtry prediktor
secara acak dari seluruh \(p\)
prediktor.Untuk klasifikasi, hasil akhir diperoleh melalui majority voting:
\[ \hat{G}_{RF}(x) = \operatorname{mode}\{G_1(x),G_2(x),\ldots,G_B(x)\} \]
Untuk regresi, hasil akhir diperoleh dengan merata-ratakan prediksi seluruh pohon:
\[ \hat{f}_{RF}(x) = \frac{1}{B}\sum_{b=1}^{B}T_b(x) \]
Dengan demikian, Random Forest merupakan metode parallel ensemble, yaitu setiap pohon dapat dibentuk secara relatif independen. Hal ini berbeda dengan metode Boosting yang membangun model secara berurutan (sequential).
Pada proses bootstrap berukuran \(n\) yang diambil dengan pengembalian dari \(n\) observasi, sebagian observasi dapat terambil lebih dari satu kali dan sebagian lainnya tidak terambil. Secara rata-rata, proporsi observasi unik yang masuk ke dalam satu sampel bootstrap mendekati \(1-e^{-1} \approx 0,632\). Artinya, sekitar 36,8% observasi tidak digunakan untuk membentuk pohon tertentu dan disebut sebagai Out-of-Bag (OOB) observations. Setiap observasi, prediksi OOB diperoleh hanya dari pohon-pohon yang tidak menggunakan observasi tersebut ketika dibentuk. Prediksi ini dapat digunakan untuk menghitung OOB prediction error sebagai ukuran evaluasi internal Random Forest (Fransiska, 2026).
Double Random Forest (DRF) merupakan metode yang diperkenalkan oleh Han, Kim, dan Lee pada tahun 2020. DRF dikembangkan untuk mengatasi kondisi ketika Random Forest masih mengalami underfitting akibat ukuran pohon yang belum cukup besar.
Pada Random Forest standar, setiap pohon dibentuk menggunakan satu sampel bootstrap pada awal pembentukan pohon. Karena satu sampel bootstrap rata-rata hanya mengandung sekitar 63,2% observasi unik, jumlah observasi unik yang tersedia untuk membentuk setiap pohon lebih sedikit dibandingkan keseluruhan data latih.
Berbeda dengan Random Forest, setiap pohon pada DRF dibangun menggunakan seluruh data latih. Sementara itu, proses bootstrap dilakukan secara sementara pada setiap node untuk mencari aturan pemisahan (split).
Secara sederhana, proses Double Random Forest dilakukan sebagai berikut (Fransiska, 2026):
mtry prediktor secara acak dan mencari
split terbaik menggunakan sampel bootstrap pada
node.Pada klasifikasi, hasil akhir diperoleh melalui majority voting, sedangkan pada regresi prediksi akhir diperoleh dengan merata-ratakan prediksi seluruh pohon. Hal ini karena setiap pohon menggunakan seluruh data latih untuk tumbuh, DRF cenderung dapat menghasilkan pohon yang lebih besar. Pada saat yang sama, penggunaan bootstrap pada setiap node dan pemilihan subset prediktor secara acak tetap menambahkan keragaman pada aturan split. Konsekuensinya, DRF umumnya membutuhkan waktu komputasi lebih besar dibandingkan Random Forest karena proses bootstrap dilakukan berulang pada banyak node (Fransiska, 2026).
Tabel 2. Perbedaan Random Forest dan Double Random Forest
| Aspek | Random Forest | Double Random Forest |
|---|---|---|
| Penggunaan data | Setiap pohon dibentuk dari sampel bootstrap yang berbeda | Setiap pohon dimulai menggunakan seluruh data latih |
| Jumlah observasi unik | Rata-rata sekitar 63,2% dari data latih pada setiap sampel bootstrap | Seluruh data latih digunakan untuk memulai setiap pohon |
| Proses pemisahan | Bootstrap sampling dilakukan pada awal pembentukan pohon | Bootstrap sampling dilakukan pada setiap node untuk mencari split |
| Ukuran pohon | Cenderung lebih kecil | Cenderung lebih besar |
| Waktu komputasi | Relatif lebih cepat | Relatif lebih lama |
| Penentuan hasil prediksi akhir | Majority voting untuk klasifikasi dan rata-rata untuk regresi | Majority voting untuk klasifikasi dan rata-rata untuk regresi |
Dalam penerapan Random Forest dan Double Random Forest, terdapat beberapa parameter yang perlu diperhatikan untuk mengoptimalkan performa model. Parameter tersebut antara lain (Fransiska, 2026):
Tabel 3. Parameter Penting Random Forest dan DRF
| Parameter | Peran |
|---|---|
num.trees / ntree |
Menentukan jumlah pohon yang dibentuk dalam ensemble. |
mtry |
Menentukan jumlah prediktor kandidat yang dipilih secara acak pada setiap node. |
min.node.size / nodesize |
Mengatur ukuran minimum node dan secara tidak langsung memengaruhi kompleksitas pohon. |
replace dan
sample.fraction |
Mengatur mekanisme dan proporsi pengambilan sampel pada Random Forest. |
splitrule |
Menentukan aturan pemisahan, misalnya Gini untuk
klasifikasi dan variance untuk regresi pada paket
ranger. |
importance |
Menentukan apakah dan bagaimana tingkat kepentingan variabel (variable importance) dihitung. |
Evaluasi model dilakukan untuk mengetahui kemampuan Random Forest dan Double Random Forest dalam menghasilkan prediksi. Ukuran evaluasi yang digunakan disesuaikan dengan jenis analisis, yaitu klasifikasi dan regresi.
Tabel 4. Ukuran Evaluasi Model
| Jenis Analisis | Ukuran Evaluasi | Arah Interpretasi |
|---|---|---|
| Klasifikasi | Accuracy, Precision, Recall/Sensitivity, Specificity, F1-Score, ROC-AUC | Semakin besar semakin baik |
| Regresi | MSE, RMSE, MAE, \(R^2\) | MSE, RMSE, dan MAE semakin kecil semakin baik, sedangkan \(R^2\) semakin besar semakin baik |
Secara umum, evaluasi tersebut digunakan untuk membandingkan performa Random Forest dan Double Random Forest sehingga dapat diketahui metode yang memberikan hasil prediksi lebih baik berdasarkan karakteristik data yang digunakan.
Data yang digunakan merupakan data sekunder berupa data simulasi
Friedman yang dibangkitkan menggunakan fungsi
mlbench.friedman1() dari package
mlbench pada perangkat lunak R, sebanyak 200 observasi
dengan set.seed(234). Karena data dibangkitkan melalui
simulasi, data ini tidak berasal dari pengamatan langsung terhadap objek
penelitian nyata.
Penelitian ini menggunakan variabel y sebagai variabel
respons numerik kontinu dan sepuluh variabel numerik
(X1–X10) sebagai variabel prediktor.
Berdasarkan persamaan pembangkit data, hanya lima variabel prediktor
pertama (X1–X5) yang benar-benar memengaruhi
y, sedangkan X6–X10 merupakan
variabel noise.
Berikut adalah langkah-langkah yang dilakukan dalam analisis:
mlbench, caret,
dan ranger.createDataPartition()
dengan set.seed(234).ranger() pada kombinasi mtry = 2, 3, 5 dan
num.trees = 200, 500, 1000 (9 model), dengan
importance = "permutation".prediction.error) dari setiap
model.set.seed(234)
reg.data <- as.data.frame(mlbench.friedman1(200))
names(reg.data) <- c(paste0("X", 1:10), "y")
str(reg.data)## 'data.frame': 200 obs. of 11 variables:
## $ X1 : num 0.7456 0.7817 0.02 0.7761 0.0669 ...
## $ X2 : num 0.575 0.316 0.765 0.229 0.172 ...
## $ X3 : num 0.0289 0.9375 0.7978 0.668 0.5974 ...
## $ X4 : num 0.72 0.185 0.534 0.553 0.755 ...
## $ X5 : num 0.875 0.704 0.952 0.478 0.533 ...
## $ X6 : num 0.276 0.643 0.987 0.843 0.733 ...
## $ X7 : num 0.9332 0.4018 0.0874 0.893 0.1024 ...
## $ X8 : num 0.60746 0.00369 0.0106 0.44639 0.83494 ...
## $ X9 : num 0.756 0.405 0.247 0.144 0.187 ...
## $ X10: num 0.718 0.534 0.667 0.68 0.595 ...
## $ y : num 24.35 18.05 12.02 12.1 9.91 ...
## X1 X2 X3 X4
## 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
## X5 X6 X7 X8
## 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
## X9 X10 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
## [1] 200 11
Data hasil simulasi terdiri dari 200 observasi dan 11 variabel, yaitu
satu variabel respons y dan sepuluh variabel prediktor
numerik (X1–X10). Seluruh prediktor memiliki
rentang nilai antara 0 sampai 1 dengan rata-rata berkisar 0,47–0,54,
sesuai dengan sifat data Friedman yang prediktornya dibangkitkan dari
sebaran seragam. Variabel y bernilai antara 3,082 sampai
26,146 dengan rata-rata 14,270 dan median 13,810. Rata-rata yang sedikit
lebih besar daripada median menunjukkan sebaran y condong
sedikit ke kanan.
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
Pembagian data menghasilkan 140 observasi sebagai data training (70%) dan 60 observasi sebagai data testing (30%). Data training digunakan untuk membangun model, sedangkan data testing digunakan untuk mengukur kemampuan prediksi pada data yang belum pernah dilihat model.
Dibentuk sembilan model Random Forest Regression dari
kombinasi mtry = 2, 3, 5 dan num.trees = 200,
500, 1000. Parameter lain dibuat sama pada seluruh model, yaitu
min.node.size = 5, replace = TRUE,
sample.fraction = 1, dan
importance = "permutation".
# mtry = 2
set.seed(234)
rf.2.200 <- ranger(
y ~ ., data = reg.train,
num.trees = 200,
mtry = 2,
min.node.size = 5,
replace = TRUE,
sample.fraction = 1,
importance = "permutation",
seed = 234
)
set.seed(234)
rf.2.500 <- ranger(
y ~ ., data = reg.train,
num.trees = 500,
mtry = 2,
min.node.size = 5,
replace = TRUE,
sample.fraction = 1,
importance = "permutation",
seed = 234
)
set.seed(234)
rf.2.1000 <- ranger(
y ~ ., data = reg.train,
num.trees = 1000,
mtry = 2,
min.node.size = 5,
replace = TRUE,
sample.fraction = 1,
importance = "permutation",
seed = 234
)
# mtry = 3
set.seed(234)
rf.3.200 <- ranger(
y ~ ., data = reg.train,
num.trees = 200,
mtry = 3,
min.node.size = 5,
replace = TRUE,
sample.fraction = 1,
importance = "permutation",
seed = 234
)
set.seed(234)
rf.3.500 <- ranger(
y ~ ., data = reg.train,
num.trees = 500,
mtry = 3,
min.node.size = 5,
replace = TRUE,
sample.fraction = 1,
importance = "permutation",
seed = 234
)
set.seed(234)
rf.3.1000 <- ranger(
y ~ ., data = reg.train,
num.trees = 1000,
mtry = 3,
min.node.size = 5,
replace = TRUE,
sample.fraction = 1,
importance = "permutation",
seed = 234
)
# mtry = 5
set.seed(234)
rf.5.200 <- ranger(
y ~ ., data = reg.train,
num.trees = 200,
mtry = 5,
min.node.size = 5,
replace = TRUE,
sample.fraction = 1,
importance = "permutation",
seed = 234
)
set.seed(234)
rf.5.500 <- ranger(
y ~ ., data = reg.train,
num.trees = 500,
mtry = 5,
min.node.size = 5,
replace = TRUE,
sample.fraction = 1,
importance = "permutation",
seed = 234
)
set.seed(234)
rf.5.1000 <- ranger(
y ~ ., data = reg.train,
num.trees = 1000,
mtry = 5,
min.node.size = 5,
replace = TRUE,
sample.fraction = 1,
importance = "permutation",
seed = 234
)oob.mse <- data.frame(
Model = c(
"RF 2-200", "RF 2-500", "RF 2-1000",
"RF 3-200", "RF 3-500", "RF 3-1000",
"RF 5-200", "RF 5-500", "RF 5-1000"
),
mtry = c(2, 2, 2, 3, 3, 3, 5, 5, 5),
num.trees = c(200, 500, 1000, 200, 500, 1000, 200, 500, 1000),
OOB_MSE = c(
rf.2.200$prediction.error,
rf.2.500$prediction.error,
rf.2.1000$prediction.error,
rf.3.200$prediction.error,
rf.3.500$prediction.error,
rf.3.1000$prediction.error,
rf.5.200$prediction.error,
rf.5.500$prediction.error,
rf.5.1000$prediction.error
)
)
knitr::kable(oob.mse, digits = 4, align = "lccc",
caption = "Tabel 5. OOB MSE Seluruh Model")| Model | mtry | num.trees | OOB_MSE |
|---|---|---|---|
| RF 2-200 | 2 | 200 | 8.2222 |
| RF 2-500 | 2 | 500 | 8.1267 |
| RF 2-1000 | 2 | 1000 | 8.0553 |
| RF 3-200 | 3 | 200 | 7.7097 |
| RF 3-500 | 3 | 500 | 7.4424 |
| RF 3-1000 | 3 | 1000 | 7.3547 |
| RF 5-200 | 5 | 200 | 7.0632 |
| RF 5-500 | 5 | 500 | 6.8750 |
| RF 5-1000 | 5 | 1000 | 6.8260 |
Nilai OOB MSE berkisar antara 6,8260 sampai 8,2222. Pada setiap nilai
mtry, OOB MSE menurun seiring bertambahnya jumlah pohon,
misalnya pada mtry = 5 turun dari 7,0632 (200 pohon)
menjadi 6,8750 (500 pohon) dan 6,8260 (1000 pohon). Penurunan juga
terjadi ketika mtry dinaikkan pada jumlah pohon yang sama.
Pada 1000 pohon, OOB MSE turun dari 8,0553 (mtry = 2)
menjadi 7,3547 (mtry = 3) dan 6,8260 (mtry =
5). Model dengan OOB MSE terkecil adalah RF 5-1000 (6,8260) dan yang
terbesar adalah RF 2-200 (8,2222), sehingga kombinasi terbaik secara
internal mengurangi kesalahan sekitar 17% dibandingkan kombinasi
terburuk.
model.rf <- list(
"RF 2-200" = rf.2.200,
"RF 2-500" = rf.2.500,
"RF 2-1000" = rf.2.1000,
"RF 3-200" = rf.3.200,
"RF 3-500" = rf.3.500,
"RF 3-1000" = rf.3.1000,
"RF 5-200" = rf.5.200,
"RF 5-500" = rf.5.500,
"RF 5-1000" = rf.5.1000
)
actual.reg <- reg.test$y
pred.rf <- lapply(
model.rf,
function(model) {
predict(model, data = reg.test)$predictions
}
)evaluasi.rf <- data.frame()
for (i in names(pred.rf)) {
pred <- pred.rf[[i]]
MSE <- mean((actual.reg - pred)^2)
RMSE <- sqrt(MSE)
MAE <- mean(abs(actual.reg - pred))
R2 <- 1 -
sum((actual.reg - pred)^2) /
sum((actual.reg - mean(actual.reg))^2)
evaluasi.rf <- rbind(
evaluasi.rf,
data.frame(
Model = i,
MSE = MSE,
RMSE = RMSE,
MAE = MAE,
R_Square = R2
)
)
}
knitr::kable(evaluasi.rf, digits = 4, align = "lcccc",
caption = "Tabel 6. Performa Model pada Data Testing")| Model | MSE | RMSE | MAE | R_Square |
|---|---|---|---|---|
| RF 2-200 | 7.8700 | 2.8054 | 2.3414 | 0.6717 |
| RF 2-500 | 8.1774 | 2.8596 | 2.3832 | 0.6589 |
| RF 2-1000 | 8.1181 | 2.8492 | 2.3794 | 0.6613 |
| RF 3-200 | 7.8139 | 2.7953 | 2.2981 | 0.6740 |
| RF 3-500 | 7.8278 | 2.7978 | 2.3058 | 0.6734 |
| RF 3-1000 | 7.7780 | 2.7889 | 2.2996 | 0.6755 |
| RF 5-200 | 7.6596 | 2.7676 | 2.2726 | 0.6805 |
| RF 5-500 | 7.3826 | 2.7171 | 2.2312 | 0.6920 |
| RF 5-1000 | 7.1925 | 2.6819 | 2.2054 | 0.6999 |
hasil.rf <- merge(
evaluasi.rf,
oob.mse[, c("Model", "mtry", "num.trees", "OOB_MSE")],
by = "Model"
)
hasil.rf <- hasil.rf[
order(hasil.rf$mtry, hasil.rf$num.trees),
]
rownames(hasil.rf) <- NULLpar(mfrow = c(1, 2))
warna <- c("2" = "tomato", "3" = "steelblue", "5" = "darkgreen")
# RMSE testing
plot(NULL,
xlim = range(hasil.rf$num.trees),
ylim = range(hasil.rf$RMSE),
xlab = "num.trees", ylab = "RMSE (Testing)",
main = "RMSE Data Testing")
for (m in c(2, 3, 5)) {
d <- hasil.rf[hasil.rf$mtry == m, ]
lines(d$num.trees, d$RMSE, type = "b", pch = 19, lwd = 2,
col = warna[as.character(m)])
}
legend("topright", legend = paste("mtry =", c(2, 3, 5)),
col = warna, lwd = 2, pch = 19, bty = "n")
# OOB MSE
plot(NULL,
xlim = range(hasil.rf$num.trees),
ylim = range(hasil.rf$OOB_MSE),
xlab = "num.trees", ylab = "OOB MSE",
main = "OOB MSE")
for (m in c(2, 3, 5)) {
d <- hasil.rf[hasil.rf$mtry == m, ]
lines(d$num.trees, d$OOB_MSE, type = "b", pch = 19, lwd = 2,
col = warna[as.character(m)])
}
legend("topright", legend = paste("mtry =", c(2, 3, 5)),
col = warna, lwd = 2, pch = 19, bty = "n")Pada data testing, MSE berkisar antara 7,1925 sampai 8,1774,
RMSE antara 2,6819 sampai 2,8596, MAE antara 2,2054 sampai 2,3832, dan
\(R^2\) antara 0,6589 sampai 0,6999.
Kenaikan mtry memperbaiki seluruh ukuran tersebut.
Rata-rata RMSE untuk mtry = 2, 3, dan 5 berturut-turut
adalah 2,8381; 2,7940; dan 2,7222, sehingga mtry = 5
memberikan kesalahan prediksi terkecil.
Pengaruh jumlah pohon tidak sekuat pengaruh mtry.
Rata-rata RMSE untuk 200, 500, dan 1000 pohon adalah 2,7894; 2,7915; dan
2,7733, dengan selisih terbesar hanya 0,0182, dibandingkan selisih
0,1159 antar nilai mtry. Pada mtry = 2, RMSE
justru naik dari 2,8054 (200 pohon) menjadi 2,8596 (500 pohon) sebelum
turun sedikit menjadi 2,8492 (1000 pohon), sedangkan pada
mtry = 3 perubahannya sangat kecil (2,7953; 2,7978;
2,7889). Hanya pada mtry = 5 RMSE turun konsisten, yaitu
2,7676; 2,7171; dan 2,6819 untuk 200, 500, dan 1000 pohon.
Hasil OOB dan data testing menunjukkan arah yang sama, yaitu
model dengan mtry lebih besar menghasilkan galat lebih
kecil. Perbedaannya, OOB MSE menurun secara konsisten seiring
bertambahnya pohon pada semua mtry, sedangkan MSE data
testing tidak selalu demikian. Hal ini wajar karena data
testing hanya terdiri dari 60 observasi sehingga lebih peka
terhadap fluktuasi kecil, sedangkan OOB MSE dihitung dari 140 observasi
training.
## [1] "RF 5-1000"
hasil.model.terbaik <- hasil.rf[
hasil.rf$Model == model.terbaik,
]
knitr::kable(hasil.model.terbaik, digits = 4, align = "lcccccc", row.names = FALSE,
caption = "Tabel 7. Model Terbaik Berdasarkan RMSE Data Testing")| Model | MSE | RMSE | MAE | R_Square | mtry | num.trees | OOB_MSE |
|---|---|---|---|---|---|---|---|
| RF 5-1000 | 7.1925 | 2.6819 | 2.2054 | 0.6999 | 5 | 1000 | 6.826 |
Model terbaik berdasarkan RMSE data testing terkecil adalah
RF 5-1000 (mtry = 5 dan num.trees =
1000) dengan MSE 7,1925, RMSE 2,6819, MAE 2,2054, dan \(R^2\) 0,6999. Model ini mampu menjelaskan
sekitar 69,99% variasi y pada data testing, dengan
rata-rata kesalahan prediksi sekitar 2,21 satuan y (RMSE
2,68 setara sekitar 19% dari rata-rata y sebesar 14,27).
Model yang sama juga memiliki OOB MSE terkecil (6,8260), sehingga
evaluasi internal dan evaluasi data testing memberikan
kesimpulan yang sama. Nilai OOB MSE (6,8260) yang sedikit lebih kecil
daripada MSE data testing (7,1925) menunjukkan tidak terdapat
indikasi overfitting yang berarti.
rf.terbaik <- model.rf[[model.terbaik]]
pred.terbaik <- pred.rf[[model.terbaik]]
residual.terbaik <- actual.reg - pred.terbaik
hasil.terbaik <- data.frame(
Aktual = actual.reg,
Prediksi = pred.terbaik,
Residual = residual.terbaik
)
knitr::kable(head(hasil.terbaik, 10), digits = 4, align = "ccc",
caption = "Tabel 8. Contoh Aktual, Prediksi, dan Residual Model Terbaik")| Aktual | Prediksi | Residual |
|---|---|---|
| 10.2323 | 12.5456 | -2.3133 |
| 11.8453 | 10.2819 | 1.5634 |
| 10.3357 | 12.7822 | -2.4465 |
| 16.7273 | 13.7236 | 3.0037 |
| 25.0771 | 20.4441 | 4.6331 |
| 15.4469 | 14.4420 | 1.0048 |
| 15.6429 | 12.7974 | 2.8455 |
| 7.1108 | 12.5782 | -5.4674 |
| 13.3513 | 15.5267 | -2.1754 |
| 12.8720 | 14.8896 | -2.0176 |
par(mfrow = c(1, 2))
# Aktual vs Prediksi
plot(
actual.reg,
pred.terbaik,
pch = 19,
xlab = "Nilai Aktual",
ylab = "Nilai Prediksi",
main = paste("Aktual vs Prediksi:", model.terbaik)
)
abline(0, 1, lty = 2, lwd = 2, col = "red")
# Residual plot
plot(
pred.terbaik,
residual.terbaik,
pch = 19,
xlab = "Nilai Prediksi",
ylab = "Residual",
main = paste("Residual Plot:", model.terbaik)
)
abline(h = 0, lty = 2, lwd = 2)Korelasi antara nilai aktual dan prediksi pada model terbaik sebesar 0,8588, yang menunjukkan hubungan positif yang kuat sehingga titik-titik pada grafik aktual vs prediksi mengikuti arah garis diagonal. Rata-rata residual sebesar -0,2726 dengan rentang -5,76 sampai 4,79. Rata-rata yang bernilai negatif dan dekat dengan nol menunjukkan prediksi secara umum hanya sedikit lebih tinggi daripada nilai aktual, tanpa bias yang besar.
Pada sepuluh observasi pertama (Tabel 8), residual negatif muncul
pada nilai aktual yang kecil (misalnya aktual 7,1108 diprediksi 12,5782
dengan residual -5,4674), sedangkan residual positif muncul pada nilai
aktual yang besar (misalnya aktual 25,0771 diprediksi 20,4441 dengan
residual 4,6331). Artinya, model cenderung memprediksi nilai ekstrem
lebih dekat ke rata-rata, yaitu terlalu tinggi untuk y yang
kecil dan terlalu rendah untuk y yang besar. Karakteristik
ini umum pada Random Forest karena prediksi diperoleh dari
rata-rata banyak pohon.
importance.rf.reg <- sort(
rf.terbaik$variable.importance,
decreasing = TRUE
)
knitr::kable(
data.frame(Variabel = names(importance.rf.reg),
Importance = as.numeric(importance.rf.reg)),
digits = 4, align = "lc",
caption = "Tabel 9. Permutation Variable Importance Model Terbaik"
)| Variabel | Importance |
|---|---|
| X4 | 12.9314 |
| X1 | 9.3875 |
| X2 | 3.8211 |
| X3 | 1.8255 |
| X5 | 0.9720 |
| X6 | 0.1000 |
| X10 | 0.0976 |
| X8 | -0.0096 |
| X9 | -0.0802 |
| X7 | -0.1430 |
barplot(
importance.rf.reg,
las = 2,
main = paste(
"Variable Importance -",
model.terbaik
),
ylab = "Permutation Importance"
)Variabel dengan tingkat kepentingan tertinggi adalah X4
(12,9314), diikuti X1 (9,3875), X2 (3,8211),
X3 (1,8255), dan X5 (0,9720). Kelima variabel
tersebut adalah prediktor yang memang membentuk y pada data
Friedman, sehingga model berhasil mengenali variabel yang informatif.
X4 menempati urutan pertama karena memiliki pengaruh linear
terbesar terhadap y, sedangkan X1 dan
X2 penting karena keduanya membentuk satu suku interaksi.
X5 memperoleh nilai terkecil di antara kelima variabel
informatif karena koefisien pengaruhnya paling kecil.
Variabel noise (X6–X10) memiliki
nilai importance yang berada di sekitar nol, yaitu antara
-0,1430 dan 0,1000 (X6 = 0,1000; X10 = 0,0976;
X8 = -0,0096; X9 = -0,0802; X7 =
-0,1430). Nilai yang sangat kecil atau sedikit negatif berarti mengacak
variabel tersebut tidak menurunkan akurasi prediksi, sehingga
variabel-variabel ini tidak berkontribusi pada model. Jarak yang jelas
antara nilai importance variabel informatif (minimal 0,9720)
dan variabel noise (maksimal 0,1000) menunjukkan model dapat
memisahkan keduanya dengan baik.
Random Forest dan Double Random Forest merupakan metode ensemble berbasis decision tree yang digunakan untuk meningkatkan kemampuan prediksi dengan menggabungkan banyak pohon keputusan. Random Forest merupakan pengembangan dari Bagging yang menggunakan bootstrap sampling serta random feature selection pada setiap node untuk mengurangi korelasi antar-pohon dan variansi model. Sementara itu, Double Random Forest memiliki mekanisme yang berbeda karena setiap pohon dibangun menggunakan seluruh data latih, sedangkan proses bootstrap dilakukan pada setiap node untuk menentukan split terbaik. Dengan demikian, keduanya memiliki konsep ensemble yang sama, tetapi berbeda dalam mekanisme pembentukan pohonnya.
Random Forest dapat diimplementasikan untuk permasalahan klasifikasi
maupun regresi, begitu pula dengan Double Random Forest. Pada
klasifikasi, hasil prediksi akhir diperoleh melalui majority
voting, sedangkan pada regresi diperoleh melalui rata-rata prediksi
seluruh pohon. Implementasi kedua metode dilakukan dengan menentukan
parameter seperti num.trees, mtry, dan
min.node.size, serta mekanisme pengambilan sampel melalui
replace dan sample.fraction. Pengaturan
parameter tersebut disesuaikan dengan karakteristik permasalahan dan
jenis data yang dianalisis.
Evaluasi performa model dilakukan menggunakan ukuran yang disesuaikan
dengan jenis permasalahan. Pada klasifikasi digunakan Accuracy,
Precision, Recall, Specificity, F1-Score, dan ROC-AUC, sedangkan pada
regresi digunakan MSE, RMSE, MAE, dan R-Square. Selain itu,
Out-of-Bag (OOB) error dapat digunakan sebagai evaluasi
internal Random Forest karena prediksi OOB diperoleh dari pohon-pohon
yang tidak menggunakan observasi tersebut dalam proses pembentukan
pohon. Pada Random Forest Regression menggunakan paket
ranger, nilai prediction.error menunjukkan OOB
MSE. Ukuran evaluasi tersebut dapat digunakan untuk mengetahui kemampuan
prediksi model serta membandingkan performa Random Forest dan Double
Random Forest.
Berdasarkan hasil dan pembahasan pada data Friedman, sembilan model
Random Forest Regression yang merupakan kombinasi mtry = 2,
3, 5 dan num.trees = 200, 500, 1000 telah dibandingkan
berdasarkan performa data testing dan OOB MSE. Model terbaik adalah RF
5-1000 dengan mtry = 5 dan num.trees = 1000,
yang menghasilkan MSE sebesar 7,1925, RMSE sebesar 2,6819, MAE sebesar
2,2054, R-Square sebesar 0,6999, dan OOB MSE sebesar 6,8260. Residual
model secara umum berada di sekitar nol, sedangkan hasil variable
importance menunjukkan bahwa X4 merupakan variabel paling penting
dengan nilai importance sebesar 12,9314, diikuti X1, X2, X3, dan X5.
Sementara itu, X6–X10 memiliki nilai importance yang mendekati nol
sehingga menunjukkan kontribusi yang sangat kecil dalam prediksi
variabel respons.
Praktikan dapat melakukan pembelajaran lebih lanjut mengenai Random Forest dan Double Random Forest, serta membandingkan hasilnya. Dalam penulisan laporan praktikan juga diharapkan untuk selalu teliti dan memperhatikan tata cara penulisan yang baik.
Fransiska, H. (2026). Modul Praktikum Machine Learning dan Model Prediction. Universitas Bengkulu: Bengkulu.
Ignatenko, V., Surkov, A., & Koltcov, S. (2024). Random forests with parametric entropy-based information gains for classification and regression problems. PeerJ Computer Science, 10, e1775.
Khairunnisa, A., Notodiputro, K. A., & Sartono, B. (2024). A comparative study of random forest and double random forest models from view points of their interpretability. Scientific Journal of Informatics, 11(1), 195–206.