Awalan

Sebelumnya kita telah berkenalan dengan Rotation Forest di Medium. Pada tulisan ini kita akan berdiskusi mengenai penerapan rotation forest menggunakan R. (remake: source)

Algoritma dasar dari rotation forest adalah sebagai berikut:
(Rodriguez et.al, 2006)

Yuk Kita mulai saja

Penerapan Rotation Forest di R

Sapa salam dulu

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.

Load package yang dibutuhkan

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

Persiapan

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
informasi
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, ...
Split data

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)
Fitur (x) dan Target (y)
y<-training_set$Peristiwa_Kematian
x<-as.matrix.data.frame(training_set)

Cek proposi Target

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
Presentase Peristiwa Kematian

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.

Model

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.

Membuat model Tanpa Penanganan

train_rf <- rotationForest(x, y, verbose = FALSE)

Prediksi

pred = predict(train_rf, test_set)

Confusion Matriks

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          
## 

Rotation Forest + Oversampling

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

Split data

set.seed(170995)
split = sample.split(data2$Peristiwa_Kematian, SplitRatio = 0.8)
training_set2 = subset(data2, split == TRUE)
test_set2 = subset(data2, split == FALSE)
Fitur (x) dan Target (y)
y2<-training_set2$Peristiwa_Kematian
x2<-as.matrix.data.frame(training_set2)

Model

train_rf2 <- rotationForest(x2, y2, verbose = FALSE)

Prediksi

pred2 = predict(train_rf2, test_set2)

Confusion Matriks

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         
## 

Rotation Forest + Undersampling

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

Split data

set.seed(170995)
split = sample.split(data3$Peristiwa_Kematian, SplitRatio = 0.8)
training_set3 = subset(data3, split == TRUE)
test_set3 = subset(data3, split == FALSE)
Fitur (x) dan Target (y)
y3<-training_set3$Peristiwa_Kematian
x3<-as.matrix.data.frame(training_set3)

Model

train_rf3 <- rotationForest(x3, y3, verbose = FALSE)

Prediksi

pred3 = predict(train_rf3, test_set3)

Confusion Matriks

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          
## 

REFERENSI

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.