Sebelumnya kita telah berkenalan dengan Rotation Forest di Medium. Pada tulisan ini kita akan berdiskusi mengenai penerapan rotation forest menggunakan R. (remake: source)
Halo teman-teman, pada RPubs kali ini kita mau mencoba menerapkan metode rotation forest pada Data Heart Failure.
Data ini didapat dari Kaggle.
Catatan: Terdapat 13 kolom, dimana 12 variabel independen (fitur) dan 1 variabel dependen (target), yang dapat digunakan untuk memprediksi kematian akibat gagal jantung menggunakan rotation forest. Yuk mari kita coba!
Salah satu fungsi yang dapat digunakan untuk menjalankan metode Rotation Forest di R adalah rotationForest()
yang tersedia pada package rotationForest()
. Pertama-tama kita harus mengetik perintah berikut untuk install package rotationForest()
, install.packages(“rotationForest”). Teman-teman dapat membaca dokumentasi rotationForest()
disini atau teman-teman setelah mengisntal package tersebut bisa dicari di bagian package pada R dan bisa membaca dokumentasinya.
library(dplyr)
## Warning: package 'dplyr' was built under R version 3.6.3
##
## 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(rotationForest)
## Warning: package 'rotationForest' was built under R version 3.6.3
## rotationForest 0.1.3
## Change log: rotationForestNews()
library(caret)
## Warning: package 'caret' was built under R version 3.6.3
## Loading required package: lattice
## Loading required package: ggplot2
## Warning: package 'ggplot2' was built under R version 3.6.3
library(caTools)
## Warning: package 'caTools' was built under R version 3.6.3
library(rpart)
## Warning: package 'rpart' was built under R version 3.6.3
Pada tahap ini, sebelumnya sudah kita bahas memvisualisasikan data yang akan kita gunakan ini. Sebelum kita membuat model dari data tersebut, langkah pertama adalah kita jelajahi dahulu data yang akan kita pakai. Bagaimana sebaran datanya, apakah ada informasi tidak lengkap, dan lain-lain. Selengkapnya, teman-teman dapat membaca medium. Nah yuk, sekarang kita membaca data nya kembali.
set.seed(170995)
data <- read.csv("heart_failure_clinical_records_dataset.csv",sep =";", header = TRUE)
head(data) #Melihat data teratas
## umur anaemia creatinine_phosphokinase diabetes ejection_fraction
## 1 75 0 582 0 20
## 2 55 0 7861 0 38
## 3 65 0 146 0 20
## 4 50 1 111 0 20
## 5 65 1 160 1 20
## 6 90 1 47 0 40
## tekanan_darah_tinggi platelets serum_creatinine serum_sodium Jenis_kelamin
## 1 1 265000 1.9 130 1
## 2 0 263358 1.1 136 1
## 3 0 162000 1.3 129 1
## 4 0 210000 1.9 137 1
## 5 0 327000 2.7 116 0
## 6 1 204000 2.1 132 1
## smoking time Peristiwa_Kematian
## 1 0 4 1
## 2 0 6 1
## 3 1 7 1
## 4 0 7 1
## 5 0 8 1
## 6 1 8 1
tail(data) #Melihat data terbawah
## umur anaemia creatinine_phosphokinase diabetes ejection_fraction
## 294 63 1 103 1 35
## 295 62 0 61 1 38
## 296 55 0 1820 0 38
## 297 45 0 2060 1 60
## 298 45 0 2413 0 38
## 299 50 0 196 0 45
## tekanan_darah_tinggi platelets serum_creatinine serum_sodium Jenis_kelamin
## 294 0 179000 0.9 136 1
## 295 1 155000 1.1 143 1
## 296 0 270000 1.2 139 0
## 297 0 742000 0.8 138 0
## 298 0 140000 1.4 140 1
## 299 0 395000 1.6 136 1
## smoking time Peristiwa_Kematian
## 294 1 270 0
## 295 1 270 0
## 296 0 271 0
## 297 0 278 0
## 298 1 280 0
## 299 1 285 0
glimpse(data)
## Observations: 299
## Variables: 13
## $ umur <dbl> 75, 55, 65, 50, 65, 90, 75, 60, 65, 80, 75...
## $ anaemia <int> 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, ...
## $ creatinine_phosphokinase <int> 582, 7861, 146, 111, 160, 47, 246, 315, 15...
## $ diabetes <int> 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, ...
## $ ejection_fraction <int> 20, 38, 20, 20, 20, 40, 15, 60, 65, 35, 38...
## $ tekanan_darah_tinggi <int> 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, ...
## $ platelets <dbl> 265000, 263358, 162000, 210000, 327000, 20...
## $ serum_creatinine <dbl> 1.90, 1.10, 1.30, 1.90, 2.70, 2.10, 1.20, ...
## $ serum_sodium <int> 130, 136, 129, 137, 116, 132, 137, 131, 13...
## $ Jenis_kelamin <int> 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, ...
## $ smoking <int> 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, ...
## $ time <int> 4, 6, 7, 7, 8, 8, 10, 10, 10, 10, 10, 10, ...
## $ Peristiwa_Kematian <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
Pada pembuatan model ini kita akan membagi data training dan testing menjadi 80% dan 20%.
set.seed(170995)
split = sample.split(data$Peristiwa_Kematian, SplitRatio = 0.8)
training_set = subset(data, split == TRUE)
test_set = subset(data, split == FALSE)
y<-training_set$Peristiwa_Kematian
x<-as.matrix.data.frame(training_set)
Pada tahap ini kita melihat jumlah peristiwa kematian, berapa banyak yang hidup dan yang meninggal.
prop.table(table(data$Peristiwa_Kematian))
##
## 0 1
## 0.6789298 0.3210702
Target<-as.factor(data$Peristiwa_Kematian)
summary(Target)
## 0 1
## 203 96
Pada gambar diatas dapat dipastikan bahwa dataset imbalance, karena jumlah pasien yang hidup (peristiwa kematian = 0) sebanyak 203, sedangkan yang meninggal (peristiwa kematian = 1) sebanyak 96. Secara statistik terdapat 32,11% positif dan 67,89% negatif.
Pada pembentukkan model menggunakan metode rotation forest, untuk menangani data tidak seimbang (imbalance data), pada tulisan ini akan melihat model yang menggunakan metode oversampling, undersampling, dan tanpa penanganan.
train_rf <- rotationForest(x, y, verbose = FALSE)
pred = predict(train_rf, test_set)
test_set$Peristiwa_Kematian<-as.factor(test_set$Peristiwa_Kematian)
pred<-as.factor(pred)
confusionMatrix(pred,test_set$Peristiwa_Kematian)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 41 0
## 1 0 19
##
## Accuracy : 1
## 95% CI : (0.9404, 1)
## No Information Rate : 0.6833
## P-Value [Acc > NIR] : 1.197e-10
##
## Kappa : 1
##
## Mcnemar's Test P-Value : NA
##
## Sensitivity : 1.0000
## Specificity : 1.0000
## Pos Pred Value : 1.0000
## Neg Pred Value : 1.0000
## Prevalence : 0.6833
## Detection Rate : 0.6833
## Detection Prevalence : 0.6833
## Balanced Accuracy : 1.0000
##
## 'Positive' Class : 0
##
Penanganan data imbalance pada R dapat menggunakan fungsi ROSE()
dengan pengaturan method = “over”. Pertama-tama teman-teman harus menginstal fungsi tersebut dengan cara install.packages(“ROSE”). Setelah itu daftarkan package ROSE()
.
library(ROSE)
## Warning: package 'ROSE' was built under R version 3.6.3
## Loaded ROSE 0.0-3
table(data$Peristiwa_Kematian)
##
## 0 1
## 203 96
data2 <- ovun.sample(Peristiwa_Kematian ~ ., data = data,
method = "over", N = 406)$data
table(data2$Peristiwa_Kematian)
##
## 0 1
## 203 203
set.seed(170995)
split = sample.split(data2$Peristiwa_Kematian, SplitRatio = 0.8)
training_set2 = subset(data2, split == TRUE)
test_set2 = subset(data2, split == FALSE)
y2<-training_set2$Peristiwa_Kematian
x2<-as.matrix.data.frame(training_set2)
train_rf2 <- rotationForest(x2, y2, verbose = FALSE)
pred2 = predict(train_rf2, test_set2)
test_set2$Peristiwa_Kematian<-as.factor(test_set2$Peristiwa_Kematian)
pred2<-as.factor(pred2)
confusionMatrix(pred2,test_set2$Peristiwa_Kematian)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 41 0
## 1 0 41
##
## Accuracy : 1
## 95% CI : (0.956, 1)
## No Information Rate : 0.5
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 1
##
## Mcnemar's Test P-Value : NA
##
## Sensitivity : 1.0
## Specificity : 1.0
## Pos Pred Value : 1.0
## Neg Pred Value : 1.0
## Prevalence : 0.5
## Detection Rate : 0.5
## Detection Prevalence : 0.5
## Balanced Accuracy : 1.0
##
## 'Positive' Class : 0
##
Penanganan data imbalance pada R dapat menggunakan fungsi ROSE()
dengan pengaturan method = “under”.
table(data$Peristiwa_Kematian)
##
## 0 1
## 203 96
data3 <- ovun.sample(Peristiwa_Kematian ~ ., data = data,
method = "under", N = 192)$data
table(data3$Peristiwa_Kematian)
##
## 0 1
## 96 96
set.seed(170995)
split = sample.split(data3$Peristiwa_Kematian, SplitRatio = 0.8)
training_set3 = subset(data3, split == TRUE)
test_set3 = subset(data3, split == FALSE)
y3<-training_set3$Peristiwa_Kematian
x3<-as.matrix.data.frame(training_set3)
train_rf3 <- rotationForest(x3, y3, verbose = FALSE)
pred3 = predict(train_rf3, test_set3)
test_set3$Peristiwa_Kematian<-as.factor(test_set3$Peristiwa_Kematian)
pred3<-as.factor(pred3)
confusionMatrix(pred3,test_set3$Peristiwa_Kematian)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 19 0
## 1 0 19
##
## Accuracy : 1
## 95% CI : (0.9075, 1)
## No Information Rate : 0.5
## P-Value [Acc > NIR] : 3.638e-12
##
## Kappa : 1
##
## Mcnemar's Test P-Value : NA
##
## Sensitivity : 1.0
## Specificity : 1.0
## Pos Pred Value : 1.0
## Neg Pred Value : 1.0
## Prevalence : 0.5
## Detection Rate : 0.5
## Detection Prevalence : 0.5
## Balanced Accuracy : 1.0
##
## 'Positive' Class : 0
##
Rodriguez, J. J., & Kuncheva, L. I. (2006). Rotation Forest: A New Classifier Ensemble Method. IEEE Transactions on Pattern Analysis and Machine Intelligence, Vol 28, No. 10.