BAB I PENDAHULUAN

1.1 Latar Belakang

Perkembangan teknologi informasi mendorong penggunaan metode Machine Learning untuk mengolah data dan menghasilkan prediksi. Salah satu metode yang banyak digunakan adalah ensemble learning, yaitu teknik yang menggabungkan beberapa model untuk meningkatkan kinerja prediksi. Random Forest merupakan metode Ensemble berbasis decision tree yang menggunakan pengambilan sampel secara bootstrap dan pemilihan fitur secara acak. Metode ini dapat digunakan untuk klasifikasi, dengan menentukan kelas berdasarkan suara terbanyak, serta regresi, dengan menghitung rata-rata hasil prediksi pohon (Darwanto, Viarindita dan Widyaningsih, 2021).

Pengembangan dari Random Forest adalah Double Random Forest (DRF), yang digunakan untuk mengatasi permasalahan underfitting yang dapat terjadi ketika pohon keputusan yang terbentuk terlalu kecil. DRF memungkinkan pembentukan pohon yang lebih besar sehingga berpotensi meningkatkan kemampuan model dalam menangkap pola data (Khairunnisa, Notodiputro dan Sartono, 2024).

Penerapan Random Forest dan Double Random Forest tidak hanya dari segi konsep, tetapi juga melalui implementasi pada permasalahan klasifikasi dan regresi. Klasifikasi digunakan ketika variabel respons berupa kategori, seperti status kemiskinan atau status kelulusan, sedangkan regresi digunakan ketika variabel respons berupa nilai numerik, seperti jumlah kasus atau besaran pendapatan (Purwanto, Sartono dan Notodiputro, 2025).

Evaluasi kinerja diperlukan untuk mengetahui kemampuan model dalam menghasilkan prediksi yang baik. Pada klasifikasi, evaluasi dapat menggunakan akurasi, presisi, recall, spesifisitas dan F1-score, sedangkan pada regresi dapat menggunakan Mean Absolute Error (MAE), Mean Squared Error (MSE) dan Root Mean Squared Error (RMSE). Selain itu, Random Forest memiliki ukuran evaluasi internal berupa Out-of-Bag (OOB) error, yaitu kesalahan prediksi berdasarkan pengamatan yang tidak digunakan dalam sampel bootstrap suatu pohon (Fadli dan Saputra, 2023).

1.2 Rumusan Masalah

Berdasarkan latar belakang tersebut, rumusan masalah dalam praktikum ini adalah sebagai berikut:

  1. Bagaimana cara memahami 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 dengan Double Random Forest?

1.3 Tujuan Penelitian

Tujuan yang ingin dicapai dalam praktikum ini adalah sebagai berikut:

  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.

BAB II TINJAUAN PUSTAKA

2.1 Random Forest

Random Forest adalah algoritma ensemble learning berbasis tree yang membangun banyak decision tree dan menggabungkan prediksinya untuk meningkatkan akurasi dan mengurangi overfitting. Metode ini dirancang untuk mengurangi variansi model dan meningkatkan kemampuan generalisasi. Seperti bagging, Random Forest membentuk banyak pohon melalui proses resampling dan kemudian menggabungkan hasil prediksinya. Perbedaannya, Random Forest menambahkan pengacakan pada 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. Tujuan pengacakan prediktor adalah mengurangi korelasi antar-pohon. Apabila semua pohon terlalu mirip, manfaat agregasi menjadi terbatas. Dengan membuat pohon yang kuat tetapi tidak terlalu berkorelasi, Random Forest dapat mengurangi variance tanpa harus memangkas setiap pohon secara agresif (Fransiska, 2026).

2.2 Double Random Forest

Double Random Forest (DRF) adalah metode yang diperkenalkan oleh Han, Kim, dan Lee pada tahun 2020. DRF dikembangkan untuk situasi ketika Random Forest masih mengalami underfitting karena tree yang dihasilkan belum cukup besar. Pada Random Forest standar, setiap tree dibentuk menggunakan satu bootstrap sample pada awal tree. Karena satu bootstrap sample hanya mengandung sekitar 63,2% observasi unik, jumlah observasi unik yang tersedia untuk membentuk tree lebih sedikit daripada seluruh data training. Setiap tree DRF dibangun menggunakan seluruh data training, sedangkan bootstrap digunakan sementara pada setiap node untuk mencari aturan split (Fransiska, 2026).

2.3 Implementasi Random Forest dan Double Random Forest

2.3.1 Klasifikasi

Klasifikasi merupakan proses pengelompokan observasi ke dalam kategori berdasarkan variabel prediktor. Pada metode Random Forest, setiap pohon keputusan menghasilkan prediksi kelas, kemudian prediksi akhir ditentukan berdasarkan suara terbanyak (majority voting). Sementara itu, Double Random Forest (DRF) merupakan pengembangan Random Forest yang dirancang untuk mengatasi kondisi underfitting (Aldania, Soleh dan Notodiputro, 2023).

2.3.2 Regresi

Regresi merupakan metode untuk memprediksi variabel respons berbentuk numerik berdasarkan variabel prediktor. Pada Random Forest Regression, prediksi akhir diperoleh melalui rata-rata prediksi seluruh pohon yang terbentuk. Adapun penerapan DRF untuk regresi memerlukan implementasi yang secara khusus mendukung respons numerik. Oleh karena itu, penggunaan DRF untuk regresi perlu memperhatikan algoritma dan perangkat lunak yang digunakan (Aldania, Soleh dan Notodiputro, 2023).

BAB III METODE PENELITIAN

3.1 Jenis dan Sumber Data

Jenis data yang digunakan dalam praktikum ini adalah data kategorik. Data kategorik adalah tipe data yang merepresentasikan karakteristik atau atribut dari objek yang diklasifikasikan ke dalam kategori tertentu. Sumber data yang digunakan merupakan data sekunder, yaitu data yang telah tersedia dan diperoleh melalui sumber yang sudah ada. Data yang digunakan adalah dataset BreastCancer dari package mlbench pada program R.

3.2 Variabel Penelitian

Variabel penelitian adalah segala sesuatu yang menjadi objek pengamatan dalam suatu penelitian. Variabel penelitian yang digunakan berasal dari dataset BreastCancer dengan jumlah 699 observasi dan 11 variabel. Variabel Class digunakan sebagai variabel respons dengan kategori benign dan malignant, sedangkan sembilan variabel prediktor yang digunakan adalah Clump Thickness, Uniformity of Cell Size, Uniformity of Cell Shape, Marginal Adhesion, Single Epithelial Cell Size, Bare Nuclei, Bland Chromatin, Normal Nucleoli dan Mitoses. Variabel Sample code number tidak digunakan dalam pemodelan karena hanya berfungsi sebagai identitas sampel.

3.3 Langkah-langkah Analisis

Langkah-langkah analisis data pada penelitian ini adalah sebagai berikut:

  1. Menyiapkan data yang akan dianalisis.

  2. Melakukan prapemrosesan data dengan menghapus pengamatan yang memiliki nilai hilang serta mengeluarkan variabel Id yang tidak digunakan dalam pemodelan.

  3. Membagi data menjadi data latih sebesar 80% dan data uji sebesar 20% menggunakan stratified sampling berdasarkan variabel target Class.

  4. Membentuk sembilan model Random Forest menggunakan kombinasi parameter mtry = 2, 3, 5 dan ntree = 200, 500, 1000.

  5. Mengevaluasi setiap model berdasarkan nilai Out-of-Bag (OOB) error untuk mengetahui tingkat kesalahan klasifikasi internal.

  6. Melakukan prediksi terhadap data uji menggunakan seluruh model yang telah dibentuk.

  7. Menyusun confusion matrix untuk membandingkan hasil prediksi dengan kelas aktual pada data uji.

  8. Menghitung metrik evaluasi yang meliputi accuracy, precision, recall, specificity dan F1-score.

  9. Membandingkan kinerja sembilan model berdasarkan metrik evaluasi dan OOB error untuk menentukan model dengan kinerja terbaik.

  10. Menganalisis variable importance untuk mengidentifikasi variabel yang paling berpengaruh dalam proses klasifikasi.

  11. Membuat dan menginterpretasikan grafik perkembangan OOB error untuk mengamati perubahan tingkat kesalahan seiring bertambahnya jumlah pohon.

  12. Menarik kesimpulan berdasarkan hasil evaluasi model, variabel yang paling berpengaruh, dan kestabilan kinerja Random Forest.

BAB IV HASIL DAN PEMBAHASAN

4.1 Import Data dan Handling Misssing Value

Memanggil Package

Package yang digunakan adalah mlbench, randomForest, ggplot2 dan knitr. Package mlbench menyediakan dataset BreastCancer, randomForest digunakan untuk membangun model Random Forest, ggplot2 digunakan untuk visualisasi hasil analisis dan knitr digunakan untuk menampilkan hasil evaluasi dalam bentuk tabel.

# Memanggil paket yang digunakan
library(mlbench)       # Dataset BreastCancer
library(randomForest)  # Algoritma Random Forest
## randomForest 4.7-1.2
## Type rfNews() to see new features/changes/bug fixes.
library(ggplot2)       # Visualisasi hasil analisis
## 
## Attaching package: 'ggplot2'
## The following object is masked from 'package:randomForest':
## 
##     margin
library(knitr)         # Menampilkan tabel pada R Markdown

Memuat Data dan Memeriksa Missing Value

# Memuat dataset BreastCancer
data("BreastCancer", package = "mlbench")
data_bc <- BreastCancer

# Memeriksa data
dim(data_bc)
## [1] 699  11
str(data_bc)
## 'data.frame':    699 obs. of  11 variables:
##  $ Id             : chr  "1000025" "1002945" "1015425" "1016277" ...
##  $ Cl.thickness   : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 5 5 3 6 4 8 1 2 2 4 ...
##  $ Cell.size      : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 1 4 1 8 1 10 1 1 1 2 ...
##  $ Cell.shape     : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 1 4 1 8 1 10 1 2 1 1 ...
##  $ Marg.adhesion  : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 1 5 1 1 3 8 1 1 1 1 ...
##  $ Epith.c.size   : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 2 7 2 3 2 7 2 2 2 2 ...
##  $ Bare.nuclei    : Factor w/ 10 levels "1","2","3","4",..: 1 10 2 4 1 10 10 1 1 1 ...
##  $ Bl.cromatin    : Factor w/ 10 levels "1","2","3","4",..: 3 3 3 3 3 9 3 3 1 2 ...
##  $ Normal.nucleoli: Factor w/ 10 levels "1","2","3","4",..: 1 2 1 7 1 7 1 1 1 1 ...
##  $ Mitoses        : Factor w/ 9 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 5 1 ...
##  $ Class          : Factor w/ 2 levels "benign","malignant": 1 1 1 1 1 2 1 1 1 1 ...
head(data_bc)
##        Id Cl.thickness Cell.size Cell.shape Marg.adhesion Epith.c.size
## 1 1000025            5         1          1             1            2
## 2 1002945            5         4          4             5            7
## 3 1015425            3         1          1             1            2
## 4 1016277            6         8          8             1            3
## 5 1017023            4         1          1             3            2
## 6 1017122            8        10         10             8            7
##   Bare.nuclei Bl.cromatin Normal.nucleoli Mitoses     Class
## 1           1           3               1       1    benign
## 2          10           3               2       1    benign
## 3           2           3               1       1    benign
## 4           4           3               7       1    benign
## 5           1           3               1       1    benign
## 6          10           9               7       1 malignant
# Memeriksa missing value
colSums(is.na(data_bc))
##              Id    Cl.thickness       Cell.size      Cell.shape   Marg.adhesion 
##               0               0               0               0               0 
##    Epith.c.size     Bare.nuclei     Bl.cromatin Normal.nucleoli         Mitoses 
##               0              16               0               0               0 
##           Class 
##               0
# Menghapus missing value
data_bc <- na.omit(data_bc)

# Menghapus variabel ID karena bukan prediktor
data_bc$Id <- NULL

# Memastikan variabel target berbentuk faktor
data_bc$Class <- factor(
  data_bc$Class,
  levels = c("benign", "malignant")
)

# Memeriksa kembali data
dim(data_bc)
## [1] 683  10
colSums(is.na(data_bc))
##    Cl.thickness       Cell.size      Cell.shape   Marg.adhesion    Epith.c.size 
##               0               0               0               0               0 
##     Bare.nuclei     Bl.cromatin Normal.nucleoli         Mitoses           Class 
##               0               0               0               0               0
table(data_bc$Class)
## 
##    benign malignant 
##       444       239

Dataset yang digunakan adalah dataset BreastCancer yang memiliki 699 observasi dan 11 variabel. Terdapat 16 missing value pada variabel Bare.nuclei. Setelah menggunakan na.omit(), jumlah observasi berkurang menjadi 683 karena 16 baris yang mengandung missing value dihapus. Hasil pemeriksaan kembali menunjukkan bahwa seluruh variabel sudah tidak memiliki missing value, sehingga data siap digunakan untuk analisis selanjutnya.

4.2 Pembagian Data Latih dan Data Uji

Data dibagi menjadi 80% data latih dan 20% data uji. Pembagian dilakukan secara stratified sampling agar proporsi kelas benign dan malignant relatif terjaga pada kedua kelompok data.

# Menetapkan seed
set.seed(234)

# Menentukan indeks training secara terstratifikasi
indeks_train <- unlist(
  lapply(levels(data_bc$Class), function(kelas) {
    indeks_kelas <- which(data_bc$Class == kelas)

    sample(
      indeks_kelas,
      size = floor(0.8 * length(indeks_kelas))
    )
  }),
  use.names = FALSE
)

# Membentuk data training dan testing
train_data <- data_bc[indeks_train, ]
test_data  <- data_bc[-indeks_train, ]

# Memeriksa jumlah observasi
nrow(train_data)
## [1] 546
nrow(test_data)
## [1] 137
# Memeriksa distribusi kelas
table(train_data$Class)
## 
##    benign malignant 
##       355       191
table(test_data$Class)
## 
##    benign malignant 
##        89        48

Pembagian data dilakukan menggunakan metode stratified sampling dengan proporsi 80% data latih dan 20% data uji berdasarkan kelas. Hasilnya, diperoleh 546 data latih dan 137 data uji. Data latih terdiri dari 355 kelas benign dan 191 kelas malignant, sedangkan data uji terdiri dari 89 kelas benign dan 48 kelas malignant.

4.3 Menentukan kombinasi parameter model

Analisis membandingkan sembilan kombinasi parameter, yaitu tiga nilai mtry dan tiga nilai ntree (jumlah pohon).

# Menentukan kombinasi parameter
daftar_mtry <- c(2, 3, 5)
daftar_ntree <- c(200, 500, 1000)

# Membentuk seluruh kombinasi parameter
kombinasi <- expand.grid(
  mtry = daftar_mtry,
  ntree = daftar_ntree
)

# Menampilkan kombinasi yang akan diuji
kable(
  kombinasi,
  caption = "Kombinasi Parameter Random Forest"
)
Kombinasi Parameter Random Forest
mtry ntree
2 200
3 200
5 200
2 500
3 500
5 500
2 1000
3 1000
5 1000

Hasil menunjukkan, bahwa terdapat sembilan kombinasi parameter Random Forest yang diuji, yaitu tiga nilai mtry (2, 3 dan 5) dan tiga nilai ntree (200, 500 dan 1.000). Kombinasi tersebut digunakan untuk membandingkan kinerja model berdasarkan jumlah prediktor yang dipertimbangkan pada setiap pemisahan dan jumlah pohon keputusan yang dibentuk.

4.4 Membentuk model Random Forest

# Menentukan kombinasi parameter
kombinasi <- expand.grid(
  mtry = c(2, 3, 5),
  ntree = c(200, 500, 1000)
)

# Menyiapkan tempat penyimpanan model
daftar_model <- list()

# Membentuk sembilan model
for (i in seq_len(nrow(kombinasi))) {

  nilai_mtry <- kombinasi$mtry[i]
  nilai_ntree <- kombinasi$ntree[i]

  set.seed(234 + i)

  nama_model <- paste0(
    "mtry_", nilai_mtry,
    "_ntree_", nilai_ntree
  )

  daftar_model[[nama_model]] <- randomForest(
    Class ~ .,
    data = train_data,
    mtry = nilai_mtry,
    ntree = nilai_ntree,
    importance = TRUE
  )
}

# Memeriksa model yang berhasil dibuat
names(daftar_model)
## [1] "mtry_2_ntree_200"  "mtry_3_ntree_200"  "mtry_5_ntree_200" 
## [4] "mtry_2_ntree_500"  "mtry_3_ntree_500"  "mtry_5_ntree_500" 
## [7] "mtry_2_ntree_1000" "mtry_3_ntree_1000" "mtry_5_ntree_1000"
# Menampilkan ringkasan model pertama
print(daftar_model[[1]])
## 
## Call:
##  randomForest(formula = Class ~ ., data = train_data, mtry = nilai_mtry,      ntree = nilai_ntree, importance = TRUE) 
##                Type of random forest: classification
##                      Number of trees: 200
## No. of variables tried at each split: 2
## 
##         OOB estimate of  error rate: 2.93%
## Confusion matrix:
##           benign malignant class.error
## benign       343        12  0.03380282
## malignant      4       187  0.02094241

Berdasarkan hasil pemodelan, model Random Forest pertama dengan mtry = 2 dan ntree = 200 menghasilkan nilai OOB error sebesar 2,93%. Model berhasil mengklasifikasikan 343 data benign dan 187 data malignant dengan benar, sedangkan 16 data lainnya salah diklasifikasikan. Hasil ini menunjukkan bahwa model memiliki tingkat kesalahan klasifikasi internal yang relatif rendah.

4.5 Melihat hasil model dan OOB error

# Mengambil OOB error dari seluruh model
hasil_oob <- data.frame(
  Model = names(daftar_model),
  mtry = kombinasi$mtry,
  ntree = kombinasi$ntree,
  OOB_Error = sapply(
    daftar_model,
    function(model) {
      model$err.rate[nrow(model$err.rate), "OOB"]
    }
  )
)

knitr::kable(
  hasil_oob,
  digits = 4,
  caption = "Perbandingan OOB Error Random Forest"
)
Perbandingan OOB Error Random Forest
Model mtry ntree OOB_Error
mtry_2_ntree_200.OOB mtry_2_ntree_200 2 200 0.0293
mtry_3_ntree_200.OOB mtry_3_ntree_200 3 200 0.0330
mtry_5_ntree_200.OOB mtry_5_ntree_200 5 200 0.0385
mtry_2_ntree_500.OOB mtry_2_ntree_500 2 500 0.0311
mtry_3_ntree_500.OOB mtry_3_ntree_500 3 500 0.0275
mtry_5_ntree_500.OOB mtry_5_ntree_500 5 500 0.0311
mtry_2_ntree_1000.OOB mtry_2_ntree_1000 2 1000 0.0293
mtry_3_ntree_1000.OOB mtry_3_ntree_1000 3 1000 0.0348
mtry_5_ntree_1000.OOB mtry_5_ntree_1000 5 1000 0.0348

Berdasarkan hasil, model mtry_3_ntree_500 menghasilkan OOB error terendah sebesar 2,75%, dengan menggunakan 3 variabel kandidat pada setiap pemisahan dan 500 pohon keputusan. Sementara itu, OOB error tertinggi sebesar 3,85% diperoleh model mtry_5_ntree_200. Dengan demikian, model mtry_3_ntree_500 memiliki tingkat kesalahan klasifikasi internal paling rendah di antara sembilan model yang diuji.

4.6 Melakukan prediksi pada data testing

# Menyimpan hasil prediksi setiap model
daftar_prediksi <- lapply(
  daftar_model,
  predict,
  newdata = test_data
)

# Melihat contoh prediksi model pertama
head(daftar_prediksi[[1]])
##         5         6         7         9        19        26 
##    benign malignant    benign    benign malignant malignant 
## Levels: benign malignant

Hasil tersebut menunjukkan bahwa model Random Forest pertama berhasil memprediksi enam data uji, yaitu data ke-5, 6, 7, 9, 19 dan 26. Hasil prediksi mengklasifikasikan data ke-5, 7 dan 9 ke dalam kelas benign, sedangkan data ke-6, 19 dan 26 ke dalam kelas malignant.

4.7 Evaluasi menggunakan confusion matrix dan metrik klasifikasi

# Fungsi untuk menghitung metrik evaluasi
hitung_metrik <- function(aktual, prediksi) {

  # Membentuk confusion matrix
  cm <- table(
    Aktual = factor(
      aktual,
      levels = c("benign", "malignant")
    ),
    Prediksi = factor(
      prediksi,
      levels = c("benign", "malignant")
    )
  )

  # Mengambil komponen confusion matrix
  TN <- cm["benign", "benign"]
  FP <- cm["benign", "malignant"]
  FN <- cm["malignant", "benign"]
  TP <- cm["malignant", "malignant"]

  # Menghitung metrik evaluasi
  accuracy <- (TP + TN) / sum(cm)

  precision <- ifelse(
    TP + FP == 0, NA, TP / (TP + FP)
  )

  recall <- ifelse(
    TP + FN == 0, NA, TP / (TP + FN)
  )

  specificity <- ifelse(
    TN + FP == 0, NA, TN / (TN + FP)
  )

  f1 <- ifelse(
    is.na(precision) || is.na(recall) ||
      precision + recall == 0,
    NA,
    2 * precision * recall / (precision + recall)
  )

  # Mengembalikan hasil evaluasi
  c(
    Accuracy = accuracy,
    Precision = precision,
    Recall = recall,
    Specificity = specificity,
    F1_Score = f1
  )
}


# Menampilkan confusion matrix untuk setiap model
for (nama in names(daftar_model)) {
  
  cat("\nModel:", nama, "\n")
  
  print(
    table(
      Aktual = test_data$Class,
      Prediksi = daftar_prediksi[[nama]]
    )
  )
}
## 
## Model: mtry_2_ntree_200 
##            Prediksi
## Aktual      benign malignant
##   benign        89         0
##   malignant      2        46
## 
## Model: mtry_3_ntree_200 
##            Prediksi
## Aktual      benign malignant
##   benign        89         0
##   malignant      2        46
## 
## Model: mtry_5_ntree_200 
##            Prediksi
## Aktual      benign malignant
##   benign        89         0
##   malignant      4        44
## 
## Model: mtry_2_ntree_500 
##            Prediksi
## Aktual      benign malignant
##   benign        89         0
##   malignant      2        46
## 
## Model: mtry_3_ntree_500 
##            Prediksi
## Aktual      benign malignant
##   benign        89         0
##   malignant      2        46
## 
## Model: mtry_5_ntree_500 
##            Prediksi
## Aktual      benign malignant
##   benign        89         0
##   malignant      4        44
## 
## Model: mtry_2_ntree_1000 
##            Prediksi
## Aktual      benign malignant
##   benign        89         0
##   malignant      2        46
## 
## Model: mtry_3_ntree_1000 
##            Prediksi
## Aktual      benign malignant
##   benign        89         0
##   malignant      2        46
## 
## Model: mtry_5_ntree_1000 
##            Prediksi
## Aktual      benign malignant
##   benign        89         0
##   malignant      4        44

Hasil confusion matrix menunjukkan bahwa model Random Forest dengan mtry = 2 dan mtry = 3 menghasilkan prediksi yang sama pada seluruh jumlah pohon (ntree), yaitu 89 data benign dan 46 data malignant diklasifikasikan dengan benar, sedangkan 2 data malignant salah diklasifikasikan sebagai benign. Sementara itu, model dengan mtry = 5 berhasil mengklasifikasikan 89 data benign dan 44 data malignant dengan benar, tetapi 4 data malignant salah diklasifikasikan sebagai benign. Dengan demikian, model dengan mtry = 2 atau mtry = 3 menunjukkan hasil klasifikasi yang lebih baik dibandingkan model dengan mtry = 5 berdasarkan confusion matrix pada data uji.

4.8 Membandingkan seluruh metrik evaluasi

# Menghitung metrik testing untuk setiap model
hasil_metrik <- do.call(
  rbind,
  lapply(names(daftar_model), function(nama) {

    metrik <- hitung_metrik(
      aktual = test_data$Class,
      prediksi = daftar_prediksi[[nama]]
    )

    data.frame(
      Model = nama,
      t(metrik),
      row.names = NULL
    )
  })
)

# Menggabungkan hasil metrik dengan OOB error
hasil_evaluasi <- merge(
  hasil_oob,
  hasil_metrik,
  by = "Model"
)

# Mengurutkan berdasarkan F1-score tertinggi
hasil_evaluasi <- hasil_evaluasi[
  order(-hasil_evaluasi$F1_Score),
]

# Menampilkan hasil perbandingan
kable(
  hasil_evaluasi,
  digits = 4,
  caption = "Perbandingan Kinerja Sembilan Model Random Forest"
)
Perbandingan Kinerja Sembilan Model Random Forest
Model mtry ntree OOB_Error Accuracy Precision Recall Specificity F1_Score
mtry_2_ntree_1000 2 1000 0.0293 0.9854 1 0.9583 1 0.9787
mtry_2_ntree_200 2 200 0.0293 0.9854 1 0.9583 1 0.9787
mtry_2_ntree_500 2 500 0.0311 0.9854 1 0.9583 1 0.9787
mtry_3_ntree_1000 3 1000 0.0348 0.9854 1 0.9583 1 0.9787
mtry_3_ntree_200 3 200 0.0330 0.9854 1 0.9583 1 0.9787
mtry_3_ntree_500 3 500 0.0275 0.9854 1 0.9583 1 0.9787
mtry_5_ntree_1000 5 1000 0.0348 0.9708 1 0.9167 1 0.9565
mtry_5_ntree_200 5 200 0.0385 0.9708 1 0.9167 1 0.9565
mtry_5_ntree_500 5 500 0.0311 0.9708 1 0.9167 1 0.9565

Berdasarkan hasil perbandingan, model Random Forest dengan mtry = 2 dan mtry = 3 menghasilkan kinerja pengujian yang sama, yaitu accuracy sebesar 98,54%, precision 100%, recall 95,83%, specificity 100% dan F1-score 97,87%. Sementara itu, model dengan mtry = 5 menghasilkan accuracy 97,08% dan F1-score 95,65%. Berdasarkan OOB error, model* mtry_3_ntree_500* memiliki nilai terendah sebesar 2,75%. Dengan demikian, model tersebut dapat dipilih sebagai model terbaik karena memiliki kesalahan klasifikasi internal paling rendah, meskipun metrik pengujiannya sama dengan model lain yang menggunakan mtry = 2 atau mtry = 3.

4.9 Visualisasi perbandingan performa model

# Mengubah tabel ke format panjang untuk visualisasi
hasil_long <- reshape(
  hasil_evaluasi[
    , c(
      "Model", "Accuracy", "Precision",
      "Recall", "Specificity", "F1_Score"
    )
  ],
  varying = c(
    "Accuracy", "Precision", "Recall",
    "Specificity", "F1_Score"
  ),
  v.names = "Nilai",
  timevar = "Metrik",
  times = c(
    "Accuracy", "Precision", "Recall",
    "Specificity", "F1-score"
  ),
  direction = "long"
)

# Membuat grafik perbandingan metrik
ggplot(
  hasil_long,
  aes(x = Model, y = Nilai, group = Metrik)
) +
  geom_point(size = 2) +
  geom_line() +
  facet_wrap(~ Metrik, ncol = 2) +
  coord_flip() +
  labs(
    title = "Perbandingan Kinerja Random Forest",
    subtitle = "Evaluasi pada data testing",
    x = "Kombinasi model",
    y = "Nilai metrik"
  ) +
  theme_minimal()

Hasil evaluasi menunjukkan bahwa kombinasi parameter Random Forest menghasilkan nilai accuracy dan F1-score yang bervariasi, sedangkan nilai precision dan specificity mencapai 1,00 pada seluruh kombinasi. Nilai recall berada pada kisaran 0,92–0,96. Hal ini menunjukkan bahwa model memiliki kemampuan yang sangat baik dalam mengidentifikasi kelas positif, meskipun kemampuan mendeteksi seluruh kasus positif masih berbeda antarparameter.

4.10 Visualisasi OBB error

# Membuat grafik OOB error
ggplot(
  hasil_oob,
  aes(
    x = factor(ntree),
    y = OOB_Error,
    group = factor(mtry)
  )
) +
  geom_point(size = 3) +
  geom_line() +
  labs(
    title = "Perbandingan OOB Error",
    x = "Jumlah pohon (ntree)",
    y = "OOB error",
    group = "mtry"
  ) +
  theme_minimal()

Grafik menunjukkan bahwa nilai Out-of-Bag (OOB) Error bervariasi pada jumlah pohon 200, 500 dan 1.000. Nilai error terendah terlihat sekitar 0,0275 pada salah satu kombinasi parameter dengan 500 pohon. Hasil ini menunjukkan bahwa penambahan jumlah pohon tidak selalu menurunkan OOB error. Oleh karena itu, pemilihan model perlu mempertimbangkan nilai OOB error dan kinerja klasifikasi pada data uji.

4.11 Menentukan model terbaik dan melihat variable importance

# Menentukan model dengan F1-score tertinggi
indeks_terbaik <- which.max(hasil_evaluasi$F1_Score)

nama_terbaik <- hasil_evaluasi$Model[indeks_terbaik]

model_terbaik <- daftar_model[[nama_terbaik]]

# Menampilkan nama model terbaik
nama_terbaik
## [1] "mtry_2_ntree_1000"
# Menampilkan metrik model terbaik
hasil_evaluasi[indeks_terbaik, ]
##               Model mtry ntree  OOB_Error  Accuracy Precision    Recall
## 1 mtry_2_ntree_1000    2  1000 0.02930403 0.9854015         1 0.9583333
##   Specificity  F1_Score
## 1           1 0.9787234
# Menampilkan confusion matrix model terbaik
table(
  Aktual = test_data$Class,
  Prediksi = daftar_prediksi[[nama_terbaik]]
)
##            Prediksi
## Aktual      benign malignant
##   benign        89         0
##   malignant      2        46
# Menampilkan variable importance
importance(model_terbaik)
##                   benign malignant MeanDecreaseAccuracy MeanDecreaseGini
## Cl.thickness    21.68858 26.277723             28.41644        16.533766
## Cell.size       21.98196 19.644157             28.48650        52.996022
## Cell.shape      17.91353 22.406868             27.70446        46.180895
## Marg.adhesion   11.77082 14.056635             17.42279        11.463529
## Epith.c.size    11.59289 11.526475             16.36637        25.098736
## Bare.nuclei     25.01850 28.186495             32.06635        37.067653
## Bl.cromatin     14.89230 16.647494             21.61335        29.180914
## Normal.nucleoli 18.03016 12.455502             19.90862        25.920325
## Mitoses         11.23140  6.067436             12.35520         3.006598
# Membuat grafik variable importance
varImpPlot(
  model_terbaik,
  main = paste("Variable Importance:", nama_terbaik)
)

Berdasarkan grafik Variable Importance, variabel Bare.nuclei memiliki tingkat kepentingan tertinggi berdasarkan ukuran MeanDecreaseAccuracy, sedangkan Cell.size memiliki nilai tertinggi berdasarkan MeanDecreaseGini. Sebaliknya, variabel Mitoses menunjukkan tingkat kepentingan terendah pada kedua ukuran tersebut. Hasil ini menunjukkan bahwa setiap variabel memberikan kontribusi yang berbeda terhadap proses klasifikasi pada model Random Forest.

4.12 Visualisasi perubahan OOB error selama pembentukan pohon

# Mengambil model terbaik
error_model <- data.frame(
  Jumlah_Pohon = seq_len(model_terbaik$ntree),
  OOB_Error = model_terbaik$err.rate[, "OOB"]
)

# Membuat grafik perkembangan OOB error
ggplot(
  error_model,
  aes(x = Jumlah_Pohon, y = OOB_Error)
) +
  geom_line() +
  labs(
    title = "Perkembangan OOB Error",
    subtitle = nama_terbaik,
    x = "Jumlah pohon",
    y = "OOB error"
  ) +
  theme_minimal()

Grafik perkembangan OOB error menunjukkan bahwa kesalahan klasifikasi cenderung menurun pada awal penambahan pohon, kemudian relatif stabil. Kondisi ini menunjukkan bahwa penambahan jumlah pohon setelah model mencapai kestabilan memberikan perubahan yang relatif kecil terhadap OOB error. Oleh karena itu, penggunaan jumlah pohon yang lebih banyak tidak selalu memberikan peningkatan kinerja yang berarti.

BAB V KESIMPULAN

5.1 Kesimpulan

Random Forest dan Double Random Forest merupakan metode Ensemble Learning berbasis decision tree yang menggabungkan sejumlah pohon keputusan untuk menghasilkan prediksi. Random Forest menggunakan pengambilan sampel bootstrap dan pemilihan fitur secara acak, sedangkan Double Random Forest dikembangkan untuk mengatasi potensi underfitting melalui pembentukan pohon yang lebih besar.

Implementasi Random Forest dan Double Random Forest dapat dilakukan untuk klasifikasi maupun regresi. Pada klasifikasi, prediksi ditentukan berdasarkan kelas dengan suara terbanyak dari pohon-pohon yang terbentuk, sedangkan pada regresi, prediksi diperoleh melalui rata-rata hasil prediksi pohon.

Evaluasi kinerja model dilakukan menggunakan metrik yang sesuai, yaitu akurasi, presisi, recall, spesifisitas dan F1-score untuk klasifikasi, serta MAE, MSE dan RMSE untuk regresi. Selain itu, Out-of-Bag (OOB) error digunakan untuk memperkirakan kesalahan prediksi model berdasarkan data yang tidak terpilih dalam sampel bootstrap suatu pohon. Perbandingan hasil evaluasi kedua metode dapat digunakan untuk menentukan model dengan kinerja lebih baik pada data yang dianalisis.

Berdasarkan hasil analisis, metode Random Forest mampu mengklasifikasikan data BreastCancer dengan sangat baik. Model dengan mtry = 2 dan mtry = 3 menghasilkan kinerja terbaik pada data uji, dengan accuracy sebesar 98,54% dan F1-score sebesar 97,87%. Sementara itu, model mtry_3_ntree_500 memiliki OOB error terendah sebesar 2,75%, sehingga dapat dipilih sebagai model terbaik berdasarkan kesalahan klasifikasi internal. Hasil variable importance menunjukkan bahwa Bare.nuclei dan Cell.size merupakan variabel yang paling berpengaruh dalam proses klasifikasi.

DAFTAR PUSTAKA

Aldania, A. N. A., Soleh, A. M., dan Notodiputro, K. A. (2023). A comparative study of CatBoost and Double Random Forest for multi-class classification. Jurnal Rekayasa Sistem dan Teknologi Informasi.

Fransiska, H. (2026). Modul Praktikum Machine Learning and Modern Prediction. Laboratorium Matematika Universitas Bengkulu.

Darwanto, A. R. S., Viarindita, T. L., dan Widyaningsih, Y. (2021). Analisis regresi logistik binomial dan algoritma Random Forest pada proses pengklasifikasian penyakit ginjal kronis. Jurnal Statistika dan Aplikasinya.

Fadli, M., dan Saputra, R. A. (2023). Klasifikasi dan evaluasi performa model Random Forest untuk prediksi stroke. Jurnal Teknik Universitas Muhammadiyah Tangerang UMT Journal.

Khairunnisa, A., Notodiputro, K. A., dan Sartono, B. (2024).A comparative study of Random Forest and Double Random Forest models from view points of their interpretability. Scientific Journal of Informatics.

Purwanto, A., Sartono, B., dan Notodiputro, K. A. (2025). A comparison of Random Forest and Double Random Forest: Dropout rates of madrasah students in Indonesia. Jurnal Ilmu Matematika dan Terapan.