#install.packages("mlr3pipelines")
library(mlr3pipelines)
library(mlr3verse)
library(mlr3learners)
library(data.table)
Data yang digunakan pada modul ini adalah data tentang kasus penyakit Diabetes, yang telah digunakan pada ilustrasi modul sebelumnya.
data_diabetes<-read.csv("https://raw.githubusercontent.com/gerrydito/Model-Klasifikasi/master/Praktikum/KNN/diabetes.csv", stringsAsFactors = TRUE)
Kita akan jalankan syntax berikut untuk mengingat kembali informasi tentang data tersebut.
dim(data_diabetes)
## [1] 752 9
head(data_diabetes)
skimr::skim(data_diabetes)
Name | data_diabetes |
Number of rows | 752 |
Number of columns | 9 |
_______________________ | |
Column type frequency: | |
factor | 1 |
numeric | 8 |
________________________ | |
Group variables | None |
Variable type: factor
skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
---|---|---|---|---|---|
Outcome | 0 | 1 | FALSE | 2 | Con: 490, Cas: 262 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
Pregnancies | 0 | 1 | 3.86 | 3.37 | 0.00 | 1.00 | 3.00 | 6.00 | 17.00 | ▇▃▂▁▁ |
Glucose | 0 | 1 | 120.70 | 31.75 | 0.00 | 99.00 | 117.00 | 140.00 | 199.00 | ▁▁▇▆▂ |
BloodPressure | 0 | 1 | 69.08 | 19.36 | 0.00 | 62.00 | 72.00 | 80.00 | 122.00 | ▁▁▇▇▁ |
SkinThickness | 0 | 1 | 20.51 | 15.96 | 0.00 | 0.00 | 23.00 | 32.00 | 99.00 | ▇▇▂▁▁ |
Insulin | 0 | 1 | 79.84 | 114.69 | 0.00 | 0.00 | 34.00 | 128.25 | 846.00 | ▇▁▁▁▁ |
BMI | 0 | 1 | 32.01 | 7.80 | 0.00 | 27.30 | 32.00 | 36.60 | 67.10 | ▁▃▇▂▁ |
DiabetesPedigreeFunction | 0 | 1 | 0.47 | 0.33 | 0.08 | 0.24 | 0.37 | 0.63 | 2.42 | ▇▃▁▁▁ |
Age | 0 | 1 | 33.21 | 11.74 | 21.00 | 24.00 | 29.00 | 41.00 | 81.00 | ▇▃▁▁▁ |
Pada ilustrasi ini, peubah yang diamati adalah peubah outcome
yang menyatakan seseorang terkena kasus penyakit diabetes atau tidak. Pada ekosistem mlr3
, kita perlu mendefinisikan task yang akan digunakan, seperti pada syntax berikut ini.
task_diabetes = TaskClassif$new(id="diabetes",backend = data_diabetes,
target = "Outcome",positive ="Case")
Metode ini memproses informasi dari data sebagai input layer, proses tersebut dilanjutkan pada layer berikutnya yaitu hidden layer, dimana setiap hidden layer dapat memuat beberapa nodes. Gambar berikut diperoleh dari Yolanda (2019) menunjukkan ilustrasi arsitektur metode ANN.
Neural network dapat dilakukan menggunakan fungsi nnet()
yang terdapat pada package nnet
, atau dapat pula dipanggil dari package mlr3extralearners
. Daftar metode yang terdapat pada package ini dapat dilihat pada link berikut: https://mlr3extralearners.mlr-org.com/articles/learners/list_learners.html
#remotes::install_github("mlr-org/mlr3extralearners")
library(mlr3extralearners)
##
## Attaching package: 'mlr3extralearners'
## The following objects are masked from 'package:mlr3':
##
## lrn, lrns
as.data.table(lrn("classif.nnet")$param_set)
Pada ilustrasi ini dimisalkan kita akan memodelkan data diabetes menggunakan metode ANN dengan banyaknya nodes pada hidden layer adalah 8.
learner_nn<-lrn("classif.nnet", size=8)
learner_nn
## <LearnerClassifNnet:classif.nnet>
## * Model: -
## * Parameters: size=8
## * Packages: nnet
## * Predict Type: prob
## * Feature types: numeric, factor, ordered
## * Properties: multiclass, twoclass, weights
Seperti yang dapat dilihat pada output di atas, algoritma nn
yang digunakan di sini hanya menerima tipe peubah numeric, factor, dan ordered, sebagai input. Oleh karenanya, beberapa peubah integer pada data diabetes akan diubah menjadi tipe numeric terlebih dahulu sebelum menerapkan algoritma tersebut pada data.
data_diabetes2<-data_diabetes
data_diabetes2[,c(1:5, 8)]<-lapply(data_diabetes2[,c(1:5, 8)], as.numeric)
task_diabetes2<-TaskClassif$new(id="diabetes2",backend = data_diabetes2,
target = "Outcome",positive ="Case")
set.seed(1)
learner_nn$train(task = task_diabetes2)
## # weights: 81
## initial value 515.874029
## iter 10 value 476.914808
## iter 20 value 452.378542
## iter 30 value 434.710869
## iter 40 value 428.549449
## iter 50 value 423.438192
## iter 60 value 417.964064
## iter 70 value 417.640296
## iter 80 value 416.113716
## iter 90 value 415.721111
## iter 100 value 414.506888
## final value 414.506888
## stopped after 100 iterations
Seandainya kita menginginkan untuk membagi data menjadi dua bagian, data training data data testing, maka kita dapat menentukan terlebih dulu dengan fungsi rsmp()
seperti yang telah dibahas pada modul sebelumnya.
resample_diabetes1 = rsmp("holdout", ratio = 0.8)
set.seed(2020)
train_test_diabetes1 = resample(task = task_diabetes2,
learner = learner_nn,
resampling = resample_diabetes1,
store_models = TRUE
)
## INFO [18:35:10.943] Applying learner 'classif.nnet' on task 'diabetes2' (iter 1/1)
## # weights: 81
## initial value 392.161360
## iter 10 value 360.435858
## iter 20 value 351.832591
## iter 30 value 343.310332
## iter 40 value 332.644844
## iter 50 value 322.557773
## iter 60 value 317.666203
## iter 70 value 313.414293
## iter 80 value 310.834335
## iter 90 value 310.130739
## iter 100 value 310.125650
## final value 310.125650
## stopped after 100 iterations
prediksi_test = as.data.table(train_test_diabetes1$prediction())
head(prediksi_test)
Selanjutnya evaluasi dapat dilakukan pada hasil validasi menggunakan data testing.
train_test_diabetes1$prediction()$confusion
## truth
## response Case Control
## Case 19 14
## Control 40 77
train_test_diabetes1$aggregate(list(msr("classif.acc"),
msr("classif.specificity"),
msr("classif.sensitivity"),
msr("classif.auc")
))
## classif.acc classif.specificity classif.sensitivity classif.auc
## 0.6400000 0.8461538 0.3220339 0.6164090
AUC (area under curve) merupakan luas daerah dibawah kurva ROC (receiver operating characteristics), yang akan diperlihatkan pada subbagian berikut ini.
“Beberapa algoritma, selain dapat memprediksi kelas, juga dapat memprediksi peluang suatu pengamatan termasuk ke dalam salah satu kelas. Terkadang, batas 0.5 digunakan sebagai threshold untuk menentukan kelas prediksi untuk pengamatan tersebut. Namun, hal ini tidak selalu tepat untuk dilakukan. Improvement dilakukan menggunakan kurva ROC yang mempertimbangkan semua kemungkinan nilai threshold tersebut, serta memvisualisasikan trade-off antara sensitivity (true positive rate) dan specitivity (true negative rate).”, (Baumer et al., 2017).
Selain itu, kurva ROC juga mencerminkan performa model. Bentuk kurva yang cenderung melengkung ke pojok kiri atas menunjukkan performa yang lebih baik. Oleh karenanya, semakin besar luas di bawah kurva ROC menunjukkan performa model yang semakin baik. Hal ini disebut dengan istilah area under curve (AUC).
library(mlr3viz)
pred=train_test_diabetes1$prediction()
# TPR vs FPR / Sensitivity vs (1 - Specificity)
ggplot2::autoplot(pred, type = "roc")
mlr3pipelines
Becker et al. (2020) menjelaskan mlr3pipelines
sebagai suatu perangkat pemrograman dataflow. Alur kerja dalam suatu machine learning dapat dituliskan dalam bentuk “Graphs” atau “Pipelines” yang menunjukkan flow data antara prapemrosesan, model fitting, dan ensemble learning. Berikut adalah ilustrasi linear preprocessing ( Bischl et al.,2020).
graph_pp = po("scale") %>>%
po("encode") %>>%
po("imputemedian") %>>%
lrn("classif.rpart")
plot(graph_pp)
PO adalah blok penyusun pada mlr3pipelines
. Contoh penggunaannya adalah sebagai berikut.
pca=mlr_pipeops$get("pca")
Atau dapat pula dilakukan dengan cara berikut.
pca=po("pca")
Kita dapat menginput metode pra-pemrosesan data seperti PCA, imputasi, dan juga algoritma pemodelan. Untuk mengetahui daftar object yang dapat diakses sebagai po
, kita dapat mengaksesnya dengan cara berikut.
library("mlr3pipelines")
as.data.table(mlr_pipeops)
Operator %>>%
digunakan untuk menghubungkan antar po
, seperti pada contoh berikut ini.
library("magrittr")
po1=po("scale")
po2=po("pca")
gr = po1 %>>% po2
gr$plot(html = FALSE)
Pada ilustrasi tersebut, kita memiliki 2 po, yaitu operasi scale
, kemudian dilanjutkan dengan pca
.
single_path=po("subsample") %>>% lrn("classif.rpart", predict_type="prob")
graph_bag=ppl("greplicate", single_path, n=3) %>>%
po("classifavg")
plot(graph_bag)
as.data.table(mlr_pipeops)
#learn_graphbag=GraphLearner$new(graph_bag)
train_test_diabetes2 = resample(task = task_diabetes,
learner = graph_bag,
resampling = resample_diabetes1,
store_models = TRUE)
## INFO [18:35:14.624] Applying learner 'subsample_1.subsample_2.subsample_3.classif.rpart_1.classif.rpart_2.classif.rpart_3.classifavg' on task 'diabetes' (iter 1/1)
pred2=train_test_diabetes2$prediction()
ggplot2::autoplot(pred2, type = "roc")
train_test_diabetes2$prediction()$confusion
## truth
## response Case Control
## Case 30 19
## Control 26 75
train_test_diabetes2$aggregate(list(msr("classif.acc"),
msr("classif.specificity"),
msr("classif.sensitivity"),
msr("classif.auc")
))
## classif.acc classif.specificity classif.sensitivity classif.auc
## 0.7000000 0.7978723 0.5357143 0.7847644
graph_stack=gunion(list(
po("learner_cv", learner=lrn("regr.lm")),
po("learner_cv", learner=lrn("regr.svm")),
po("nop"))) %>>%
po("featureunion") %>>%
lrn("regr.ranger")
plot(graph_stack)
stacking=gunion(list(
po("learner_cv", learner=lrn("classif.ranger", predict_type="prob")),
po("learner_cv", learner=lrn("classif.kknn", predict_type="prob")))) %>>%
po("featureunion") %>>%
lrn("classif.log_reg", predict_type="prob")
stacking$plot()
set.seed(20202311)
cv10_instance = rsmp("cv")$instantiate(task_diabetes)
bmr = benchmark(data.table(
task = list(task_diabetes),
learner = list(
stacking,
lrn("classif.ranger", predict_type="prob"),
lrn("classif.kknn", predict_type="prob"),
lrn("classif.log_reg", predict_type="prob")),
resampling = list(cv10_instance)))
result=bmr$aggregate(list(msr("classif.acc"),
msr("classif.auc")
))
result[,c("learner_id", "classif.acc", "classif.auc")]
Becker, M., Binder, M.,Bischl, B., Lang, M., Pfisterer, F.,Reich, N.G., Richter, J., Schratz, P., and Sonabend, R. (2020, November 22). mlr3 Book. https://mlr3book.mlr-org.com
Bischl, B., Pfisterer, F., and Binder, M. (2020, May 28). Pipelines and AutoML with mlr3. https://github.com/mlr-org/mlr-outreach/tree/master/2020_whyr
Yolanda, R. (2019, June 26). ANN classification with ‘nnet’ package in R. Medium. https://medium.com/@yolandawiyono98/ann-classification-with-nnet-package-in-r-3c4dc14d1f14