BAB I PENDAHULUAN

1.1 Latar Belakang Masalah

Perkembangan teknologi digital menyebabkan data yang dihasilkan semakin besar dan kompleks, sehingga dibutuhkan model prediksi yang tidak hanya akurat, tetapi juga stabil. Model prediksi tunggal, seperti pohon keputusan (decision tree), umumnya mudah dibangun tetapi rawan mengalami overfitting sehingga kemampuan generalisasinya terbatas (Ilmi dkk., 2025). Salah satu pendekatan untuk mengatasi keterbatasan tersebut adalah ensemble learning, yaitu pendekatan yang menggabungkan banyak model dasar (base learner) agar diperoleh model gabungan yang lebih akurat dan stabil (Fransiska, 2026).

Random Forest (RF) merupakan algoritma ensemble learning berbasis pohon yang membangun banyak pohon keputusan, kemudian menggabungkan prediksinya untuk meningkatkan akurasi dan mengurangi overfitting. RF merupakan pengembangan dari bagging (bootstrap aggregating) yang menambahkan pengacakan pada pemilihan prediktor di setiap node, sehingga pohon-pohon dalam forest tidak berkorelasi terlalu tinggi satu sama lain (Fransiska, 2026). Dengan kata lain, RF menerapkan teknik bagging sekaligus pemilihan fitur secara acak (random feature selection), dan dapat digunakan baik untuk kasus klasifikasi maupun regresi (Wicaksono dkk., 2024; Ilmi dkk., 2025). Selain RF, terdapat Double Random Forest (DRF) yang dikembangkan untuk situasi ketika RF masih mengalami underfitting karena pohon yang terbentuk belum cukup besar. Pada DRF, setiap pohon dibangun menggunakan seluruh data training, sedangkan bootstrap digunakan sementara pada setiap node untuk mencari aturan pemisahan (split) (Fransiska, 2026).

Berdasarkan hal tersebut, praktikum ini dilakukan untuk memahami RF dan DRF sebagai metode ensemble berbasis decision tree, mengimplementasikan RF untuk kasus regresi menggunakan R pada data Friedman dengan membandingkan nilai mtry dan num.trees, serta mengevaluasi kinerjanya menggunakan OOB error, MSE, RMSE, MAE, dan \(R^2\) (Fransiska, 2026)..

1.2 Rumusan Masalah

  1. Apa yang dimaksud dengan Random Forest dan Double Random Forest sebagai metode ensemble berbasis decision tree?
  2. Bagaimana cara mengimplementasikan Random Forest untuk klasifikasi dan regresi serta Double Random Forest untuk klasifikasi dan regresi?
  3. Bagaimana cara mengevaluasi performa model, memahami Out-of-Bag (OOB) error, dan membandingkan Random Forest dan Double Random Forest?

1.3 Tujuan Praktikum

  1. Mahasiswa dapat memahami Random Forest dan Double Random Forest sebagai metode ensemble berbasis decision tree.
  2. Mahasiswa dapat mengimplementasikan Random Forest untuk klasifikasi dan regresi, serta Double Random Forest untuk klasifikasi dan regresi.
  3. Mahasiswa dapat mengevaluasi performa model, memahami Out-of-Bag (OOB) error, dan membandingkan Random Forest dengan Double Random Forest.

1.4 Batasan Masalah

Adapun batasan masalah yang ditentukan pada penelitian ini, yaitu lakukan analisis Random Forest secara lengkap mulai dari persiapan data, pembentukan model, prediksi, evaluasi, visualisasi, dan interpretasi dengan menggunakan set.seed(234) agar hasil dapat direproduksi, 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, \(R^2\), residual plot, dan variable importance. Tampilkan pula OOB MSE sebagai evaluasi internal model.

BAB II TINJAUAN PUSTAKA

2.1 Dari Bagging ke Random Forest

Ensemble learning merupakan pendekatan yang menggabungkan beberapa model dasar agar diperoleh model gabungan dengan kemampuan prediksi yang lebih baik. Random Forest adalah algoritma ensemble learning berbasis tree yang membangun banyak decision tree dan menggabungkan prediksinya untuk meningkatkan akurasi dan mengurangi overfitting. Menurut James, Witten, Hastie, dan Tibshirani dalam An Introduction to Statistical Learning (ISL), Random Forest merupakan pengembangan dari metode bagging (Bootstrap Aggregating) yang menggunakan kumpulan pohon keputusan (decision trees) sebagai model dasar. Metode ini dirancang untuk mengurangi variansi model dan meningkatkan kemampuan generalisasi (Fransiska, 2026).

Seperti bagging, RF membentuk banyak pohon dari proses resampling kemudian menggabungkan hasil prediksinya. Perbedaannya, RF menambahkan pengacakan pada pemilihan prediktor di setiap node, sehingga pohon-pohon dalam forest tidak hanya dibangun dari sampel yang berbeda, tetapi juga tidak selalu mempertimbangkan prediktor yang sama ketika mencari split terbaik. Tujuan pengacakan prediktor adalah mengurangi korelasi antar-pohon, sebab apabila semua pohon terlalu mirip maka manfaat agregasi menjadi terbatas (Fransiska, 2026). RF juga dikembangkan dari metode Classification and Regression Tree (CART) dengan menerapkan bagging dan random feature selection (Wicaksono dkk., 2024). Perbedaan bagging dan RF dirangkum pada Tabel 1.

Tabel 1. Perbedaan Bagging dan Random Forest

Aspek Bagging Random Forest
Data tiap tree Umumnya sampel bootstrap Umumnya sampel bootstrap
Prediktor pada split Semua prediktor dapat dipertimbangkan Hanya mtry prediktor yang dipilih secara acak
Korelasi antar-tree Dapat relatif tinggi Ditekan 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 tree

2.2 Proses Random Forest

Misalkan tersedia data latih \(D = (x_i, y_i)\), \(i = 1, 2, \dots, n\) dan akan dibentuk \(B\) pohon. Secara sederhana, proses RF dilakukan sebagai berikut (Fransiska, 2026; Wicaksono dkk., 2024):

  1. Mengambil sampel bootstrap dari data latih untuk membentuk data bagi tree ke-\(b\).
  2. Pada setiap node, memilih mtry prediktor secara acak dari seluruh \(p\) prediktor.
  3. Menentukan split terbaik hanya dari mtry prediktor yang terpilih.
  4. Menumbuhkan decision tree hingga memenuhi aturan penghentian, misalnya minimum node size.
  5. Mengulangi proses sampai diperoleh \(B\) tree, kemudian menggabungkan prediksi seluruh tree.

Untuk regresi, hasil akhir diperoleh dengan merata-ratakan prediksi semua tree:

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

sedangkan untuk klasifikasi, hasil akhir diperoleh melalui majority voting:

\[ \hat{G}_{RF}(x) = \text{mode}\{G_1(x), G_2(x), \dots, G_B(x)\} \]

dengan \(T_b(x)\) merupakan prediksi tree ke-\(b\) dan \(B\) merupakan banyaknya pohon yang dibangun. RF merupakan metode parallel ensemble, sehingga setiap tree dapat dibentuk secara relatif independen, berbeda dari boosting yang bersifat sequential (Fransiska, 2026).

2.3 Out-of-Bag (OOB) Error

Pada bootstrap berukuran \(n\) yang diambil dengan pengembalian dari \(n\) observasi, sebagian observasi dapat terambil lebih dari sekali dan sebagian lainnya tidak terambil. Secara rata-rata, proporsi observasi unik yang masuk ke satu sampel bootstrap mendekati \(1 - e^{-1} \approx 0{,}632\), sehingga sekitar 36,8% observasi tidak digunakan untuk membentuk tree tertentu dan disebut Out-of-Bag (OOB) observations (Fransiska, 2026).

Untuk setiap observasi, prediksi OOB diperoleh hanya dari tree-tree yang tidak menggunakan observasi tersebut ketika dibentuk. Prediksi ini digunakan untuk menghitung OOB prediction error sebagai ukuran evaluasi internal RF (Fransiska, 2026). Pada kasus regresi, OOB error dinyatakan sebagai OOB Mean Squared Error (MSE):

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

dengan \(\hat{y}_i^{OOB}\) merupakan prediksi observasi ke-\(i\) yang diperoleh hanya dari tree yang tidak memuat observasi tersebut. Semakin rendah kesalahan OOB, semakin baik kinerja model (Hasna dkk., 2024; Ilmi dkk., 2025). Pada paket ranger, OOB error dihitung secara otomatis; untuk regresi, prediction.error menyatakan OOB MSE dan r.squared menyatakan \(R^2\) berbasis OOB (Fransiska, 2026).

2.4 Double Random Forest (DRF)

Double Random Forest (DRF) diperkenalkan oleh Han, Kim, dan Lee pada tahun 2020 untuk situasi ketika RF masih mengalami underfitting karena pohon yang dihasilkan belum cukup besar (Fransiska, 2026). Aldania dkk. (2023) juga menempatkan DRF sebagai pengembangan RF yang baik digunakan ketika model RF yang dihasilkan mengalami underfitting.

Pada RF standar, setiap pohon dibentuk menggunakan satu sampel bootstrap pada awal pohon yang hanya memuat sekitar 63,2% observasi unik. Pada DRF, setiap pohon dibangun menggunakan seluruh data training, sedangkan bootstrap digunakan sementara pada setiap node untuk mencari aturan split. Secara sederhana, proses DRF dilakukan sebagai berikut (Fransiska, 2026):

  1. Memulai setiap tree dengan seluruh data training, bukan satu sampel bootstrap untuk seluruh tree.
  2. Pada node yang sedang diproses, mengambil sampel bootstrap dari observasi yang mencapai node tersebut.
  3. Memilih mtry prediktor secara acak dan mencari split terbaik menggunakan sampel bootstrap pada node.
  4. Menerapkan split terbaik tersebut pada data asli yang mencapai node, kemudian mengirim observasi asli ke child nodes.
  5. Mengulangi proses sampai aturan penghentian tercapai untuk seluruh tree, lalu menggabungkan prediksi seluruh tree (majority voting untuk klasifikasi dan rata-rata untuk regresi).

Tabel 2. Perbedaan Random Forest dan Double Random Forest

Aspek Random Forest Double Random Forest
Penggunaan data Setiap pohon dibentuk dari data berbeda, yaitu hasil bootstrap pada data latih Setiap pohon dibentuk dari data yang sama, yaitu keseluruhan data latih
Jumlah observasi unik Sekitar \(1 - e^{-1} \approx 0{,}63\) kali data latih Seluruh data latih; bootstrap hanya sementara pada setiap node untuk mencari split
Proses pemisahan Random feature subset Bootstrap sampling pada setiap node dan random feature subset
Ukuran pohon Pohon lebih kecil dibandingkan DRF Cenderung menghasilkan pohon yang lebih besar dan beragam
Waktu komputasi Lebih cepat Lebih lama karena bootstrap diulang pada banyak node
Prediksi akhir Klasifikasi: majority voting; regresi: rata-rata Klasifikasi: majority voting; regresi: rata-rata

2.5 Parameter Penting dan Evaluasi Model

Tiga hyperparameter utama yang berpengaruh pada kinerja RF adalah ntree, mtry, dan nodesize. ntree menyatakan banyak pohon yang dibangun dalam ensemble, mtry menyatakan banyak variabel yang tersedia untuk dipecah pada setiap node sehingga menentukan keragaman antar pohon, sedangkan nodesize merupakan ukuran minimal node yang menjadi kriteria penghentian dan mengontrol kedalaman pohon (Ilmi dkk., 2025). Parameter tersebut beserta argumen pada fungsi ranger() dirangkum pada Tabel 3.

Tabel 3. Parameter Penting Random Forest dan DRF

Parameter Peran Argumen pada ranger()
Jumlah tree Menentukan jumlah tree yang dibentuk dalam ensemble num.trees
Jumlah prediktor kandidat Menentukan banyak prediktor kandidat yang dipilih secara acak pada setiap node mtry
Ukuran minimum node Mengatur ukuran minimum node dan secara tidak langsung kompleksitas tree min.node.size
Mekanisme sampling Mengatur mekanisme dan proporsi sampling replace, sample.fraction
Aturan split Menentukan aturan split, misalnya variance untuk regresi splitrule
Variable importance Menentukan apakah dan bagaimana variable importance dihitung importance

BAB III METODE PENELITIAN

3.1 Jenis dan Sumber Data

Jenis data yang digunakan dalam penelitian ini adalah data kuantitatif, yaitu data berbentuk angka yang dapat diolah dan dianalisis secara statistik. Sumber data yang digunakan merupakan data simulasi yang dibangkitkan melalui fungsi mlbench.friedman1() pada package mlbench dalam perangkat lunak R. Dataset ini terdiri dari 200 pengamatan dengan satu variabel respon (y) dan sepuluh variabel prediktor yang digunakan untuk membangun model prediksi menggunakan metode Random Forest Regression dengan mtry = 2, 3, dan 5 serta num.trees = 200, 500, dan 1000.

3.2 Variabel Penelitian

Tabel 4. Variabel Penelitian

No Variabel Keterangan Tipe Data Peran
1 y Variabel respon hasil simulasi Friedman, dibangkitkan dari fungsi \(10\sin(\pi x_1 x_2) + 20(x_3 - 0{,}5)^2 + 10x_4 + 5x_5 + \varepsilon\) Numerik Respon
2 x.1 Variabel prediktor ke-1, berdistribusi seragam pada interval [0, 1] Numerik Prediktor
3 x.2 Variabel prediktor ke-2, berdistribusi seragam pada interval [0, 1] Numerik Prediktor
4 x.3 Variabel prediktor ke-3, berdistribusi seragam pada interval [0, 1] Numerik Prediktor
5 x.4 Variabel prediktor ke-4, berdistribusi seragam pada interval [0, 1] Numerik Prediktor
6 x.5 Variabel prediktor ke-5, berdistribusi seragam pada interval [0, 1] Numerik Prediktor
7 x.6 Variabel prediktor ke-6, berdistribusi seragam pada interval [0, 1] dan tidak memengaruhi respon (noise) Numerik Prediktor
8 x.7 Variabel prediktor ke-7, berdistribusi seragam pada interval [0, 1] dan tidak memengaruhi respon (noise) Numerik Prediktor
9 x.8 Variabel prediktor ke-8, berdistribusi seragam pada interval [0, 1] dan tidak memengaruhi respon (noise) Numerik Prediktor
10 x.9 Variabel prediktor ke-9, berdistribusi seragam pada interval [0, 1] dan tidak memengaruhi respon (noise) Numerik Prediktor
11 x.10 Variabel prediktor ke-10, berdistribusi seragam pada interval [0, 1] dan tidak memengaruhi respon (noise) Numerik Prediktor

3.3 Langkah-langkah Analisis

  1. Memanggil package yang dibutuhkan, yaitu ranger untuk membangun model Random Forest, mlbench untuk membangkitkan data Friedman, caret untuk membagi data, dan knitr untuk menampilkan tabel.
  2. Membangkitkan data Friedman #1 sebanyak 200 pengamatan menggunakan fungsi mlbench.friedman1() yang diawali set.seed(234), kemudian mengubahnya menjadi data frame.
  3. Membagi data menjadi 70% data training dan 30% data testing menggunakan fungsi createDataPartition() dengan set.seed(234).
  4. Menentukan kombinasi mtry (2, 3, 5) dan num.trees (200, 500, 1000) sehingga terbentuk 9 model.
  5. Membangun model Random Forest Regression menggunakan fungsi ranger() dengan min.node.size = 5, replace = TRUE, sample.fraction = 1, dan importance = “permutation” pada setiap kombinasi.
  6. Menampilkan evaluasi internal berupa OOB MSE dan \(R^2\) OOB pada setiap model.
  7. Memprediksi nilai respon pada data testing menggunakan setiap model.
  8. Menghitung metrik evaluasi pada setiap model, yaitu MSE, RMSE, MAE, dan \(R^2\).
  9. Membandingkan hasil metrik evaluasi dari kesembilan model untuk menentukan model terbaik, yaitu model dengan nilai MSE, RMSE, dan MAE terkecil serta \(R^2\) terbesar.
  10. Membuat plot nilai aktual terhadap nilai prediksi dan plot residual.
  11. Menampilkan variable importance pada model terbaik.
  12. Menginterpretasikan hasil dan menarik kesimpulan.

3.4 Diagram Alir Penelitian

BAB IV Hasil dan Pembahasan

4.1 Persiapan Data

Tahap awal adalah memanggil package yang dibutuhkan, yaitu ranger untuk membangun model Random Forest, mlbench untuk membangkitkan data Friedman, caret untuk membagi data, dan knitr untuk menampilkan tabel. Kemudian data Friedman #1 dibangkitkan sebanyak 200 pengamatan dengan set.seed(234) agar hasil dapat direproduksi.

library(ranger)
library(mlbench)
library(caret)
library(knitr)

set.seed(234)
reg.data <- as.data.frame(mlbench.friedman1(200))

dim(reg.data)
## [1] 200  11
str(reg.data)
## '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 ...
head(reg.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
summary(reg.data$y)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   3.082  10.593  13.810  14.270  18.063  26.146

Interpretasi:

Berdasarkan hasil pemeriksaan data, data Friedman #1 terdiri atas 200 pengamatan dan 11 variabel, yaitu 10 variabel prediktor (x.1 hingga x.10) dan satu variabel respons (y). Seluruh variabel bertipe numerik sehingga dapat digunakan dalam analisis regresi Random Forest.

Hasil ringkasan variabel respons menunjukkan nilai minimum sebesar 3,082, kuartil pertama sebesar 10,593, median sebesar 13,810, rata-rata sebesar 14,270, kuartil ketiga sebesar 18,063, dan nilai maksimum sebesar 26,146. Nilai rata-rata yang sedikit lebih besar daripada median menunjukkan bahwa distribusi variabel respons cenderung sedikit menceng ke kanan.

4.2 Pembagian Data Training dan Testing

Kemudian data dibagi menjadi 70% data training dan 30% data testing menggunakan fungsi createDataPartition() dengan set.seed(234). Karena variabel respon berupa data numerik, pembagian dilakukan berdasarkan kelompok nilai respon sehingga sebaran y pada kedua data relatif serupa.

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
dim(reg.test)
## [1] 60 11

Interpretasi:

Berdasarkan hasil pembagian data, sebanyak 200 pengamatan dibagi menjadi 140 pengamatan data training dan 60 pengamatan data testing. Data training mencakup 70% dari keseluruhan data, sedangkan data testing mencakup 30%. Masing-masing kelompok terdiri atas 11 variabel, yaitu 10 variabel prediktor dan satu variabel respons. Data training digunakan untuk membangun model regresi Random Forest, sedangkan data testing digunakan untuk mengukur kemampuan model dalam memprediksi data yang belum pernah digunakan selama proses pelatihan.

4.3 Pembentukan Model Random Forest Regression

Model Random Forest Regression dibangun dengan fungsi ranger(). Model dibuat untuk setiap kombinasi mtry = 2, 3, dan 5 dengan num.trees = 200, 500, dan 1000, sehingga diperoleh 9 model. Parameter lainnya dibuat sama pada seluruh model, yaitu min.node.size = 5, replace = TRUE, sample.fraction = 1, dan importance = “permutation”. Fungsi set.seed(234) dan argumen seed = 234 digunakan agar hasil dapat direproduksi.

mtry_set  <- c(2, 3, 5)
ntree_set <- c(200, 500, 1000)

grid       <- expand.grid(num.trees = ntree_set, mtry = mtry_set)
grid$Model <- paste0("mtry=", grid$mtry, ", ntree=", grid$num.trees)

rf_list        <- vector("list", nrow(grid))
names(rf_list) <- grid$Model

for (i in seq_len(nrow(grid))) {
  set.seed(234)
  rf_list[[i]] <- ranger(
    y ~ ., data = reg.train,
    num.trees       = grid$num.trees[i],
    mtry            = grid$mtry[i],
    min.node.size   = 5,
    replace         = TRUE,
    sample.fraction = 1,
    importance      = "permutation",
    seed            = 234
  )
}

# Contoh keluaran salah satu model (mtry = 3, num.trees = 500)
rf_list[["mtry=3, ntree=500"]]
## Ranger result
## 
## Call:
##  ranger(y ~ ., data = reg.train, num.trees = grid$num.trees[i],      mtry = grid$mtry[i], min.node.size = 5, replace = TRUE, sample.fraction = 1,      importance = "permutation", seed = 234) 
## 
## Type:                             Regression 
## Number of trees:                  500 
## Sample size:                      140 
## Number of independent variables:  10 
## Mtry:                             3 
## Target node size:                 5 
## Variable importance mode:         permutation 
## Splitrule:                        variance 
## OOB prediction error (MSE):       7.442423 
## R squared (OOB):                  0.7198089

Interpretasi:

Berdasarkan hasil pemodelan menggunakan fungsi ranger(), dibentuk 9 model Random Forest Regression dari kombinasi tiga nilai mtry dan tiga nilai num.trees. Setiap pohon dibangun dari sampel bootstrap (replace = TRUE dan sample.fraction = 1) dengan ukuran node minimum 5, dan pada setiap node hanya mtry prediktor yang dipilih secara acak sebagai kandidat split. Keluaran model pada contoh di atas memuat jenis pohon (Regression), jumlah pohon, ukuran sampel, jumlah variabel independen, nilai mtry, ukuran node target, serta evaluasi internal berupa OOB prediction error (MSE) dan \(R^2\).

4.4 Evaluasi Internal: OOB MSE

Evaluasi internal model dilakukan menggunakan Out-of-Bag (OOB) error yang dihitung otomatis oleh ranger. Pada regresi, prediction.error menyatakan OOB MSE dan r.squared menyatakan \(R^2\) berbasis OOB. Evaluasi ini tidak memerlukan data testing karena menggunakan observasi yang tidak ikut membentuk suatu pohon.

oob_df <- data.frame(
  Model     = grid$Model,
  mtry      = grid$mtry,
  num.trees = grid$num.trees,
  OOB_MSE   = sapply(rf_list, function(m) m$prediction.error),
  OOB_R2    = sapply(rf_list, function(m) m$r.squared),
  row.names = NULL
)

kable(oob_df, digits = 4, align = "c",
      format.args = list(decimal.mark = ","),
      caption = "Tabel 5. OOB MSE dan R-Square OOB pada Setiap Kombinasi mtry dan num.trees")
Tabel 5. OOB MSE dan R-Square OOB pada Setiap Kombinasi mtry dan num.trees
Model mtry num.trees OOB_MSE OOB_R2
mtry=2, ntree=200 2 200 8,2222 0,6905
mtry=2, ntree=500 2 500 8,1267 0,6940
mtry=2, ntree=1000 2 1000 8,0553 0,6967
mtry=3, ntree=200 3 200 7,7097 0,7097
mtry=3, ntree=500 3 500 7,4424 0,7198
mtry=3, ntree=1000 3 1000 7,3547 0,7231
mtry=5, ntree=200 5 200 7,0632 0,7341
mtry=5, ntree=500 5 500 6,8750 0,7412
mtry=5, ntree=1000 5 1000 6,8260 0,7430

Interpretasi:

Berdasarkan Tabel 5, nilai OOB MSE terkecil sebesar 6,8260 diperoleh pada model mtry=5, ntree=1000 dengan \(R^2\) OOB sebesar 0,7430, sedangkan OOB MSE terbesar sebesar 8,2222 diperoleh pada model mtry=2, ntree=200. Selisih antara OOB MSE terbesar dan terkecil adalah 1,3962 (sekitar 20,5% dari OOB MSE terkecil), sehingga perbedaan kombinasi parameter memberikan perbedaan kinerja internal yang cukup terlihat. Jika dirata-ratakan, OOB MSE terkecil diperoleh pada mtry = 5 dan pada num.trees = 1000. Semakin rendah OOB MSE, semakin baik kinerja internal model.

cols <- c("steelblue", "darkorange", "forestgreen")

plot(NULL, xlim = range(ntree_set), ylim = range(oob_df$OOB_MSE),
     xlab = "Jumlah pohon (num.trees)", ylab = "OOB MSE", xaxt = "n",
     main = "OOB MSE menurut mtry dan num.trees")
axis(1, at = ntree_set)
for (j in seq_along(mtry_set)) {
  d <- oob_df[oob_df$mtry == mtry_set[j], ]
  lines(d$num.trees, d$OOB_MSE, type = "b", pch = 19, lwd = 2, col = cols[j])
}
legend("topright", legend = paste("mtry =", mtry_set),
       col = cols, lty = 1, pch = 19, lwd = 2, cex = 0.8)

Interpretasi:

Plot di atas memperlihatkan perubahan OOB MSE terhadap jumlah pohon pada masing-masing nilai mtry. Pada umumnya, penambahan jumlah pohon membuat kurva semakin mendatar karena prediksi rata-rata dari semakin banyak pohon menjadi lebih stabil, sedangkan perbedaan antar garis menunjukkan pengaruh nilai mtry terhadap galat internal model.

4.5 Hasil Prediksi

Setiap model digunakan untuk memprediksi nilai respon pada data testing dengan fungsi predict(), lalu hasilnya dibandingkan dengan nilai aktual.

actual <- reg.test$y

pred_list <- lapply(rf_list, function(m) predict(m, data = reg.test)$predictions)

hasil_pred <- data.frame(
  Aktual     = actual,
  Pred_mtry2 = pred_list[["mtry=2, ntree=500"]],
  Pred_mtry3 = pred_list[["mtry=3, ntree=500"]],
  Pred_mtry5 = pred_list[["mtry=5, ntree=500"]]
)

kable(head(hasil_pred, 10), digits = 3, align = "c",
      format.args = list(decimal.mark = ","),
      caption = "Tabel 6. Perbandingan Nilai Aktual dan Prediksi (10 Pengamatan Pertama, num.trees = 500)")
Tabel 6. Perbandingan Nilai Aktual dan Prediksi (10 Pengamatan Pertama, num.trees = 500)
Aktual Pred_mtry2 Pred_mtry3 Pred_mtry5
10,232 12,875 12,455 12,413
11,845 10,866 10,618 10,345
10,336 13,115 13,229 12,773
16,727 13,981 13,368 13,614
25,077 18,842 19,528 20,427
15,447 14,133 14,255 14,504
15,643 13,308 12,625 12,844
7,111 12,420 12,824 12,853
13,351 15,379 15,389 15,482
12,872 14,394 14,621 14,807

Interpretasi:

Berdasarkan Tabel 6, nilai prediksi dari ketiga model pada umumnya mengikuti nilai aktual, tetapi ketepatannya berbeda pada setiap pengamatan. Pada 10 pengamatan pertama dengan num.trees = 500, rata-rata selisih absolut antara nilai aktual dan prediksi adalah 2,789 untuk mtry = 2, 2,896 untuk mtry = 3, dan 2,743 untuk mtry = 5. Selisih terbesar terjadi pada pengamatan ke-8 dengan nilai aktual 7,111, sedangkan prediksi ketiga model berkisar antara 12,420 sampai 12,853. Karena perbandingan pada 10 pengamatan belum mewakili seluruh data, kinerja yang lebih tepat perlu dilihat dari metrik evaluasi pada seluruh data testing.

4.6 Metrik Evaluasi

Kinerja model dievaluasi dengan MSE, RMSE, MAE, dan R-Square yang dihitung dari nilai aktual dan prediksi pada seluruh data testing. Nilai OOB MSE dari Tabel 5 ditampilkan kembali sebagai pembanding.

hitung_metrik <- function(actual, pred) {
  MSE  <- mean((actual - pred)^2)
  RMSE <- sqrt(MSE)
  MAE  <- mean(abs(actual - pred))
  R2   <- 1 - sum((actual - pred)^2) / sum((actual - mean(actual))^2)
  c(MSE = MSE, RMSE = RMSE, MAE = MAE, R2 = R2)
}

metrik    <- t(sapply(pred_list, function(p) hitung_metrik(actual, p)))
metrik_df <- data.frame(Model     = grid$Model,
                        mtry      = grid$mtry,
                        num.trees = grid$num.trees,
                        OOB_MSE   = oob_df$OOB_MSE,
                        metrik, row.names = NULL)

kable(metrik_df, digits = 4, align = "c",
      format.args = list(decimal.mark = ","),
      caption = "Tabel 7. Perbandingan Metrik Evaluasi Random Forest Regression pada Data Testing")
Tabel 7. Perbandingan Metrik Evaluasi Random Forest Regression pada Data Testing
Model mtry num.trees OOB_MSE MSE RMSE MAE R2
mtry=2, ntree=200 2 200 8,2222 7,8700 2,8054 2,3414 0,6717
mtry=2, ntree=500 2 500 8,1267 8,1774 2,8596 2,3832 0,6589
mtry=2, ntree=1000 2 1000 8,0553 8,1181 2,8492 2,3794 0,6613
mtry=3, ntree=200 3 200 7,7097 7,8139 2,7953 2,2981 0,6740
mtry=3, ntree=500 3 500 7,4424 7,8278 2,7978 2,3058 0,6734
mtry=3, ntree=1000 3 1000 7,3547 7,7780 2,7889 2,2996 0,6755
mtry=5, ntree=200 5 200 7,0632 7,6596 2,7676 2,2726 0,6805
mtry=5, ntree=500 5 500 6,8750 7,3826 2,7171 2,2312 0,6920
mtry=5, ntree=1000 5 1000 6,8260 7,1925 2,6819 2,2054 0,6999

Interpretasi:

Berdasarkan Tabel 7, nilai MSE terkecil pada data testing diperoleh pada model mtry=5, ntree=1000, yaitu 7,1925 dengan RMSE 2,6819 dan MAE 2,2054. Nilai R-Square terbesar sebesar 0,6999 diperoleh pada model mtry=5, ntree=1000, artinya model mampu menjelaskan sekitar 69,99% keragaman nilai respon pada data testing. Keempat metrik menunjukkan model terbaik yang sama, sehingga pemilihan model terbaik konsisten. Selisih MSE antara model terbaik dan terburuk adalah 0,9849 (sekitar 13,7% dari MSE terkecil), sehingga perbedaan kombinasi mtry dan num.trees memberikan perbedaan kinerja yang cukup terlihat.

Jika dirata-ratakan, MSE terkecil berdasarkan mtry diperoleh pada mtry = 5, sedangkan berdasarkan jumlah pohon diperoleh pada num.trees = 1000. Sebagai pembanding, galat acak pada data Friedman #1 memiliki varians sekitar 1, sehingga MSE terbaik berada sekitar 7,19 kali di atas batas tersebut. Berdasarkan evaluasi internal, model terbaik menurut OOB MSE adalah mtry=5, ntree=1000, yang sama dengan model terbaik pada data testing, sehingga evaluasi internal (OOB) konsisten dengan hasil pengujian.

plot(NULL, xlim = range(ntree_set), ylim = range(metrik_df$MSE),
     xlab = "Jumlah pohon (num.trees)", ylab = "MSE data testing", xaxt = "n",
     main = "MSE Data Testing menurut mtry dan num.trees")
axis(1, at = ntree_set)
for (j in seq_along(mtry_set)) {
  d <- metrik_df[metrik_df$mtry == mtry_set[j], ]
  lines(d$num.trees, d$MSE, type = "b", pch = 19, lwd = 2, col = cols[j])
}
legend("topright", legend = paste("mtry =", mtry_set),
       col = cols, lty = 1, pch = 19, lwd = 2, cex = 0.8)

4.7 Plot Nilai Aktual dan Prediksi

Plot dibuat untuk melihat kesesuaian nilai prediksi terhadap nilai aktual pada setiap kombinasi mtry dan num.trees. Baris pertama hingga ketiga berturut-turut menunjukkan mtry = 2, 3, dan 5, sedangkan kolom pertama hingga ketiga menunjukkan num.trees = 200, 500, dan 1000. Garis merah putus-putus menunjukkan kondisi ideal, yaitu nilai prediksi sama dengan nilai aktual.

par(mfrow = c(3, 3), mar = c(4, 4, 3, 1))
for (i in seq_along(pred_list)) {
  plot(actual, pred_list[[i]], pch = 19, col = "steelblue",
       xlab = "Nilai Aktual", ylab = "Nilai Prediksi",
       main = grid$Model[i], cex.main = 0.95)
  abline(a = 0, b = 1, lty = 2, lwd = 2, col = "red")
}

par(mfrow = c(1, 1))

Interpretasi:

Pada kesembilan plot, titik-titik menyebar mengikuti garis diagonal, yang menunjukkan bahwa model mampu menangkap pola data Friedman. Korelasi antara nilai aktual dan prediksi berkisar antara 0,8445 sampai 0,8946, dengan korelasi terbesar pada model mtry=2, ntree=200. Pada model terbaik, kemiringan hubungan prediksi terhadap nilai aktual sebesar 0,578, yang berarti prediksi cenderung tertarik ke nilai tengah sehingga nilai aktual yang ekstrem sulit ditangkap sepenuhnya. Hal ini wajar pada RF karena prediksi merupakan rata-rata dari banyak pohon.

4.8 Plot Residual

Plot residual dibuat untuk memeriksa selisih antara nilai aktual dan prediksi terhadap nilai prediksi. Residual yang baik tersebar acak di sekitar nol tanpa pola tertentu.

par(mfrow = c(3, 3), mar = c(4, 4, 3, 1))
for (i in seq_along(pred_list)) {
  res <- actual - pred_list[[i]]
  plot(pred_list[[i]], res, pch = 19, col = "steelblue",
       xlab = "Nilai Prediksi", ylab = "Residual",
       main = grid$Model[i], cex.main = 0.95)
  abline(h = 0, lty = 2, lwd = 2, col = "red")
}

par(mfrow = c(1, 1))

Interpretasi:

Pada model terbaik (mtry=5, ntree=1000), rata-rata residual sebesar -0,2726 dengan simpangan baku 2,6905. Rata-rata residual yang dekat dengan nol menunjukkan bahwa model tidak cenderung memprediksi terlalu tinggi atau terlalu rendah secara sistematis. Residual terbesar bernilai -5,761, yaitu selisih terjauh antara nilai aktual dan prediksi pada data testing. Sebaran residual pada kesembilan plot perlu dicermati secara visual, karena sebaran acak di sekitar garis nol menunjukkan model telah menangkap pola yang ada, sedangkan pola melengkung atau melebar menunjukkan masih ada struktur yang belum tertangkap.

4.9 Variable Importance

Variable importance pada model terbaik dihitung menggunakan importance = "permutation" pada ranger, yaitu penurunan kinerja prediksi OOB ketika nilai suatu variabel diacak. Semakin besar nilainya, semakin besar kontribusi variabel tersebut terhadap prediksi.

info_vars  <- paste0("x.", 1:5)
noise_vars <- paste0("x.", 6:10)

imp_best <- sort(rf_list[[best_idx]]$variable.importance, decreasing = TRUE)

imp_df <- data.frame(
  Variabel   = names(imp_best),
  Importance = as.numeric(imp_best),
  Jenis      = ifelse(names(imp_best) %in% info_vars, "Informatif", "Noise"),
  row.names  = NULL
)

kable(imp_df, digits = 4, align = "c",
      format.args = list(decimal.mark = ","),
      caption = "Tabel 8. Permutation Importance Variabel pada Model Terbaik")
Tabel 8. Permutation Importance Variabel pada Model Terbaik
Variabel Importance Jenis
x.4 12,9314 Informatif
x.1 9,3875 Informatif
x.2 3,8211 Informatif
x.3 1,8255 Informatif
x.5 0,9720 Informatif
x.6 0,1000 Noise
x.10 0,0976 Noise
x.8 -0,0096 Noise
x.9 -0,0802 Noise
x.7 -0,1430 Noise
barplot(imp_best, las = 2,
        col = ifelse(names(imp_best) %in% info_vars, "steelblue", "grey70"),
        ylab = "Permutation Importance",
        main = paste("Variable Importance - Random Forest Regression\n(", best_lab, ")"))
legend("topright", legend = c("Informatif (x.1-x.5)", "Noise (x.6-x.10)"),
       fill = c("steelblue", "grey70"), cex = 0.8)

Interpretasi:

Berdasarkan Tabel 8, variabel yang paling berpengaruh adalah x.4 dengan nilai importance sebesar 12,9314, diikuti oleh x.1 sebesar 9,3875 dan x.2 sebesar 3,8211. Pada data Friedman #1, hanya variabel x.1 sampai x.5 yang benar-benar membentuk respon, sedangkan x.6 sampai x.10 merupakan noise. Rata-rata nilai importance variabel x.1 sampai x.5 sebesar 5,7875, sedangkan rata-rata variabel noise hanya -0,0071. Lima variabel dengan importance tertinggi pada model terbaik tepat sama dengan variabel informatif (x.1 sampai x.5), dan pola yang sama juga ditemukan pada seluruh sembilan model. Hal ini menunjukkan bahwa Random Forest berhasil membedakan variabel yang informatif dari variabel noise.

5.1 Kesimpulan

Random Forest (RF) adalah metode ensemble learning berbasis decision tree yang membangun banyak pohon dari sampel bootstrap dan memilih sejumlah mtry prediktor secara acak pada setiap node. Dengan cara ini pohon-pohon yang terbentuk tidak terlalu berkorelasi, sehingga variansi model berkurang dan kemampuan generalisasi meningkat. Prediksi akhir diperoleh melalui majority voting pada klasifikasi dan rata-rata prediksi seluruh pohon pada regresi. Double Random Forest (DRF) merupakan pengembangan RF yang dirancang untuk kondisi ketika RF mengalami underfitting. Setiap pohon DRF dibangun dari seluruh data training, sedangkan bootstrap hanya digunakan sementara pada setiap node untuk mencari aturan split. Akibatnya DRF cenderung menghasilkan pohon yang lebih besar dan beragam, dengan waktu komputasi yang lebih lama dibandingkan RF.

RF dan DRF dapat diimplementasikan menggunakan R untuk kasus klasifikasi maupun regresi dengan tahapan yang sama, yaitu persiapan data, pembagian data training dan testing, pembentukan model, prediksi, evaluasi, dan interpretasi. RF diimplementasikan menggunakan paket ranger dengan parameter penting seperti num.trees, mtry, dan min.node.size, sedangkan DRF dijalankan menggunakan sintaks khusus yang disediakan pada modul. Pada klasifikasi, kinerja model dievaluasi menggunakan confusion matrix beserta Accuracy, Precision, Recall, Specificity, dan F1-score, sedangkan pada regresi menggunakan MSE, RMSE, MAE, dan \(R^2\).

Performa model dievaluasi secara internal melalui Out-of-Bag (OOB) error dan secara eksternal melalui data testing. OOB error dihitung dari observasi yang tidak ikut membentuk suatu pohon (sekitar 36,8% data), sehingga dapat menjadi ukuran kinerja tanpa memerlukan data testing. Pada klasifikasi OOB error berupa proporsi salah klasifikasi, sedangkan pada regresi berupa OOB MSE, dan semakin kecil nilainya semakin baik model. Jika dibandingkan, RF lebih cepat secara komputasi, sedangkan DRF lebih sesuai ketika RF menghasilkan pohon yang terlalu kecil dan model masih underfitting, dengan konsekuensi waktu komputasi yang lebih besar. Pemilihan model terbaik sebaiknya mempertimbangkan hasil evaluasi pada data testing dan OOB error secara bersama-sama.

Berdasarkan hasil analisis Random Forest Regression pada data Friedman #1, diperoleh sembilan model dari kombinasi mtry = 2, 3, dan 5 dengan num.trees = 200, 500, dan 1000. Berdasarkan evaluasi internal, OOB MSE terkecil sebesar 6,8260 diperoleh pada model mtry=5, ntree=1000. Berdasarkan data testing, model terbaik adalah mtry=5, ntree=1000 dengan MSE sebesar 7,1925, RMSE sebesar 2,6819, MAE sebesar 2,2054, dan \(R^2\) sebesar 0,6999. Analisis variable importance menunjukkan bahwa variabel x.4, x.1, dan x.2 memberikan kontribusi terbesar, sedangkan variabel x.1 hingga x.5 merupakan variabel informatif yang membentuk respons dan x.6 hingga x.10 merupakan variabel noise. Dengan demikian, Random Forest Regression dapat digunakan untuk memodelkan hubungan nonlinier antara prediktor dan respons serta mengidentifikasi kontribusi variabel prediktor. Pemilihan model terbaik perlu mempertimbangkan hasil evaluasi pada data testing dan OOB error secara bersama-sama, bukan hanya salah satunya.

5.2 Saran

Pada praktikum Machine Learning berikutnya, disarankan agar praktikan lebih teliti dalam memasukkan dan mengolah data menggunakan RStudio, terutama dalam penggunaan sintaks serta interpretasi Random Forest. Selain itu, pemilihan nilai mtry, num.trees, dan min.node.size perlu diperhatikan agar model tidak mengalami underfitting maupun overfitting dan waktu komputasi tetap wajar. Untuk penelitian selanjutnya, perbandingan dapat diperluas dengan mencoba nilai min.node.size yang berbeda, menerapkan Double Random Forest pada data yang sama untuk membandingkan kinerja dan waktu komputasinya dengan RF, serta membandingkan hasilnya dengan metode ensemble lain seperti bagging atau boosting.

DAFTAR PUSTAKA

Aldania, A. N. A., Soleh, A. M., & Notodiputro, K. A. (2023). A comparative study of CatBoost and double random forest for multi-class classification. Jurnal RESTI (Rekayasa Sistem dan Teknologi Informasi), 7(1), 129–137.

Fransiska, H. (2026). Modul Praktikum Machine Learning. Universitas Bengkulu.

Hasna, H., Amalita, N., Permana, D., & Salma, A. (2024). Random forest implementation for air pollution standard index classification in DKI Jakarta 2022. UNP Journal of Statistics and Data Science, 2(2), 226–233.

Ilmi, I. N., Mustafid, & Suparti. (2025). Penerapan model regresi random forest untuk prediksi harga laptop berdasarkan fitur laptop. Jurnal Gaussian, 14(2), 269–279.

Wicaksono, A. S., Godjali, M. R., Indriyany, I. A., Budiaji, W., & Ikhsan, A. (2024). Pemodelan klasifikasi preferensi ideologi partai politik pada pemilih pemula di Provinsi Banten. Jurnal Gaussian, 13(2), 421–430.