library(rsample)
# untuk persiapan data
library(dplyr)
library(readxl)
# untuk keperluan machine learning
library(partykit)
library(randomForest)
library(caret)
# untuk keperluan evaluasi
library(ROCR)
Setelah berkenalan dengan Naive Bayes, terdapat model lainnya yang menganut konsep tree based. Model tree based ini dianggap sebagai salah satu model yang robust dan menjadi fondasi model-model terbaik sekarang.
Akan ada 2 model yang kita pelajari, yaitu:
Decision tree merupakan tree-based model yang cukup sederhana dengan performa yang robust/powerful untuk membuat prediksi. Seperti namanya, decision tree menghasilkan struktur pohon yang tersusun dari pertanyaan-pertanyaan yang berkaitan dengan variabel prediktor. Pertanyaan-pertanyaan ini akan menjadi guidance dalam menentukan hasil prediksi.
🗒️ Note: Selain klasifikasi, decision tree juga dapat digunakna nuntuk kasus regresi.
Outlook
.Humidity
.Tingkat homogen ini dapat diukur menggunakan entropy dan information gain.
Secara intuitif, decision tree memilih predictor yang sebisa mungkin menyeragamkan (homogen) target variabel pada leaf node.
Berikut adalah contoh visualisasi decision tree dari kasus di atas.
dine <- read.csv("data_input/dineout.csv",
sep = ";",
stringsAsFactors = T)
dine_tree <- ctree(formula = Dine.Out ~ .,
data = dine,
control = ctree_control(mincriterion = 0.5,
minsplit = 0,
minbucket = 0))
plot(dine_tree, type = "simple")
Dalam kesempatan kali ini, kita akan menggunakan kembali data pada material C1 minggu kemarin. Tujuan dari penggunaan data ini adalah agar kita dapat membandingkan peforma dari model Logistic Regression & K-NN, dengan model tree based.
# Read Data
credit <- read_xlsx("data_input/credit_taiwan_clean.xlsx")
# Mengubah format data
credit <-
credit %>%
select(-id) %>%
mutate_at( vars(sex, education, marriage, gb_flag), as.factor )
Dataset memiliki 25 kolom dan 30,952 dengan penjelasan sebagai berikut:
id
= id debiturlimit_bal
= Besaran kredit limit yang diberikan dalam
dolar NTsex
= jenis kelamin
education
= Pendidikan terakhir
marriage
= Status pernikahan
age
= Usia dalam tahunpay_*
= Status pembayaran dalam bulan April (1) -
September (6).
bill_amt*
= Jumlah tagihan pada bulan April (1) -
September (6) dalam dolar NTpay_amt*
= Jumlah pembayaran/pengeluaran sebelumnya
pada bulan April (1) - September(6) dalam dolar NTgb_flag
= Flagging pembayaran default (gagal bayar)
pada bulan berikutnya
Pada material kali ini, kita juga akan menambah wawasan dalam melakukan proses data preprocessing, berikut adalah beberapa tambahannya
Dalam melakukan pembagian data menjadi data train dan test, terdapat
pendekatan lainnya yang dapat digunakan, yaitu
initial_split()
Cara kerjanya sendiri kita akan menggunakan parameter
data =
: untuk memasukan data yang akan dibagiprop =
: jumlah proporsi data yang akan dijadikan data
trainingSelain dari fungsi tersebut untuk implemetnasinya kita akan
menggunakan fungsi training()
&
testing()
.
RNGkind(sample.kind = "Rounding")
set.seed(100)
splitter <- initial_split(data = credit, prop = 0.8)
credit_train <- training(splitter)
credit_test <- testing(splitter)
## .
## 0 1
## 13349 11412
Dalam machine learning, upsampling dan downsampling digunakan untuk menangani imbalanced data, yaitu ketika satu kelas memiliki jauh lebih banyak sampel dibandingkan kelas lainnya.
Upsampling
adalah teknik menambah jumlah sampel
kelas minoritas agar lebih seimbang dengan kelas mayoritas. Caranya bisa
dengan menduplikasi data yang sudah.
Downsampling
adalah kebalikan dari upsampling, yaitu
mengurangi jumlah sampel kelas mayoritas agar lebih seimbang dengan
kelas minoritas.
Fungsi untuk Upsampling dan Downsampling
upSample()
: fungsi untuk upsampling.downSample()
: fungsi untuk downsampling.x
: predictor.y
: target.yname
: nama kolom target.# upsampling
RNGkind(sample.kind = "Rounding")
set.seed(100)
loan_train_up <- upSample(x = credit_train %>% select(-gb_flag),
y = credit_train$gb_flag,
yname = "gb_flag")
loan_train_up$gb_flag %>% table() %>% prop.table()
## .
## 0 1
## 0.5 0.5
Untuk membuat model decision tree, dapat digunakan fungsi
ctree()
dari library partykit
.
🧪 Formula: ctree(formula, data)
formula = y ~ x
y
: variabel target.x
: variabel prediktor.data
: dataframe yang berisikan variabel target dan
prediktor.# tuning model decision tree
tree_credit <- ctree(formula = gb_flag ~ .,
data = loan_train_up
# control = ctree_control(mincriterion = 0.95,
# minsplit = 20,
# minbucket = 10)
)
# prediksi kelas di data training
pred_tuned_train <- predict(tree_credit,
loan_train_up,
type = "response")
# confusion matrix data training
confusionMatrix(pred_tuned_train,
loan_train_up$gb_flag,
positive = "1")
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 10868 885
## 1 2481 12464
##
## Accuracy : 0.8739
## 95% CI : (0.8699, 0.8779)
## No Information Rate : 0.5
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.7478
##
## Mcnemar's Test P-Value : < 0.00000000000000022
##
## Sensitivity : 0.9337
## Specificity : 0.8141
## Pos Pred Value : 0.8340
## Neg Pred Value : 0.9247
## Prevalence : 0.5000
## Detection Rate : 0.4669
## Detection Prevalence : 0.5598
## Balanced Accuracy : 0.8739
##
## 'Positive' Class : 1
##
# prediksi kelas di data testing
pred_tuned_test <- predict(tree_credit,
credit_test,
type = "response")
# confusion matrix data testing
confusionMatrix(pred_tuned_test,
credit_test$gb_flag,
positive = "1")
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 2663 271
## 1 673 2584
##
## Accuracy : 0.8475
## 95% CI : (0.8383, 0.8564)
## No Information Rate : 0.5388
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.6963
##
## Mcnemar's Test P-Value : < 0.00000000000000022
##
## Sensitivity : 0.9051
## Specificity : 0.7983
## Pos Pred Value : 0.7934
## Neg Pred Value : 0.9076
## Prevalence : 0.4612
## Detection Rate : 0.4174
## Detection Prevalence : 0.5261
## Balanced Accuracy : 0.8517
##
## 'Positive' Class : 1
##
Dalam machine learning, performa model bergantung pada seberapa baik model dapat menggeneralisasi terhadap data baru. Tiga kondisi utama yang sering terjadi adalah underfitting, overfitting, dan just right.
Bagaimana perbandingan dari confusion matrix di atas?
Kekurangan dari decision tree adalah kecenderungannya untuk overfitting. Hal ini terjadi karena decision tree melakukan percabangan data hingga amat detail (bahkan hingga dalam leaf node hanya terdapat 1 observasi).
Untuk mengatasinya, decision tree perlu tahu kapan ia berhenti membuat cabang. Dengan demikian, pohon yang dihasilkan tidak terlalu kompleks. Pemotongan/pencegahan cabang pohon disebut pruning. Pruning terbagi menjadi 2 cara:
Mari kita lakukan tuning terhadap model decision tree dengan mengubah beberapa nilai berikut:
mincriterion
mincriterion = 0.95
, nilai p-value harus
< 0.05 agar sebuah node dapat membuat cabang (berkaitan dengan
signifikansi prediktor).mincriterion = 0.95
.minsplit
minsplit = 20
.minbucket
minbucket = 7
.💡️ Tips: semakin besar ketiga parameter di atas, semakin sederhana decision tree yang dihasilkan (semakin ketat kriteria dalam melakukan percabangan).
# tuning model decision tree
tree_credit_tuned <- ctree(formula = gb_flag ~ .,
data = loan_train_up,
control = ctree_control(mincriterion = 0.95,
minsplit = 300,
minbucket = 150)
)
# Ensemble Method: Random Forest
Ensemble method merupakan pendekatan machine learning untuk melakukan prediksi dengan mengombinasikan prediksi dari beberapa model menjadi sebuah prediksi. Dengan kombinasi dari beberapa prediktor tersebut, ensemble method dapat meningkatkan performa prediksi model. Contoh ensemble method adalah random forest.
🌳🌳 Random forest terbentuk dari sekumpulan decision tree. Masing-masing decision tree memiliki karakteristik yang berbeda dan tidak saling berhubungan.
Salah satu hal yang menarik lainnya yang akan kita pelajari adalah bagaimana melakukan cross validation
# # JANGAN DI RUN
# # definisikan training control untuk repeated k-fold cross validation
# train_ctrl <- trainControl(method = "repeatedcv",
# number = 5, # seberapa banyak kita ingin membagi data
# repeats = 3)
#
# # training model random forest dengan train()
# credit_forest <- train(gb_flag ~ .,
# data = loan_train_up,
# method = "rf", # pilih metode random forest
# trControl = train_ctrl)
Salah satu kelemahan random forest adalah pembuatan model yang
membutuhkan waktu yang cukup lama. Practice yang baik selesai melakukan
training adalah menyimpan model tersebut ke dalam bentuk file RDS dengan
function saveRDS()
agar model dapat langsung digunakan
tanpa harus training dari awal.
## Random Forest
##
## 26698 samples
## 23 predictor
## 2 classes: '0', '1'
##
## No pre-processing
## Resampling: Cross-Validated (5 fold, repeated 3 times)
## Summary of sample sizes: 21359, 21358, 21358, 21359, 21358, 21358, ...
## Resampling results across tuning parameters:
##
## mtry Accuracy Kappa
## 2 0.9289335 0.8578669
## 14 0.9320799 0.8641597
## 27 0.9296203 0.8592405
##
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was mtry = 14.
💡 Penjelasan Output Model
... samples
: banyak bootstrap data untuk pembuatan
model -> banyak DT.... predictors
: banyak prediktor.... classes
: banyak kelas target.mtry
& accuracy
: banyaknya
mtry
yang digunakan dan accuracy model untuk masing-masing
mtry.
Digunakan untuk menentukan model terbaik.Pada tahap bootstrap sampling, terdapat data yang tidak digunakan dalam pembuatan model. Data ini yang disebut sebagai data out-of-bag (OOB).
Model random forest akan menggunakan data OOB sebagai data untuk melakukan evaluasi dengan cara menghitung error (serupa dengan data testing). Error inilah yang disebut OOB Error. Dalam kasus klasifikasi, OOB error merupakan persentase data OOB yang misklasifikasi.
Syntax: object_model$finalModel
##
## Call:
## randomForest(x = x, y = y, mtry = param$mtry)
## Type of random forest: classification
## Number of trees: 500
## No. of variables tried at each split: 14
##
## OOB estimate of error rate: 5.64%
## Confusion matrix:
## 0 1 class.error
## 0 12026 1323 0.09910855
## 1 183 13166 0.01370889
Sebelumnya, kita sudah mengetahui bahwa accuracy tidak representatif apabila digunakan untuk kasus kelas target yang imbalance. Sebagai alternatif, kita dapat menggunakan precision atau recall. Akan tetapi, kedua metrics ini sangat berpengaruh pada nilai threshold.
Saat kita menggeser nilai threshold, nilai TP, TN, FP, dan FN dapat naik atau turun.
Untuk mengetahui apakah model kita baik di semua threshold, kita dapat membuat plot ROC (Receiver Operating Characteristic).
ROC merupakan plot antara TPR (True Positive Rate) dan FPR (False Positive Rate) pada setiap threshold. TPR pada sumbu y dan FPR pada sumbu x.
\[TPR = \frac{TP}{TP+FN} \qquad \qquad FPR = \frac{FP}{FP+TN}\]
Perhatikan plot di bawah ini.
Mari kita buat plot ROC
# membuat prediction object agar dapt menghitung nilai TPR, FPR,
rf_roc <- prediction(predictions = pred_prob,
labels = credit_test$gb_flag,
label.ordering = c("1", "0")) # urutan: kelas negatif, positif
# membuat plot ROC
model_roc_vec <- performance(rf_roc,
"tpr", # True Positive Rate (Recall)
"fpr") # False Positive Rate (1 - Specificity)
plot(model_roc_vec)
abline(0,1 , lty = 2)
💡 Plot ROC Ideal
Karena bentuk ROC visual, untuk mengetahui apakah model kita sudah baik di semua threshold, kita memerlukan AUC (Area Under Curve)
AUC menunjukkan luas area di bawah kurva ROC.
💡 Kriteria AUC
## [1] 0.9940546