Sebelum mengenal tentang classification, mari sedikit membahas tentang machine learning itu sendiri. Machine Learning adalah suatu bidang ilmiah yang mempelajari tentang algoritma dan model statistik yang digunakan oleh sistem komputer dengan mengandalkan pola. Machine learning atau dalam Bahasa Indonesia Pembelajaran Mesin juga memberikan kemampuan pada sistem untuk secara otomatis belajar dan meningkat dari pengalaman tanpa diprogram secara eksplisit. Pembelajaran mesin berfokus pada pengembangan program komputer yang dapat mengakses data dan menggunakannya untuk belajar sendiri.
Lalu kita masuk kedalam pembahasan apa itu classification? Classification dapat didefinisikan sebagai proses memprediksi kelas atau kategori dari nilai yang diamati atau titik data yang diberikan. Output yang dikategorikan dapat memiliki bentuk seperti “Black” atau “White” atau “spam” atau “no spam”. Secara matematis, classification adalah tugas mendekati fungsi pemetaan (f) dari variabel input (X) ke variabel output (Y). Ini pada dasarnya milik pembelajaran mesin yang diawasi di mana target juga disediakan bersama dengan set data input.
BERBAGAI ALGORITMA CLASSIFICATION
Berikut ini adalah beberapa algoritma classification :
Logistic Regression
Support Vector Machine (SVM)
Decision Tree
Naïve Bayes
Random Forest
Tujuan utama dari kursus ini adalah untuk memberikan pengenalan yang komprehensif untuk classification in machine learning dengan menggunakan data yang ada.
Mempelajari algoritma klasifikasi dari dasar, menyelidiki dasar matematika yang mendukung algoritma Naïve Bayes, algoritma Decision Tree, dan algoritma Random Forest.
merupakan algoritma klasifikasi yang didasari oleh Bayes’ Theorem of Probability.
Memiliki karakter:
Kekurangan dari Naive Bayes:
laplace yang berbeda akan
menghasilkan probabilitas yang berbeda pula.merupakan tree-based model yang cukup sederhana dengan performa yang robust/powerful untuk prediksi. Decision Tree menghasilkan visualisasi berupa pohon keputusan yang dapat diinterpretasi dengan mudah.
Memiliki karakter:
Kekurangan dari Decision Tree:
merupakan salah satu jenis Ensemble Method yang terdiri dari banyak Decision Tree. Masing-masing Decision Tree memiliki karakteristik masing-masing dan tidak saling berhubungan. Random Forest memanfaatkan konsep Bagging (Bootstrap and Aggregation) dalam pembuatannya.
Memiliki karakter:
Kekurangan dari Random Forest:
saveRDS() agar model dapat langsung digunakan tanpa harus
training dari awal.Load Library
library(dplyr) # for data wrangling
library(ggplot2) # to visualize data
library(gridExtra) # to display multiple graph
library(inspectdf) # for EDA
library(tidymodels) # to build tidy models
library(caret) # to pre-process data
library(rsample) # to splitting data random
library(e1071) # to naive bayes model
library(ROCR) # to ROC AUC
library(plotly) # to visualize data
library(rpart) # to decision tree
library(rattle) # to decision tree
library(rpart.plot) # to decision treeRead Data
Dataset yang digunakan merupakan hasil tes diagnosis dan riwayat penyakit diabetes dari 768 pasien.
# read data
diab <- read.csv("diabetes.csv")
# cek data
head(diab)Deskripsi data:
pregnant: Number of times pregnant
glucose: Plasma glucose concentration (glucose
tolerance test)
pressure: Diastolic blood pressure (mm Hg)
triceps: Triceps skin fold thickness (mm)
insulin: 2-Hour serum insulin (mu U/ml)
mass: Body mass index (weight in kg/(height in
m)^2)
pedigree: Diabetes pedigree function
age: Age (years)
diabetes: Test for Diabetes
kelas positif: diabetes (pos)
kelas negatif: sehat (neg)
Cek tipe data pada dataset diab:
glimpse(diab)#> Rows: 768
#> Columns: 9
#> $ pregnant <int> 6, 1, 8, 1, 0, 5, 3, 10, 2, 8, 4, 10, 10, 1, 5, 7, 0, 7, 1, 1…
#> $ glucose <int> 148, 85, 183, 89, 137, 116, 78, 115, 197, 125, 110, 168, 139,…
#> $ pressure <int> 72, 66, 64, 66, 40, 74, 50, 0, 70, 96, 92, 74, 80, 60, 72, 0,…
#> $ triceps <int> 35, 29, 0, 23, 35, 0, 32, 0, 45, 0, 0, 0, 0, 23, 19, 0, 47, 0…
#> $ insulin <int> 0, 0, 0, 94, 168, 0, 88, 0, 543, 0, 0, 0, 0, 846, 175, 0, 230…
#> $ mass <dbl> 33.6, 26.6, 23.3, 28.1, 43.1, 25.6, 31.0, 35.3, 30.5, 0.0, 37…
#> $ pedigree <dbl> 0.627, 0.351, 0.672, 0.167, 2.288, 0.201, 0.248, 0.134, 0.158…
#> $ age <int> 50, 31, 32, 21, 33, 30, 26, 29, 53, 54, 30, 34, 57, 59, 51, 3…
#> $ diabetes <chr> "pos", "neg", "pos", "neg", "pos", "neg", "pos", "neg", "pos"…
Sesuaikan tipe data pada dataset diab:
# your code
diab <- diab %>%
mutate(diabetes = as.factor(diabetes))# inspect missing value
round(prop.table(table(is.na(diab))),3)#>
#> FALSE
#> 1
data.frame(cbind(missing = colSums(is.na(diab)),
prop = round(prop.table(colSums(is.na(diab))),2)))Data set sudah baik, karena tidak terdapat missing value di setiap variable / kolom nya.
Target Variable Proportion
x <- inspectdf::inspect_cat(diab)
show_plot(x)Berdasarkan plot, ada proporsi yang tidak seimbang antara level dalam variabel target kami. Untuk melakukan penyeimbangan data tersebut dapat dilakukan upSampling / downSampling, untuk saat ini saya akan menggunakan downsampling (bukan upsampling) untuk menyeimbangkan proporsi.
# inspect corelation between predictors
GGally::ggcorr(diab[,-9], hjust = 1, layout.exp = 2, label = T, label_size = 2.9)
Berdasarkan plot di atas, ada beberapa variabel prediktor yang memiliki
korelasi tinggi satu sama lain. Variabel-variabel tersebut adalah
pregnant. Ini memberi kami peringatan dini bahwa data ini mungkin tidak
sesuai untuk beberapa model seperti Naive Bayes.
Split data diab menjadi diab_train dan
diab_test dengan proporsi 80:20
RNGkind(sample.kind = "Rounding")
set.seed(1013)
# your code here
index_diab <- sample(x = nrow(diab),
size= nrow(diab)*0.8)
diab_train <- diab[index_diab, ]
diab_test <- diab[-index_diab, ]#upsampling
RNGkind(sample.kind = "Rounding")
set.seed(1013)
diab_train <- downSample(x = diab_train %>% select(-diabetes),
y = diab_train$diabetes,
yname = "diabetes") #nama kolom targetCek Proposinya lagi
prop.table(table(diab_train$diabetes))#>
#> neg pos
#> 0.5 0.5
Data sudah balance, sehingga bisa dilakukan modeling.
Berdasarkan karakteristiknya, data diab kami sebenarnya tidak terlalu sesuai untuk Naive Bayes. Dari deskripsi data, beberapa prediktor kami memiliki korelasi yang tinggi satu sama lain. Prediktor juga variabel kontinu. Meski begitu, kami masih akan mencoba menggunakan Naive Bayes dan hasilnya akan dibandingkan dengan model lainnya. Saat membangun model Naive Bayes, kita juga harus menerapkan estimator Laplace.
naive <- naiveBayes(formula = diabetes ~ . ,
data = diab_train,
laplace = 1)# model fitting
naive_pred <- predict(naive, diab_test, type = "class") # for the class prediction
naive_prob <- predict(naive, diab_test, type = "raw") # for the probability
# result
naive_table <- select(diab_test, diabetes) %>%
bind_cols(diabetes_pred = naive_pred) %>%
bind_cols(diabetes_eprob = round(naive_prob[,1],4)) %>%
bind_cols(diabetes_pprob = round(naive_prob[,2],4))
# performance evaluation - confusion matrix
naive_table %>%
conf_mat(diabetes, diabetes_pred) %>%
autoplot(type = "heatmap")naive_table %>%
summarise(
accuracy = accuracy_vec(diabetes, diabetes_pred),
sensitivity = sens_vec(diabetes, diabetes_pred),
specificity = spec_vec(diabetes, diabetes_pred),
precision = precision_vec(diabetes, diabetes_pred)
)# ROC
naive_roc <- data.frame(prediction=round(naive_prob[,1],4),
trueclass=as.numeric(naive_table$diabetes=="pos"))
head(naive_roc)naive_roc <- ROCR::prediction(naive_roc$prediction, naive_roc$trueclass)
# ROC curve
plot(performance(naive_roc, "tpr", "fpr"),
main = "ROC")
abline(a = 0, b = 1, lty= 2)
- TPR: dari seluruh pasien yang actualnya diabetes, persentase model
kita mengklasifikasi dengan benar (tetap diprediksi sebagai diabetes). -
FPR: dari seluruh pasien yang actualnya sehat, persentase model kita
salah mengklasifikasi (diprediksi jadi diabetes).
# AUC
auc_ROCR_n <- performance(naive_roc, measure = "auc")
auc_ROCR_n <- auc_ROCR_n@y.values[[1]]
auc_ROCR_n#> [1] 0.2141667
# metrics lama
model_n <- naive_table %>%
summarise(
accuracy = accuracy_vec(diabetes, diabetes_pred),
sensitivity = sens_vec(diabetes, diabetes_pred),
specificity = spec_vec(diabetes, diabetes_pred),
precision = precision_vec(diabetes, diabetes_pred)
) %>%
cbind(AUC = auc_ROCR_n)Untuk informasi Anda, ini adalah metrik yang akan kami evaluasi dari model:
Selain itu, ada juga kurva Receiver Operating Characteristics (ROC) dan Area Under Curve (AUC) untuk mengevaluasi model kami. ROC memplot proporsi true positive rate (TPR atau Sensitivitas) dengan proporsi false negative rate (FNR atau 1-Spesifikasi). ROC adalah kurva probabilitas dan AUC mewakili derajat atau ukuran keterpisahan. Ini memberitahu seberapa banyak model mampu membedakan antara kelas. Semakin dekat kurva mencapai kiri atas plot (True positive tinggi sementara False negative rendah), semakin baik model kita. Semakin tinggi skor AUC, semakin baik model kami memisahkan kelas target kami.
Berdasarkan hasil, accuracy, sensitivity, specificity, dan precision model kami dapat diterima. Sayangnya, Kurva ROC belum menunjukkan pemisahan yang cukup baik dengan skor AUC 0.2141667 dan dapat ditingkatkan lebih lanjut.
Dalam kasus kami, diabetes diklasifikasikan untuk mengetahui tindakan lanjutan untuk pasien. Kesalahan klasifikasi kedua kelas sama-sama akan berdampak ke pasien. Hal ini karena jika pasien yang mengalami diabetes namun didiagnosa sehat, maka kemungkinan pasien akan terlambat mendapatkan penanganan medisnya. Sedangkan jika pasien yang sehat namun didiagnosa diabetes, maka pasien tersebut mungkin akan mengeluarkan biaya lebih yang tidak seharusnya.
Di bawah ini, saya akan mendemonstrasikan beberapa praktik penyetelan model dengan mengubah threshold untuk klasifikasi.
# model tuning - metrics function
metrics <- function(cutoff, prob, ref, postarget, negtarget)
{
predict <- factor(ifelse(prob >= cutoff, postarget, negtarget))
conf <- caret::confusionMatrix(predict , ref, positive = postarget)
acc <- conf$overall[1]
rec <- conf$byClass[1]
prec <- conf$byClass[3]
spec <- conf$byClass[2]
mat <- t(as.matrix(c(rec , acc , prec, spec)))
colnames(mat) <- c("recall", "accuracy", "precicion", "specificity")
return(mat)
}
co <- seq(0.01,0.99,length=100)
result <- matrix(0,100,4)
# apply function metrics
for(i in 1:100){
result[i,] = metrics(cutoff = co[i],
prob = naive_table$diabetes_eprob,
ref = as.factor(ifelse(naive_table$diabetes == "pos", 1, 0)),
postarget = "1",
negtarget = "0")
}
# visualize
ggplotly(tibble("Recall" = result[,1],
"Accuracy" = result[,2],
"Precision" = result[,3],
"Specificity" = result[,4],
"Cutoff" = co) %>%
gather(key = "Metrics", value = "value", 1:4) %>%
ggplot(aes(x = Cutoff, y = value, col = Metrics)) +
geom_line(lwd = 1.5) +
scale_color_manual(values = c("darkred","darkgreen","orange", "blue")) +
scale_y_continuous(breaks = seq(0,1,0.1), limits = c(0,1)) +
scale_x_continuous(breaks = seq(0,1,0.1)) +
labs(title = "Tradeoff Model Perfomance") +
theme_minimal() +
theme(legend.position = "top",
panel.grid.minor.y = element_blank(),
panel.grid.minor.x = element_blank()))Dari plot di atas, kita tahu bahwa break-even point dari recall-specificity adalah pada 0,26. Tetapi jika kita menetapkan threshold 0,66, kita mendapatkan recall 10% , specificity 61% sekaligus memiliki accuracy 27%.
# tuning final model
naive_table <- naive_table %>%
mutate(tuning_pred = as.factor(ifelse(diabetes_eprob >= 0.26, "pos", "neg")))
# metrics result
final_n <- naive_table %>%
summarise(
accuracy = accuracy_vec(diabetes, tuning_pred),
sensitivity = sens_vec(diabetes, tuning_pred),
specificity = spec_vec(diabetes, tuning_pred),
precision = precision_vec(diabetes, tuning_pred)
) %>%
cbind(AUC = auc_ROCR_n)
final_nModel pohon keputusan adalah salah satu model berbasis pohon yang memiliki manfaat utama yang dapat diinterpretasikan. Pohon keputusan adalah algoritma yang akan membuat sekumpulan aturan yang divisualisasikan dalam diagram yang menyerupai pohon.
Untuk benar-benar memahami tampilannya, mari kita buat model pohon keputusan berdasarkan data diab_train kita. Kita dapat menggunakan paket rpart untuk membangun model pohon keputusan dan menggunakan paket rattle dan rpart.plot untuk memvisualisasikannya.
# model building
dtree <- rpart(formula = diabetes ~ .,
data = diab_train,
method = "class")
fancyRpartPlot(dtree, sub = NULL)Sebuah decision tree terdiri dari beberapa bagian. Kotak pertama di bagian atas plot adalah root node. Akar akan membelah dan membuat cabang dengan aturan tertentu. Setiap cabang diakhiri dengan node. Beberapa node dipecah lagi menjadi node lain dan disebut internal node. Node yang tidak membelah lagi atau muncul di ujung pohon disebut terminal node atau leaf node, seperti halnya daun pada pohon.
Setiap node menunjukkan:
# model fitting
dtree_pred <- predict(dtree, diab_test, type = "class")
dtree_prob <- predict(dtree, diab_test, type = "prob")
# result
dtree_table <- select(diab_test, diabetes) %>%
bind_cols(diabetes_pred = dtree_pred) %>%
bind_cols(diabetes_eprob = round(dtree_prob[,1],4)) %>%
bind_cols(diabetes_pprob = round(dtree_prob[,2],4))
# performance evaluation - confusion matrix
dtree_table %>%
conf_mat(diabetes, diabetes_pred) %>%
autoplot(type = "heatmap")dtree_table %>%
summarise(
accuracy = accuracy_vec(diabetes, diabetes_pred),
sensitivity = sens_vec(diabetes, diabetes_pred),
specificity = spec_vec(diabetes, diabetes_pred),
precision = precision_vec(diabetes, diabetes_pred)
)# ROC
dtree_roc <- data.frame(prediction=round(dtree_prob[,1],4),
trueclass=as.numeric(dtree_table$diabetes=="pos"))
head(dtree_roc)dtree_roc <- ROCR::prediction(dtree_roc$prediction, dtree_roc$trueclass)
# ROC curve
plot(performance(dtree_roc, "tpr", "fpr"),
main = "ROC")
abline(a = 0, b = 1, lty = 2)
- TPR: dari seluruh pasien yang actualnya diabetes, persentase model
kita mengklasifikasi dengan benar (tetap diprediksi sebagai diabetes). -
FPR: dari seluruh pasien yang actualnya sehat, persentase model kita
salah mengklasifikasi (diprediksi jadi diabetes).
# AUC
auc_ROCR_d <- performance(dtree_roc, measure = "auc")
auc_ROCR_d <- auc_ROCR_d@y.values[[1]]
auc_ROCR_d#> [1] 0.250463
# metrics lama
model_d <- dtree_table %>%
summarise(
accuracy = accuracy_vec(diabetes, diabetes_pred),
sensitivity = sens_vec(diabetes, diabetes_pred),
specificity = spec_vec(diabetes, diabetes_pred),
precision = precision_vec(diabetes, diabetes_pred)
) %>%
cbind(AUC = auc_ROCR_d)Dari hasil model decision tree, saya tidak akan menyetel model dari parameter karena dengan menggunakan parameter default, kita sudah mendapatkan pohon berukuran normal (tidak perlu melakukan perform tree pruning). Sebagai gantinya, saya akan mencoba menyetel model dengan mengubah threshold untuk klasifikasi.
for(i in 1:100){
result[i,] = metrics(cutoff = co[i],
prob = dtree_table$diabetes_eprob,
ref = as.factor(ifelse(dtree_table$diabetes == "pos", 1, 0)),
postarget = "1",
negtarget = "0")
}
ggplotly(data_frame("Recall" = result[,1],
"Accuracy" = result[,2],
"Precision" = result[,3],
"Specificity" = result[,4],
"Cutoff" = co) %>%
gather(key = "Metrics", value = "value", 1:4) %>%
ggplot(aes(x = Cutoff, y = value, col = Metrics)) +
geom_line(lwd = 1.5) +
scale_color_manual(values = c("darkred","darkgreen","orange", "blue")) +
scale_y_continuous(breaks = seq(0,1,0.1), limits = c(0,1)) +
scale_x_continuous(breaks = seq(0,1,0.1)) +
labs(title = "Tradeoff Model Perfomance") +
theme_minimal() +
theme(legend.position = "top",
panel.grid.minor.y = element_blank(),
panel.grid.minor.x = element_blank()))# tuning final model
dtree_table <- dtree_table %>%
mutate(tuning_pred = as.factor(ifelse(diabetes_eprob >= 0.69, "pos", "neg")))
# metrics result
final_d <- dtree_table %>%
summarise(
accuracy = accuracy_vec(diabetes, tuning_pred),
sensitivity = sens_vec(diabetes, tuning_pred),
specificity = spec_vec(diabetes, tuning_pred),
precision = precision_vec(diabetes, tuning_pred)
) %>%
cbind(AUC = auc_ROCR_d)
final_dUntuk benar-benar memahami cara kerja random forest , mari terapkan algoritme random forest ke data diabetes kita.
# model building
set.seed(1013)
ctrl <- trainControl(method="repeatedcv",
number=5,
repeats=5) # k-fold cross validation
forest <- train(diabetes ~ .,
data=diab_train,
method="rf",
trControl = ctrl)
forest#> Random Forest
#>
#> 428 samples
#> 8 predictor
#> 2 classes: 'neg', 'pos'
#>
#> No pre-processing
#> Resampling: Cross-Validated (5 fold, repeated 5 times)
#> Summary of sample sizes: 342, 342, 342, 344, 342, 342, ...
#> Resampling results across tuning parameters:
#>
#> mtry Accuracy Kappa
#> 2 0.7224268 0.4449867
#> 5 0.7341042 0.4682384
#> 8 0.7332179 0.4665231
#>
#> Accuracy was used to select the optimal model using the largest value.
#> The final value used for the model was mtry = 5.
Dari ringkasan model, kita mengetahui bahwa jumlah optimal variabel yang dipertimbangkan untuk dipecah pada setiap node adalah 8. Kita juga dapat memeriksa pentingnya setiap variabel yang digunakan di random forest kita menggunakan varImp().
varImp(forest)#> rf variable importance
#>
#> Overall
#> glucose 100.0000
#> mass 47.1589
#> age 36.7729
#> pedigree 29.3881
#> pressure 15.7786
#> pregnant 10.8465
#> triceps 0.2399
#> insulin 0.0000
Saat menggunakan random forest - kami tidak diharuskan untuk membagi dataset kami menjadi data train dan test karena random forest sudah memiliki estimates out-of-bag (OOB) yang bertindak sebagai perkiraan accuracy yang andal pada unseen examples. Meskipun, juga dimungkinkan untuk mengadakan regular train-test cross-validation. Misalnya, OOB yang kami capai (dalam summary di bawah) dihasilkan dari dataset diab_train kami.
plot(forest$finalModel)
legend("topright", colnames(forest$finalModel$err.rate),col=1:6,cex=0.8,fill=1:6)forest$finalModel#>
#> Call:
#> randomForest(x = x, y = y, mtry = min(param$mtry, ncol(x)))
#> Type of random forest: classification
#> Number of trees: 500
#> No. of variables tried at each split: 5
#>
#> OOB estimate of error rate: 26.4%
#> Confusion matrix:
#> neg pos class.error
#> neg 156 58 0.2710280
#> pos 55 159 0.2570093
Mari kita uji model random forest kita ke dataset diab_test kita:
# model fitting
forest_pred <- predict(forest, diab_test, type = "raw")
forest_prob <- predict(forest, diab_test, type = "prob")
# result
forest_table <- select(diab_test, diabetes) %>%
bind_cols(diabetes_pred = forest_pred) %>%
bind_cols(diabetes_eprob = round(forest_prob[,1],4)) %>%
bind_cols(diabetes_pprob = round(forest_prob[,2],4))
# performance evaluation - confusion matrix
forest_table %>%
conf_mat(diabetes, diabetes_pred) %>%
autoplot(type = "heatmap")forest_table %>%
summarise(
accuracy = accuracy_vec(diabetes, diabetes_pred),
sensitivity = sens_vec(diabetes, diabetes_pred),
specificity = spec_vec(diabetes, diabetes_pred),
precision = precision_vec(diabetes, diabetes_pred)
)# ROC
forest_roc <- data.frame(prediction=round(forest_prob[,1],4),
trueclass=as.numeric(forest_table$diabetes=="pos"))
head(forest_roc)forest_roc <- ROCR::prediction(forest_roc$prediction, forest_roc$trueclass)
# ROC curve
plot(performance(forest_roc, "tpr", "fpr"),
main = "ROC")
abline(a = 0, b = 1, lty = 2)# AUC
auc_ROCR_f <- performance(forest_roc, measure = "auc")
auc_ROCR_f <- auc_ROCR_f@y.values[[1]]
auc_ROCR_f#> [1] 0.2111111
# metrics lama
model_f <- forest_table %>%
summarise(
accuracy = accuracy_vec(diabetes, diabetes_pred),
sensitivity = sens_vec(diabetes, diabetes_pred),
specificity = spec_vec(diabetes, diabetes_pred),
precision = precision_vec(diabetes, diabetes_pred)
) %>%
cbind(AUC = auc_ROCR_f)Berdasarkan analisis dan hasil di atas, model random forest memberi kami hasil accuracy, recall, specificity, dan precision yang cukup baik (all metrics > 62%). Namun nilai AUC modelnya kurang baik yaitu 22%, saya akan coba mengatur threshold untuk bisa mencapai score yang lebih tinggi pada setiap numeriknya.
for(i in 1:100){
result[i,] = metrics(cutoff = co[i],
prob = forest_table$diabetes_eprob,
ref = as.factor(ifelse(forest_table$diabetes == "pos", 1, 0)),
postarget = "1",
negtarget = "0")
}
ggplotly(data_frame("Recall" = result[,1],
"Accuracy" = result[,2],
"Precision" = result[,3],
"Specificity" = result[,4],
"Cutoff" = co) %>%
gather(key = "Metrics", value = "value", 1:4) %>%
ggplot(aes(x = Cutoff, y = value, col = Metrics)) +
geom_line(lwd = 1.5) +
scale_color_manual(values = c("darkred","darkgreen","orange", "blue")) +
scale_y_continuous(breaks = seq(0,1,0.1), limits = c(0,1)) +
scale_x_continuous(breaks = seq(0,1,0.1)) +
labs(title = "Tradeoff Model Perfomance") +
theme_minimal() +
theme(legend.position = "top",
panel.grid.minor.y = element_blank(),
panel.grid.minor.x = element_blank()))# tuning final model
forest_table <- forest_table %>%
mutate(tuning_pred = as.factor(ifelse(diabetes_eprob >= 0.59, "pos", "neg")))
# metrics result
final_f <- forest_table %>%
summarise(
accuracy = accuracy_vec(diabetes, tuning_pred),
sensitivity = sens_vec(diabetes, tuning_pred),
specificity = spec_vec(diabetes, tuning_pred),
precision = precision_vec(diabetes, tuning_pred)
) %>%
cbind(AUC = auc_ROCR_f)
final_frbind("Naive Bayes (lama)" = model_n,
"Decision Tree (lama)" = model_d,
"Random Forest (lama)" = model_f)rbind( "Naive Bayes (baru)" = final_n,
"Decision Tree (baru)" = final_d,
"Random Forest (baru)" = final_f)Berdasarkan tabel metrik di atas, model prediksi yang dibangun menggunakan model lama dikarenakan hasilnya lebih baik sebelum dilakukan pengaturan threshold.
Algoritma Random Forest (lama) memberikan hasil terbaik. Model memberikan akurasi tertinggi 74% sekaligus mempertahankan sensitivitas dengan nilai 80%, spesifisitas nya 64%, dan presisi di atas 70%. Oleh karena itu model terbaik untuk memprediksi diagnosa diabetes atau tidak berdasarkan prediktor yang ada adalah model Random Forest.