Perkembangan teknologi informasi mendorong penggunaan metode machine learning dalam mengolah dan menganalisis data. Salah satu metode yang banyak digunakan adalah ensemble learning, yaitu teknik yang menggabungkan beberapa model untuk menghasilkan prediksi yang lebih baik. Salah satu algoritma dalam metode tersebut adalah Random Forest, yang menggabungkan sejumlah pohon keputusan (decision tree) melalui proses pengambilan sampel dan pemilihan variabel secara acak. Metode ini dapat digunakan untuk menyelesaikan permasalahan klasifikasi maupun regresi (Hidayatulloh dkk, 2022).
Random Forest memiliki keunggulan dalam menghasilkan prediksi yang stabil dan mengurangi risiko overfitting. Namun, dalam kondisi tertentu, model ini masih dapat mengalami underfitting ketika pohon keputusan yang terbentuk kurang mampu menangkap pola data. Salah satu pengembangan yang dapat digunakan untuk mengatasi permasalahan tersebut adalah Double Random Forest, yaitu metode yang mengembangkan pohon keputusan menjadi lebih besar sehingga diharapkan mampu meningkatkan kemampuan prediksi model (Purwanto dkk, 2025).
Penerapan kedua metode tersebut perlu disertai dengan evaluasi untuk mengetahui kemampuan model dalam menghasilkan prediksi. Evaluasi dapat dilakukan menggunakan beberapa ukuran, seperti accuracy, precision, recall, dan F1-score untuk klasifikasi, serta MAE, MSE, RMSE, dan R2 untuk regresi. Selain itu, Out-of-Bag (OOB) error dapat digunakan untuk memperkirakan kesalahan prediksi model berdasarkan pengamatan yang tidak digunakan dalam pembentukan pohon tertentu. Penelitian Hasna dkk (2024) menunjukkan bahwa OOB error dapat digunakan untuk mengevaluasi kinerja model Random Forest dalam klasifikasi Indeks Standar Pencemaran Udara.
Berdasarkan latar belakang, rumusan masalah yang dapat disimpulkan adalah:
Apa yang dimaksud dengan Random Forest dan Doble Random Forest sebagai metode ensemble berbasis decision tree?
Bagaimana cara mengimplementasikan Random Forest untuk klasifikasi dan regresi, serta Double Random Forest untuk klasifikasi dan regresi?
Bagaimana cara mengevaluasi perfoma model, memahami Out-of-Bag (OOB) error, dan membandingkan Random Forest dan Double Random Forest?
Berdasarkan rumusan masalah, tujuan yang dapat disimpulkan adalah:
Mahasiswa dapat memahami Random Forest dan Doble Random Forest sebagai metode ensemble berbasis decision tree.
Mahasiswa dapat mengimplementasikan Random Forest untuk klasifikasi dan regresi, serta Double Random Forest untuk klasifikasi dan regresi.
Mahasiswa dapat mengevaluasi perfoma model, memahami Out-of-Bag (OOB) error, dan membandingkan Random Forest dan Double Random Forest.
Adapun manfaat pada penelitian ini, yaitu:
Adapun batasan masalah pada laporan praktikum pertemuan ini adalah lakukan analisis Random Forest secara lengkap mulai dari persiapan data, pembentukan model, prediksi, evaluasi, visualisasi, dan interpretasi. Gunakan set.seed(234) agar hasil dapat direproduksi. Lakukan Random Forest Classification pada data BreastCancer. Bandingkan mtry = 2, 3, dan 5 dengan num.trees = 200, 500, dan 1000. Bandingkan performa data testing berdasarkan confusion matrix, Accuracy, Precision, Recall, Specificity, F1-score, dan variable importance. Tampilkan pula OOB error sebagai evaluasi internal model.
Adapun sistematika penulisan dari praktikum ini adalah:
BAB I PENDAHULUAN Bab I terdiri dari latar belakang, rumusan masalah, batasan masalah, tujuan penelitian, manfaat penelitian, dan sistematika penulisan.
BAB II TINJAUAN PUSTAKA Bab tinjauan pustaka ini meliputi landasan teori yang berisi tentang pembahasan teori yang digunakan dalam penelitian.
BAB III METODE PENELITIAN Bab ini terdiri dari analisis jenis dan sumber data, variabel penelitian, algoritma penelitian, dan diagram alur.
BAB IV HASIL DAN PEMBAHASAN Bab ini merupakan tahapan pencapaian hasil yang diperoleh dari analisis data yang dilakukan serta penjelasan dari hasil tersebut di bagian pembahasan.
BAB V KESIMPULAN DAN SARAN Bab ini merupakan bagian penutup dalam laporan ini berupa penarikan kesimpulan mengenai hasil analisis dari penelitian serta penyampaian saran oleh penulis.
DAFTAR PUSTAKA
LAMPIRAN
Random Forest merupakan algoritma machine learning yang termasuk dalam metode ensemble learning dengan menggabungkan sejumlah pohon keputusan (decision tree) untuk menghasilkan prediksi. Metode ini menggunakan teknik bootstrap aggregating (bagging) dan pemilihan variabel prediktor secara acak pada setiap pembentukan pohon. Penggabungan beberapa pohon tersebut bertujuan menghasilkan prediksi yang lebih stabil serta mengurangi risiko overfitting (Hidayatulloh dkk, 2022).
Secara umum, proses pembentukan Random Forest dimulai dengan mengambil sampel data secara acak menggunakan teknik bootstrap, kemudian membentuk pohon keputusan berdasarkan variabel prediktor yang dipilih secara acak. Proses tersebut dilakukan berulang kali hingga terbentuk sejumlah pohon keputusan. Selanjutnya, seluruh hasil prediksi digabungkan untuk memperoleh prediksi akhir.
Random Forest dapat digunakan untuk dua jenis permasalahan, yaitu:
Random Forest Classification, digunakan untuk memprediksi variabel respons berbentuk kategorik. Hasil prediksi akhir ditentukan berdasarkan kelas yang paling banyak dipilih oleh seluruh pohon keputusan (majority voting).
Random Forest Regression, digunakan untuk memprediksi variabel respons berbentuk numerik. Hasil prediksi akhir diperoleh melalui rata-rata prediksi seluruh pohon keputusan.
Selain itu, Random Forest memiliki ukuran evaluasi internal berupa Out-of-Bag (OOB) error. OOB merupakan kesalahan prediksi yang dihitung menggunakan pengamatan yang tidak terpilih dalam proses bootstrap pada pembentukan pohon tertentu. Pengamatan tersebut digunakan untuk menguji kemampuan prediksi pohon yang bersangkutan. Nilai OOB error yang semakin kecil menunjukkan bahwa kesalahan prediksi model semakin rendah. Hasna et al. (2024) menerapkan OOB error dalam klasifikasi Indeks Standar Pencemaran Udara dan memperoleh OOB error sebesar 0,83%.
Secara sederhana, proses Random Forest dilakukan sebagai berikut (Fransiska, 2026):
Mengambil sampel bootstrap dari data latih untuk membentuk data bagi tree ke-𝑏.
Pada setiap node, memilih mtry prediktor secara acak dari seluruh 𝑝 prediktor.
Menentukan split terbaik hanya dari mtry prediktor yang terpilih.
Menumbuhkan decision tree hingga memenuhi aturan penghentian, misalnya minimum node size.
Mengulangi proses sampai diperoleh 𝐵 tree, kemudian menggabungkan prediksi seluruh tree.
Double Random Forest (DRF) merupakan pengembangan dari algoritma Random Forest yang bertujuan mengatasi kemungkinan terjadinya underfitting. Metode ini dilakukan dengan membentuk pohon keputusan yang lebih besar melalui pengaturan parameter nodesize yang lebih kecil. Dengan demikian, pohon keputusan diharapkan mampu menangkap pola data yang lebih kompleks dibandingkan model Random Forest biasa (Hidayatulloh dkk, 2022).
Proses penerapan DRF pada dasarnya menggunakan prinsip pembentukan pohon keputusan seperti pada Random Forest, tetapi dilakukan pengembangan terhadap ukuran pohon yang terbentuk. Tahapan tersebut bertujuan meningkatkan kemampuan model dalam mengenali pola hubungan antara variabel prediktor dan variabel respons.
DRF dapat diterapkan pada permasalahan klasifikasi maupun regresi. Pada klasifikasi, hasil prediksi diperoleh melalui mekanisme majority voting, sedangkan pada regresi menggunakan rata-rata hasil prediksi seluruh pohon keputusan. Evaluasi model dapat dilakukan menggunakan ukuran kinerja yang sama dengan Random Forest, sehingga hasil keduanya dapat dibandingkan secara langsung.
DRF dapat membantu memperbaiki kondisi underfitting pada model Random Forest. Namun, DRF tidak selalu menghasilkan kinerja yang lebih baik karena peningkatan kemampuan model bergantung pada karakteristik data yang digunakan. Oleh karena itu, diperlukan evaluasi untuk mengetahui metode yang memberikan hasil prediksi terbaik (Purwanto dkk, 2025).
Jenis data yang digunakan di dalam penelitian ini berupa data kuantitatif. Data kuantitatif merupakan data atau informasi yang didapatkan dalam bentuk angka atau numerik. Data yang digunakan merupakan data sekunder dataset BreastCancer yang tersedia dalam paket mlbench pada program RStudio. Dataset ini berisi karakteristik sel tumor payudara yang digunakan untuk mengklasifikasikan kondisi tumor ke dalam dua kategori, yaitu benign (jinak) dan malignant (ganas). Dalam analisis ini, metode Random Forest diterapkan dengan mengombinasikan variasi nilai mtry, yaitu 2, 3, dan 5, serta jumlah pohon keputusan (num.trees) sebanyak 200, 500, dan 1000. Kombinasi tersebut digunakan untuk mengetahui perbedaan kinerja model klasifikasi berdasarkan parameter yang digunakan.
Variabel penelitian adalah karakter atau segala sesuatu yang menjadi perhatian dalam suatu penelitian. Pada penelitian ini terdapat 9 variabel prediktor dan 1 variabel respon. Variabel prediktor meliputi Cl.thickness (ketebalan gumpalan sel), Cell.size (keseragaman ukuran sel), Cell.shape (keseragaman bentuk sel), Marg.adhesion (adhesi marginal), Epith.c.size (ukuran sel epitel), Bare.nuclei (inti sel yang tidak tertutup), Bl.cromatin (kromatin lunak), Normal.nucleoli (nukleolus normal), dan Mitoses (aktivitas mitosis). Sementara itu, variabel respon adalah Class, yang menunjukkan kategori kondisi tumor payudara, yaitu benign (jinak) dan malignant (ganas).
Berikut adalah algoritma untuk menyelesaiankan batasan masalah:
Memanggil package yang diperlukan dan memuat dataset BreastCancer.
Melakukan pemeriksaan dan prapemrosesan data.
Menentukan variabel prediktor dan variabel respon.
Membagi data menjadi data training dan data testing dengan proporsi 70:30.
Membentuk model klasifikasi menggunakan metode Random Forest dengan beberapa kombinasi parameter.
Melakukan prediksi terhadap data testing.
Mengevaluasi kinerja model menggunakan confusion matrix dan metrik evaluasi.
Membandingkan nilai accuracy, F1-score, dan OOB Error dari setiap model.
Menganalisis variable importance.
Menentukan model Random Forest terbaik berdasarkan hasil evaluasi.
## Loading required package: ggplot2
## Loading required package: lattice
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr)
# 2. PERSIAPAN DATA
# Memanggil data BreastCancer
data(BreastCancer, package = "mlbench")
# Membuat salinan data
bc <- BreastCancer
# Melihat struktur data
str(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 ...
## Id Cl.thickness Cell.size Cell.shape Marg.adhesion
## Length :699 1 :145 1 :384 1 :353 1 :407
## N.unique :645 5 :130 10 : 67 2 : 59 2 : 58
## N.blank : 0 3 :108 3 : 52 10 : 58 3 : 58
## Min.nchar: 5 4 : 80 2 : 45 3 : 56 10 : 55
## Max.nchar: 8 10 : 69 4 : 40 4 : 44 4 : 33
## 2 : 50 5 : 30 5 : 34 8 : 25
## (Other):117 (Other): 81 (Other): 95 (Other): 63
## Epith.c.size Bare.nuclei Bl.cromatin Normal.nucleoli Mitoses
## 2 :386 1 :402 2 :166 1 :443 1 :579
## 3 : 72 10 :132 3 :165 10 : 61 2 : 35
## 4 : 48 2 : 30 1 :152 3 : 44 3 : 33
## 1 : 47 5 : 30 7 : 73 2 : 36 10 : 14
## 6 : 41 3 : 28 4 : 40 8 : 24 4 : 12
## 5 : 39 (Other): 61 5 : 34 6 : 22 7 : 9
## (Other): 66 NAs : 16 (Other): 69 (Other): 69 (Other): 17
## Class
## benign :458
## malignant:241
##
##
##
##
##
# Menghapus variabel Id
bc$Id <- NULL
# Menghapus missing value
bc <- na.omit(bc)
# Mengubah variabel Class menjadi factor
bc$Class <- factor(
bc$Class,
levels = c("benign", "malignant")
)
# Memeriksa struktur data
str(bc)## 'data.frame': 683 obs. of 10 variables:
## $ 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 ...
## - attr(*, "na.action")= 'omit' Named int [1:16] 24 41 140 146 159 165 236 250 276 293 ...
## ..- attr(*, "names")= chr [1:16] "24" "41" "140" "146" ...
## 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
##
## benign malignant
## 444 239
##
## benign malignant
## 0.6500732 0.3499268
## Cl.thickness Cell.size Cell.shape Marg.adhesion Epith.c.size
## 1 :139 1 :373 1 :346 1 :393 2 :376
## 5 :128 10 : 67 2 : 58 2 : 58 3 : 71
## 3 :104 3 : 52 10 : 58 3 : 58 4 : 48
## 4 : 79 2 : 45 3 : 53 10 : 55 1 : 44
## 10 : 69 4 : 38 4 : 43 4 : 33 6 : 40
## 2 : 50 5 : 30 5 : 32 8 : 25 5 : 39
## (Other):114 (Other): 78 (Other): 93 (Other): 61 (Other): 65
## Bare.nuclei Bl.cromatin Normal.nucleoli Mitoses Class
## 1 :402 3 :161 1 :432 1 :563 benign :444
## 10 :132 2 :160 10 : 60 2 : 35 malignant:239
## 2 : 30 1 :150 3 : 42 3 : 33
## 5 : 30 7 : 71 2 : 36 10 : 14
## 3 : 28 4 : 39 8 : 23 4 : 12
## 8 : 21 5 : 34 6 : 22 7 : 9
## (Other): 40 (Other): 68 (Other): 68 (Other): 17
# Menghitung jumlah setiap kelas
jumlah.kelas <- as.data.frame(table(bc$Class))
colnames(jumlah.kelas) <- c("Class", "Jumlah")
# Visualisasi distribusi kelas
ggplot(jumlah.kelas,
aes(x = Class, y = Jumlah, fill = Class)) +
geom_col(width = 0.6) +
labs(
title = "Distribusi Kelas BreastCancer",
x = "Kelas",
y = "Jumlah Observasi"
) +
theme_minimal() +
theme(legend.position = "none")# 4. PEMBAGIAN DATA TRAINING DAN TESTING
set.seed(234)
# Membagi data dengan proporsi 70:30
idx.cls <- createDataPartition(
bc$Class,
p = 0.70,
list = FALSE
)
# Data training
bc.train <- bc[idx.cls, ]
# Data testing
bc.test <- bc[-idx.cls, ]
# Melihat dimensi data
dim(bc.train)## [1] 479 10
## [1] 204 10
##
## benign malignant
## 311 168
##
## benign malignant
## 133 71
Dataset BreastCancer yang digunakan berasal dari paket mlbench dan pada tahap awal terdiri atas 699 observasi. Setelah variabel Id dihapus dan observasi yang memiliki missing value dikeluarkan menggunakan na.omit(), data yang digunakan dalam pemodelan berjumlah 683 observasi dengan sembilan variabel prediktor dan satu variabel respons, yaitu Class. Variabel respons terdiri atas dua kategori, yaitu benign sebanyak 444 observasi (65,01%) dan malignant sebanyak 239 observasi (34,99%).
Berdasarkan hasil, kelas benign memiliki jumlah observasi lebih banyak dibandingkan kelas malignant. Proporsi kedua kelas tersebut menunjukkan bahwa distribusi data tidak sepenuhnya seimbang, karena kelas benign mencakup sekitar 65,01% dari keseluruhan data, sedangkan kelas malignant sekitar 34,99%. Meskipun demikian, kedua kelas tetap memiliki jumlah observasi yang dapat digunakan untuk membangun model klasifikasi. Data selanjutnya dibagi dengan proporsi 70:30, sehingga diperoleh 479 observasi sebagai data training dan 204 observasi sebagai data testing. Pembagian tersebut menghasilkan 311 data benign dan 168 data malignant pada training, serta 133 data benign dan 71 data malignant pada testing.
# 5. PEMBENTUKAN MODEL RANDOM FOREST
# Kombinasi parameter
nilai.mtry <- c(2, 3, 5)
jumlah.trees <- c(200, 500, 1000)
# Menyiapkan tempat penyimpanan hasil
hasil.model <- list()
hasil.evaluasi <- list()
hasil.importance <- list()
# Fungsi untuk menghindari pembagian dengan nol
safe_div <- function(a, b) {
if (is.na(b) || b == 0) {
return(NA_real_)
} else {
return(a / b)
}
}
# Perulangan pembentukan model
nomor <- 1
for (m in nilai.mtry) {
for (nt in jumlah.trees) {
cat("\n====================================\n")
cat("Model:", nomor, "\n")
cat("mtry:", m, "\n")
cat("num.trees:", nt, "\n")
cat("====================================\n")
# Membentuk model Random Forest
set.seed(234)
rf <- ranger(
Class ~ .,
data = bc.train,
num.trees = nt,
mtry = m,
min.node.size = 1,
replace = TRUE,
sample.fraction = 1,
importance = "permutation",
seed = 234
)
# Menentukan nama model
nama.model <- paste0("mtry_", m, "_ntree_", nt)
# Menyimpan model
hasil.model[[nama.model]] <- rf
# Mengambil nilai OOB Error
oob <- rf$prediction.error
# Melakukan prediksi pada data testing
prediksi <- predict(
rf,
data = bc.test
)$predictions
# Mengubah hasil prediksi menjadi factor
prediksi <- factor(
prediksi,
levels = c("benign", "malignant")
)
aktual <- factor(
bc.test$Class,
levels = c("benign", "malignant")
)
# Membentuk confusion matrix
cm <- table(
Actual = aktual,
Predicted = prediksi
)
# Mengambil nilai TP, TN, FP, dan FN
TN <- as.numeric(cm["benign", "benign"])
FP <- as.numeric(cm["benign", "malignant"])
FN <- as.numeric(cm["malignant", "benign"])
TP <- as.numeric(cm["malignant", "malignant"])
# Menghitung metrik evaluasi
accuracy <- safe_div(
TP + TN,
TP + TN + FP + FN
)
precision <- safe_div(
TP,
TP + FP
)
recall <- safe_div(
TP,
TP + FN
)
specificity <- safe_div(
TN,
TN + FP
)
f1 <- safe_div(
2 * precision * recall,
precision + recall
)
# Menyimpan hasil evaluasi
hasil.evaluasi[[nama.model]] <- data.frame(
Model = nama.model,
mtry = m,
num.trees = nt,
OOB_Error = oob,
Accuracy = accuracy,
Precision = precision,
Recall = recall,
Specificity = specificity,
F1_Score = f1
)
# Menyimpan variable importance
hasil.importance[[nama.model]] <- data.frame(
Model = nama.model,
Variabel = names(rf$variable.importance),
Importance = as.numeric(rf$variable.importance)
)
nomor <- nomor + 1
}
}##
## ====================================
## Model: 1
## mtry: 2
## num.trees: 200
## ====================================
##
## ====================================
## Model: 2
## mtry: 2
## num.trees: 500
## ====================================
##
## ====================================
## Model: 3
## mtry: 2
## num.trees: 1000
## ====================================
##
## ====================================
## Model: 4
## mtry: 3
## num.trees: 200
## ====================================
##
## ====================================
## Model: 5
## mtry: 3
## num.trees: 500
## ====================================
##
## ====================================
## Model: 6
## mtry: 3
## num.trees: 1000
## ====================================
##
## ====================================
## Model: 7
## mtry: 5
## num.trees: 200
## ====================================
##
## ====================================
## Model: 8
## mtry: 5
## num.trees: 500
## ====================================
##
## ====================================
## Model: 9
## mtry: 5
## num.trees: 1000
## ====================================
# 6. TABEL HASIL EVALUASI SELURUH MODEL
# Menggabungkan hasil evaluasi
tabel.evaluasi <- bind_rows(hasil.evaluasi)
# Membulatkan kolom numerik saja
tabel.evaluasi <- tabel.evaluasi %>%
mutate(
across(
where(is.numeric),
~ round(.x, 4)
)
)
# Menampilkan hasil evaluasi
print(tabel.evaluasi)## Model mtry num.trees OOB_Error Accuracy Precision Recall
## 1 mtry_2_ntree_200 2 200 0.0292 0.9804 0.9589 0.9859
## 2 mtry_2_ntree_500 2 500 0.0292 0.9755 0.9459 0.9859
## 3 mtry_2_ntree_1000 2 1000 0.0292 0.9706 0.9452 0.9718
## 4 mtry_3_ntree_200 3 200 0.0271 0.9706 0.9577 0.9577
## 5 mtry_3_ntree_500 3 500 0.0292 0.9706 0.9577 0.9577
## 6 mtry_3_ntree_1000 3 1000 0.0271 0.9657 0.9444 0.9577
## 7 mtry_5_ntree_200 5 200 0.0292 0.9608 0.9437 0.9437
## 8 mtry_5_ntree_500 5 500 0.0292 0.9608 0.9437 0.9437
## 9 mtry_5_ntree_1000 5 1000 0.0271 0.9559 0.9429 0.9296
## Specificity F1_Score
## 1 0.9774 0.9722
## 2 0.9699 0.9655
## 3 0.9699 0.9583
## 4 0.9774 0.9577
## 5 0.9774 0.9577
## 6 0.9699 0.9510
## 7 0.9699 0.9437
## 8 0.9699 0.9437
## 9 0.9699 0.9362
# Mengurutkan berdasarkan F1-Score dan Accuracy
tabel.urut <- tabel.evaluasi %>%
arrange(
desc(F1_Score),
desc(Accuracy)
)
print(tabel.urut)## Model mtry num.trees OOB_Error Accuracy Precision Recall
## 1 mtry_2_ntree_200 2 200 0.0292 0.9804 0.9589 0.9859
## 2 mtry_2_ntree_500 2 500 0.0292 0.9755 0.9459 0.9859
## 3 mtry_2_ntree_1000 2 1000 0.0292 0.9706 0.9452 0.9718
## 4 mtry_3_ntree_200 3 200 0.0271 0.9706 0.9577 0.9577
## 5 mtry_3_ntree_500 3 500 0.0292 0.9706 0.9577 0.9577
## 6 mtry_3_ntree_1000 3 1000 0.0271 0.9657 0.9444 0.9577
## 7 mtry_5_ntree_200 5 200 0.0292 0.9608 0.9437 0.9437
## 8 mtry_5_ntree_500 5 500 0.0292 0.9608 0.9437 0.9437
## 9 mtry_5_ntree_1000 5 1000 0.0271 0.9559 0.9429 0.9296
## Specificity F1_Score
## 1 0.9774 0.9722
## 2 0.9699 0.9655
## 3 0.9699 0.9583
## 4 0.9774 0.9577
## 5 0.9774 0.9577
## 6 0.9699 0.9510
## 7 0.9699 0.9437
## 8 0.9699 0.9437
## 9 0.9699 0.9362
Pembentukan model Random Forest dilakukan dengan mengombinasikan nilai mtry sebesar 2, 3, dan 5 serta jumlah pohon (num.trees) sebesar 200, 500, dan 1000. Dengan demikian, diperoleh sembilan kombinasi model yang dilatih menggunakan data training. Parameter mtry menunjukkan banyaknya variabel prediktor yang dipilih secara acak sebagai kandidat pemisah pada setiap pembentukan pohon, sedangkan num.trees menunjukkan jumlah pohon keputusan yang dibangun dalam model. Seluruh model menggunakan min.node.size sebesar 1, pengambilan sampel dengan pengembalian (replace = TRUE), dan permutation importance untuk mengukur kontribusi variabel.
Pengujian setiap model dilakukan menggunakan data testing yang tidak digunakan pada proses pelatihan. Kinerja model dievaluasi melalui accuracy, precision, recall, specificity, F1-Score, serta OOB Error. Penggunaan beberapa kombinasi parameter bertujuan untuk mengetahui konfigurasi yang memberikan hasil klasifikasi paling baik pada data BreastCancer.
# 7. MENENTUKAN MODEL TERBAIK
# Memilih model berdasarkan F1-Score tertinggi
tabel.valid <- tabel.evaluasi %>%
filter(
!is.na(F1_Score),
!is.na(Accuracy)
) %>%
arrange(
desc(F1_Score),
desc(Accuracy)
)
# Mengambil nama model terbaik
model.terbaik <- tabel.valid$Model[1]
# Menampilkan model terbaik
cat("\nModel terbaik:", model.terbaik, "\n")##
## Model terbaik: mtry_2_ntree_200
# Mengambil objek model terbaik
rf.terbaik <- hasil.model[[model.terbaik]]
# Menampilkan model terbaik
print(rf.terbaik)## Ranger result
##
## Call:
## ranger(Class ~ ., data = bc.train, num.trees = nt, mtry = m, min.node.size = 1, replace = TRUE, sample.fraction = 1, importance = "permutation", seed = 234)
##
## Type: Classification
## Number of trees: 200
## Sample size: 479
## Number of independent variables: 9
## Mtry: 2
## Target node size: 1
## Variable importance mode: permutation
## Splitrule: gini
## OOB prediction error: 2.92 %
# 8. CONFUSION MATRIX MODEL TERBAIK
# Prediksi model terbaik
prediksi.terbaik <- predict(
rf.terbaik,
data = bc.test
)$predictions
prediksi.terbaik <- factor(
prediksi.terbaik,
levels = c("benign", "malignant")
)
aktual <- factor(
bc.test$Class,
levels = c("benign", "malignant")
)
# Membentuk confusion matrix
cm.terbaik <- confusionMatrix(
data = prediksi.terbaik,
reference = aktual,
positive = "malignant"
)
# Menampilkan confusion matrix
print(cm.terbaik)## Confusion Matrix and Statistics
##
## Reference
## Prediction benign malignant
## benign 130 1
## malignant 3 70
##
## Accuracy : 0.9804
## 95% CI : (0.9506, 0.9946)
## No Information Rate : 0.652
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.9571
##
## Mcnemar's Test P-Value : 0.6171
##
## Sensitivity : 0.9859
## Specificity : 0.9774
## Pos Pred Value : 0.9589
## Neg Pred Value : 0.9924
## Prevalence : 0.3480
## Detection Rate : 0.3431
## Detection Prevalence : 0.3578
## Balanced Accuracy : 0.9817
##
## 'Positive' Class : malignant
##
## Predicted
## Actual benign malignant
## benign 130 3
## malignant 1 70
Berdasarkan perbandingan nilai accuracy dan F1-Score, model dengan mtry = 2 dan num.trees = 200 dipilih sebagai model Random Forest terbaik. Model tersebut menghasilkan accuracy sebesar 98,04% dan F1-Score sebesar 97,22%, yang merupakan nilai tertinggi di antara sembilan kombinasi model yang diuji. Setelah model terbaik ditentukan, prediksi kelas dilakukan terhadap data testing dan hasilnya dibandingkan dengan kelas aktual melalui confusion matrix. Dalam evaluasi ini, kelas malignant ditetapkan sebagai kelas positif.
Berdasarkan confusion matrix model terbaik, dari 133 observasi aktual benign, sebanyak 130 observasi diprediksi benar sebagai benign, sedangkan 3 observasi salah diprediksi sebagai malignant. Dari 71 observasi aktual malignant, sebanyak 70 observasi diprediksi benar sebagai malignant dan 1 observasi salah diprediksi sebagai benign. Dengan demikian, terdapat 200 prediksi benar dan 4 prediksi salah dari total 204 observasi pada data testing. Hasil evaluasi menghasilkan accuracy sebesar 98,04%, sensitivity sebesar 98,59%, specificity sebesar 97,74%, precision sebesar 95,89%, dan F1-Score sebesar 97,22%. Sensitivity menunjukkan kemampuan model mengenali observasi malignant, sedangkan specificity menunjukkan kemampuan model mengenali observasi benign. Nilai-nilai tersebut memperlihatkan bahwa model terbaik mampu mengklasifikasikan kedua kelas dengan baik pada data testing yang digunakan.
# 9. VISUALISASI ACCURACY DAN F1-SCORE
# Mengubah data ke format panjang
data.metric <- tabel.evaluasi %>%
select(
Model,
Accuracy,
F1_Score
) %>%
pivot_longer(
cols = c(Accuracy, F1_Score),
names_to = "Metrik",
values_to = "Nilai"
)
# Visualisasi Accuracy dan F1-Score
ggplot(
data.metric,
aes(
x = Model,
y = Nilai,
fill = Metrik
)
) +
geom_col(position = "dodge") +
labs(
title = "Perbandingan Accuracy dan F1-Score",
x = "Model Random Forest",
y = "Nilai Evaluasi"
) +
scale_y_continuous(
limits = c(0, 1.05)
) +
theme_minimal() +
theme(
axis.text.x = element_text(
angle = 45,
hjust = 1
)
)Berdasarkan hasil, nilai accuracy dan F1-Score dari sembilan model Random Forest secara umum tergolong tinggi. Nilai accuracy berada pada rentang 95,59% sampai 98,04%, sedangkan F1-Score berada pada rentang 93,62% sampai 97,22%. Model dengan mtry = 2 dan num.trees = 200 menghasilkan accuracy tertinggi sebesar 98,04% dan F1-Score tertinggi sebesar 97,22%. Model tersebut menunjukkan bahwa 98,04% observasi pada data testing berhasil diklasifikasikan dengan benar, sementara nilai F1-Score yang tinggi menunjukkan keseimbangan yang baik antara precision dan recall.
Pada kombinasi mtry = 2, peningkatan jumlah pohon dari 200 menjadi 500 dan 1000 diikuti penurunan accuracy dari 98,04% menjadi 97,55% dan 97,06%. Pola penurunan juga terlihat pada beberapa kombinasi mtry lainnya. Dengan demikian, penambahan jumlah pohon tidak selalu meningkatkan kinerja klasifikasi pada data testing. Berdasarkan kriteria pemilihan yang mengutamakan F1-Score tertinggi dan kemudian accuracy, model mtry = 2 dan num.trees = 200 dipilih sebagai model terbaik.
# 10. VISUALISASI OOB ERROR
# Mengambil nilai OOB Error setiap model
data.oob <- tabel.evaluasi %>%
select(
Model,
OOB_Error
)
# Visualisasi OOB Error
ggplot(
data.oob,
aes(
x = Model,
y = OOB_Error
)
) +
geom_col(
fill = "steelblue",
width = 0.7
) +
labs(
title = "Perbandingan OOB Error Random Forest",
x = "Model Random Forest",
y = "OOB Error"
) +
theme_minimal() +
theme(
axis.text.x = element_text(
angle = 45,
hjust = 1
)
)Berdasarkan hasil memperlihatkan nilai OOB Error dari sembilan model Random Forest yang berada pada rentang 0,0271 hingga 0,0292 atau sekitar 2,71% sampai 2,92%. Nilai OOB Error terendah sebesar 2,71% diperoleh pada model dengan mtry = 3 dan num.trees = 200, mtry = 3 dan num.trees = 1000, serta mtry = 5 dan num.trees = 1000. Sementara itu, model lainnya memiliki OOB Error sebesar 2,92%. Perbedaan nilai OOB Error antarmodel relatif kecil.
Model terbaik berdasarkan F1-Score dan accuracy, yaitu mtry = 2 dan num.trees = 200, memiliki OOB Error sebesar 2,92%. Hal ini menunjukkan bahwa model dengan OOB Error paling rendah tidak selalu menjadi model dengan hasil evaluasi testing terbaik. OOB Error menggambarkan kesalahan prediksi internal berdasarkan observasi yang tidak terpilih dalam sampel bootstrap pada pembentukan pohon, sedangkan accuracy dan F1-Score pada pembahasan ini dihitung berdasarkan data testing. Oleh karena itu, pemilihan model mempertimbangkan hasil evaluasi pada data testing sesuai kriteria yang telah ditetapkan.
# 11. VARIABLE IMPORTANCE MODEL TERBAIK
# Mengambil variable importance
importance.terbaik <- data.frame(
Variabel = names(rf.terbaik$variable.importance),
Importance = as.numeric(
rf.terbaik$variable.importance
)
)
# Mengurutkan variable importance
importance.terbaik <- importance.terbaik %>%
arrange(desc(Importance))
# Menampilkan hasil variable importance
print(importance.terbaik)## Variabel Importance
## 1 Bare.nuclei 0.083924522
## 2 Cell.size 0.078718154
## 3 Cell.shape 0.060967868
## 4 Cl.thickness 0.024489152
## 5 Bl.cromatin 0.021478062
## 6 Normal.nucleoli 0.020446839
## 7 Marg.adhesion 0.019251533
## 8 Epith.c.size 0.011737675
## 9 Mitoses 0.003751688
# Visualisasi variable importance
ggplot(
importance.terbaik,
aes(
x = reorder(Variabel, Importance),
y = Importance
)
) +
geom_col(fill = "steelblue") +
coord_flip() +
labs(
title = "Variable Importance Model Terbaik",
x = "Variabel",
y = "Permutation Importance"
) +
theme_minimal()Berdasarkan hasil menunjukkan tingkat kepentingan sembilan variabel prediktor pada model terbaik berdasarkan permutation importance. Variabel Bare.nuclei memiliki nilai importance tertinggi sebesar 0,0839, diikuti Cell.size sebesar 0,0787 dan Cell.shape sebesar 0,0610. Ketiga variabel tersebut memiliki kontribusi relatif lebih besar dibandingkan variabel prediktor lainnya dalam membantu model melakukan klasifikasi.
Variabel Cl.thickness memiliki nilai importance sebesar 0,0245, Bl.cromatin sebesar 0,0215, Normal.nucleoli sebesar 0,0204, dan Marg.adhesion sebesar 0,0193. Selanjutnya, Epith.c.size memiliki nilai sebesar 0,0117, sedangkan Mitoses memiliki nilai terendah sebesar 0,0038. Hasil ini menunjukkan bahwa kontribusi setiap prediktor dalam model tidak sama. Nilai permutation importance menunjukkan kontribusi prediktif variabel dalam model, bukan hubungan sebab-akibat.
# 12. PERBANDINGAN VARIABLE IMPORTANCE SELURUH MODEL
# Menggabungkan variable importance
data.importance <- bind_rows(hasil.importance)
# Menampilkan hasil
print(data.importance)## Model Variabel Importance
## 1 mtry_2_ntree_200 Cl.thickness 0.024489152
## 2 mtry_2_ntree_200 Cell.size 0.078718154
## 3 mtry_2_ntree_200 Cell.shape 0.060967868
## 4 mtry_2_ntree_200 Marg.adhesion 0.019251533
## 5 mtry_2_ntree_200 Epith.c.size 0.011737675
## 6 mtry_2_ntree_200 Bare.nuclei 0.083924522
## 7 mtry_2_ntree_200 Bl.cromatin 0.021478062
## 8 mtry_2_ntree_200 Normal.nucleoli 0.020446839
## 9 mtry_2_ntree_200 Mitoses 0.003751688
## 10 mtry_2_ntree_500 Cl.thickness 0.026747140
## 11 mtry_2_ntree_500 Cell.size 0.077257729
## 12 mtry_2_ntree_500 Cell.shape 0.062974113
## 13 mtry_2_ntree_500 Marg.adhesion 0.019112201
## 14 mtry_2_ntree_500 Epith.c.size 0.013222617
## 15 mtry_2_ntree_500 Bare.nuclei 0.080504597
## 16 mtry_2_ntree_500 Bl.cromatin 0.021877891
## 17 mtry_2_ntree_500 Normal.nucleoli 0.021841450
## 18 mtry_2_ntree_500 Mitoses 0.003090966
## 19 mtry_2_ntree_1000 Cl.thickness 0.026309142
## 20 mtry_2_ntree_1000 Cell.size 0.077885328
## 21 mtry_2_ntree_1000 Cell.shape 0.062585865
## 22 mtry_2_ntree_1000 Marg.adhesion 0.018885437
## 23 mtry_2_ntree_1000 Epith.c.size 0.014006791
## 24 mtry_2_ntree_1000 Bare.nuclei 0.081727341
## 25 mtry_2_ntree_1000 Bl.cromatin 0.020503315
## 26 mtry_2_ntree_1000 Normal.nucleoli 0.019947983
## 27 mtry_2_ntree_1000 Mitoses 0.003346598
## 28 mtry_3_ntree_200 Cl.thickness 0.027788431
## 29 mtry_3_ntree_200 Cell.size 0.091653406
## 30 mtry_3_ntree_200 Cell.shape 0.062810795
## 31 mtry_3_ntree_200 Marg.adhesion 0.019128466
## 32 mtry_3_ntree_200 Epith.c.size 0.009877622
## 33 mtry_3_ntree_200 Bare.nuclei 0.097215967
## 34 mtry_3_ntree_200 Bl.cromatin 0.017950453
## 35 mtry_3_ntree_200 Normal.nucleoli 0.015967442
## 36 mtry_3_ntree_200 Mitoses 0.003686372
## 37 mtry_3_ntree_500 Cl.thickness 0.026031551
## 38 mtry_3_ntree_500 Cell.size 0.085328389
## 39 mtry_3_ntree_500 Cell.shape 0.065123301
## 40 mtry_3_ntree_500 Marg.adhesion 0.019338940
## 41 mtry_3_ntree_500 Epith.c.size 0.010949414
## 42 mtry_3_ntree_500 Bare.nuclei 0.099119249
## 43 mtry_3_ntree_500 Bl.cromatin 0.018814782
## 44 mtry_3_ntree_500 Normal.nucleoli 0.014788223
## 45 mtry_3_ntree_500 Mitoses 0.003211898
## 46 mtry_3_ntree_1000 Cl.thickness 0.024814485
## 47 mtry_3_ntree_1000 Cell.size 0.085535688
## 48 mtry_3_ntree_1000 Cell.shape 0.059257703
## 49 mtry_3_ntree_1000 Marg.adhesion 0.019528413
## 50 mtry_3_ntree_1000 Epith.c.size 0.011860487
## 51 mtry_3_ntree_1000 Bare.nuclei 0.100283344
## 52 mtry_3_ntree_1000 Bl.cromatin 0.019201313
## 53 mtry_3_ntree_1000 Normal.nucleoli 0.016485996
## 54 mtry_3_ntree_1000 Mitoses 0.003185340
## 55 mtry_5_ntree_200 Cl.thickness 0.023260225
## 56 mtry_5_ntree_200 Cell.size 0.089778781
## 57 mtry_5_ntree_200 Cell.shape 0.042713777
## 58 mtry_5_ntree_200 Marg.adhesion 0.020899801
## 59 mtry_5_ntree_200 Epith.c.size 0.008615232
## 60 mtry_5_ntree_200 Bare.nuclei 0.125936890
## 61 mtry_5_ntree_200 Bl.cromatin 0.014237292
## 62 mtry_5_ntree_200 Normal.nucleoli 0.021657685
## 63 mtry_5_ntree_200 Mitoses 0.002635523
## 64 mtry_5_ntree_500 Cl.thickness 0.021676702
## 65 mtry_5_ntree_500 Cell.size 0.090904474
## 66 mtry_5_ntree_500 Cell.shape 0.045966760
## 67 mtry_5_ntree_500 Marg.adhesion 0.019536614
## 68 mtry_5_ntree_500 Epith.c.size 0.009305183
## 69 mtry_5_ntree_500 Bare.nuclei 0.124282812
## 70 mtry_5_ntree_500 Bl.cromatin 0.015268145
## 71 mtry_5_ntree_500 Normal.nucleoli 0.020300877
## 72 mtry_5_ntree_500 Mitoses 0.003024808
## 73 mtry_5_ntree_1000 Cl.thickness 0.022686356
## 74 mtry_5_ntree_1000 Cell.size 0.091093145
## 75 mtry_5_ntree_1000 Cell.shape 0.043806238
## 76 mtry_5_ntree_1000 Marg.adhesion 0.018867468
## 77 mtry_5_ntree_1000 Epith.c.size 0.009737954
## 78 mtry_5_ntree_1000 Bare.nuclei 0.121396617
## 79 mtry_5_ntree_1000 Bl.cromatin 0.016189366
## 80 mtry_5_ntree_1000 Normal.nucleoli 0.020778434
## 81 mtry_5_ntree_1000 Mitoses 0.003221466
# Visualisasi variable importance seluruh model
ggplot(
data.importance,
aes(
x = Variabel,
y = Importance,
fill = Model
)
) +
geom_col(position = "dodge") +
labs(
title = "Perbandingan Variable Importance Seluruh Model",
x = "Variabel",
y = "Permutation Importance"
) +
theme_minimal() +
theme(
axis.text.x = element_text(
angle = 45,
hjust = 1
)
)Berdasarkan hasil, tingkat kepentingan variabel dibandingkan pada seluruh kombinasi mtry dan num.trees. Secara umum, Bare.nuclei, Cell.size, dan Cell.shape menunjukkan nilai importance yang relatif tinggi pada berbagai konfigurasi model. Bare.nuclei mencapai nilai tertinggi sekitar 0,1259 pada kombinasi mtry = 5 dan num.trees = 200. Cell.size memiliki nilai sekitar 0,0773 sampai 0,0917, sedangkan Cell.shape berada pada kisaran 0,0427 sampai 0,0651..
Sebaliknya, Mitoses secara konsisten memiliki nilai importance paling rendah pada seluruh model, yaitu sekitar 0,0026 sampai 0,0037. Variabel Cl.thickness, Bl.cromatin, Normal.nucleoli, Marg.adhesion, dan Epith.c.size menunjukkan tingkat kepentingan di antara kelompok variabel dengan importance tinggi dan rendah. Perubahan nilai importance menunjukkan bahwa besarnya kontribusi relatif suatu variabel dapat berubah sesuai konfigurasi model. Meskipun demikian, Bare.nuclei, Cell.size, dan Cell.shape tetap menjadi variabel yang relatif dominan.
Berdasarkan hasil dapat disimpulkan bahwa metode Random Forest mampu melakukan klasifikasi pada dataset BreastCancer dengan kinerja yang sangat baik. Model terbaik diperoleh menggunakan kombinasi parameter mtry = 2 dan num.trees = 200, dengan nilai accuracy sebesar 98,04% dan F1-Score sebesar 97,22%. Hasil evaluasi confusion matrix menunjukkan bahwa model mampu mengklasifikasikan 200 dari 204 observasi data testing dengan benar. Selain itu, hasil analisis variable importance menunjukkan bahwa variabel Bare.nuclei, Cell.size, dan Cell.shape merupakan variabel yang memiliki kontribusi relatif terbesar dalam proses klasifikasi, sedangkan Mitoses memiliki kontribusi paling rendah. Dengan demikian, Random Forest dapat digunakan sebagai metode klasifikasi untuk membedakan kelas benign dan malignant berdasarkan variabel prediktor pada dataset BreastCancer.
Fransiska, H. (2026). Modul Praktikum Machine Learning and Modern Prediction. Laboratorium Matematika Fakultas Matematika dan Ilmu Pengetahuan Alam 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.
Hidayatulloh, N. G. T., Notodiputro, K. A., & Angraini, Y. (2022). Perbandingan kinerja Random Forest dan Double Random Forest untuk klasifikasi status kemiskinan di level kabupaten/kota. IPB University.
Purwanto, A., Sartono, B., & Notodiputro, K. A. (2025). A comparison of Random Forest and Double Random Forest: Dropout rates of madrasah students in Indonesia. BAREKENG: Jurnal Ilmu Matematika dan Terapan, 19(1), 227–236.
Ramayanti, F., Vionanda, D., Permana, D., & Zilrahmi. (2023). Application of Random Forest to Identify for Poor Households in West Sumatera Province. UNP Journal of Statistics and Data Science, 1(2), 97–104.