Salah satu isu kesehatan masyarakat di Indonesia adalah penggunaan kontrasepsi. Banyak aspek yang mungkin mempengaruhi penggunaan kontrasepsi termasuk didalamnya adalah faktor agama. Penelitian ini bertujuan untuk melihat gambaran faktor agama dalam penggunaan kontrasepsi. Dataset ini merupakan bagian dari Survei Prevalensi Kontrasepsi Nasional Indonesia Tahun 1987. Sampelnya adalah wanita menikah yang tidak sedang hamil atau tidak mengetahui dirinya sedang hamil pada saat wawancara. kita akan coba analisa prediksi agama islam apa non islam bagaimana hubungan kontrasepsi kondisi sosio ekonomi dengan motode pendekatan naive bayes, decision tree, dan random forest. Kita akan coba membandingkan dengan ketiga metode tersebut.
Pertama kita akan panggil library yang sudah di instal yaitu dply, e1071, dan caret
Mari kita baca data survei prevalsi kontrasepsi Nasional berikut :
data berikut belum ada nama kolom hanya ada simbol-simbol, kita akan menyesuaikan kolom tersebut sesuai dengan sumber data itu berasal
Pada beberapa variabel yang digunakan terdapat ketidaksesuaian tipe data, oleh karena itu yang perlu kita lakukan adalah melakukan penyesuaian tipe data pada beberapa variabel yang ada
colnames(cms_data) <- c("Wife.Age", "Wife.Education", "Husband.Education", "NumberOfChildren", "Wife.Religion", "WifeWorking", "HusbandOccupation", "StandardOfLiving", "MediaExposure","ContraceptiveMethod")lalu kita sesuaikan struktur data tersebut
library(dplyr)
cms_data <- cms_data %>%
mutate_at(vars("Wife.Education",
"Husband.Education",
"Wife.Religion",
"WifeWorking",
"HusbandOccupation",
"StandardOfLiving",
"MediaExposure",
"ContraceptiveMethod"), as.factor)
glimpse(cms_data)#> Rows: 1,472
#> Columns: 10
#> $ Wife.Age <int> 45, 43, 42, 36, 19, 38, 21, 27, 45, 38, 42, 44, 42…
#> $ Wife.Education <fct> 1, 2, 3, 3, 4, 2, 3, 2, 1, 1, 1, 4, 2, 3, 2, 1, 2,…
#> $ Husband.Education <fct> 3, 3, 2, 3, 4, 3, 3, 3, 1, 3, 4, 4, 4, 4, 4, 1, 2,…
#> $ NumberOfChildren <int> 10, 7, 9, 8, 0, 6, 1, 3, 8, 2, 4, 1, 1, 2, 0, 7, 6…
#> $ Wife.Religion <fct> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
#> $ WifeWorking <fct> 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1,…
#> $ HusbandOccupation <fct> 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 1, 1, 3, 2, 4, 2, 2,…
#> $ StandardOfLiving <fct> 4, 4, 3, 2, 3, 2, 2, 4, 2, 3, 3, 4, 3, 3, 1, 4, 4,…
#> $ MediaExposure <fct> 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,…
#> $ ContraceptiveMethod <fct> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
data tersebut kita sudah ubah sesuai dengan karakteristik datanya.
kemudian kita akan melakukan cek missing value
#> Wife.Age Wife.Education Husband.Education NumberOfChildren
#> 0 0 0 0
#> Wife.Religion WifeWorking HusbandOccupation StandardOfLiving
#> 0 0 0 0
#> MediaExposure ContraceptiveMethod
#> 0 0
dari hasil diatas tidak menunjukan missing value
#> Wife.Age Wife.Education Husband.Education NumberOfChildren
#> Min. :16.00 1:152 1: 44 Min. : 0.000
#> 1st Qu.:26.00 2:333 2:178 1st Qu.: 1.000
#> Median :32.00 3:410 3:351 Median : 3.000
#> Mean :32.54 4:577 4:899 Mean : 3.262
#> 3rd Qu.:39.00 3rd Qu.: 4.250
#> Max. :49.00 Max. :16.000
#> Wife.Religion WifeWorking HusbandOccupation StandardOfLiving MediaExposure
#> 0: 220 0: 369 1:436 1:129 0:1363
#> 1:1252 1:1103 2:424 2:229 1: 109
#> 3:585 3:430
#> 4: 27 4:684
#>
#>
#> ContraceptiveMethod
#> 1:628
#> 2:333
#> 3:511
#>
#>
#>
dari hasil diatas range min dan maksimal lumayan jauh dibawah kita akan proporsionalkan membagi data dan melakukan skala terhadap data.
kemudian kita akan melakukan cross validation dengan membagi data train dan data test dengan perbandingan 80% dan 20%
RNGkind(sample.kind = "Rounding")
set.seed(100)
# train-test splitting
index <- sample(x = nrow(cms_data), size = nrow(cms_data)*0.80)
cms_train <- cms_data[index,]
cms_test <- cms_data[-index,]kemudian akan melakukan cek proposi data train pada variabel target yaitu wife religion
#>
#> 0 1
#> 0.1537808 0.8462192
dari proporsi diatas data train sangat tidak seimbang, kita akan coba seimbangkan dengan fungsi downSample dengan proporsi 50 : 50 dengan target Wife Religion
Downsampling: mengurangi observasi kelas mayoritas hingga seimbang dengan kelas minoritas.
RNGkind(sample.kind = "Rounding")
set.seed(100)
cms_train <- downSample(x = cms_train %>% select(-Wife.Religion),
y = cms_train$Wife.Religion,
yname = "Wife.Religion")Nah sekarang dapat melakukan cek data apakah data sudah seimbang
#>
#> 0 1
#> 0.5 0.5
Ada karakteristik tertentu dari Naive Bayes yang harus diperhatikan:
library(caret)
# confusion matrix
# confusionMatric(data_prediksi, data_aktual)
confusionMatrix(cms_test$pred_label, cms_test$Wife.Religion)#> Confusion Matrix and Statistics
#>
#> Reference
#> Prediction 0 1
#> 0 34 85
#> 1 5 171
#>
#> Accuracy : 0.6949
#> 95% CI : (0.6389, 0.747)
#> No Information Rate : 0.8678
#> P-Value [Acc > NIR] : 1
#>
#> Kappa : 0.2887
#>
#> Mcnemar's Test P-Value : <0.0000000000000002
#>
#> Sensitivity : 0.8718
#> Specificity : 0.6680
#> Pos Pred Value : 0.2857
#> Neg Pred Value : 0.9716
#> Prevalence : 0.1322
#> Detection Rate : 0.1153
#> Detection Prevalence : 0.4034
#> Balanced Accuracy : 0.7699
#>
#> 'Positive' Class : 0
#>
positive : non islam negative : islam
Sekedar informasi, berikut adalah metrik yang akan evaluasi dari model
Isi dari Confusion Matrix:
Re-call/Sensitivity = dari semua data aktual yang positif, seberapa mampu proporsi model saya menebak benar. Specificity = dari semua data aktual yang negatif, seberapa mampu proporsi model saya menebak yang benar. Accuracy = seberapa mampu model saya menebak dengan benar target Y. Precision = dari semua hasil prediksi, seberapa mampu model saya dapat menebak benar kelas positif.
Model naive bayes memperoleh akurasi sebesar 69%, Sensitivity mengukur kemampuan model untuk mengidentifikasi dengan benar orang yang sebenarnya positif(non islam) dari semua orang yang sebenarnya positif.Karena penggunaan kontrasepsi lebih prioritas utama adalah kelas ke target positif maka hasil sensitivity 87,18%.
Pohon keputusan terdiri dari beberapa bagian. Kotak pertama di bagian atas plot adalah simpul akar. Akar akan membelah dan membuat cabang-cabang dengan aturan tertentu. Setiap cabang diakhiri dengan sebuah simpul. Beberapa node akan terpecah lagi menjadi node lain dan disebut node internal. Node yang tidak terpecah lagi atau muncul di ujung pohon disebut node terminal atau node daun, seperti daun pada pohon.
Setiap node menunjukkan:
kelas yang diprediksi (Sangat Baik/Buruk-Normal). probabilitas kelas Sangat Baik/Buruk-Normal. persentase pengamatan dalam simpul tersebut. akar dan simpul internal juga menunjukkan aturan (variabel dengan ambang batas/nilai) yang akan mempartisi setiap pengamatan.
Sebuah tree akan memilih untuk membagi data sedemikian rupa sehingga node yang dihasilkan akan berisi titik-titik data dengan kelas yang sama sebanyak mungkin (homogen). Salah satu ukuran homogenitas/kemurnian dalam kelompok adalah entropi atau ukuran ketidakteraturan. Entropi mendekati 0 berarti sebagian besar pengamatan berada dalam kelas yang sama (homogen). Entropi mendekati 1 berarti sebaliknya (heterogen). Pohon keputusan dibangun menggunakan mode top-down. Node akar akan dipilih dari variabel dan aturan kondisional yang akan memberikan entropi tertinggi. Root akan dipartisi (dipecah) menjadi node dengan masing-masing partisi memiliki entropi yang berbeda. Untuk referensi lebih lanjut mengenai perhitungan entropi, Anda dapat membaca artikel ini. Perbedaan entropi sebelum dan sesudah pemisahan disebut perolehan informasi. Pohon akan lebih memilih untuk melakukan pemisahan menggunakan variabel dan aturan yang akan menghasilkan perolehan informasi yang lebih tinggi (dari entropi tinggi ke entropi rendah).
Ada beberapa karakteristik tertentu dari model pohon keputusan:
Berkinerja baik pada variabel numerik dan kategorikal.
Semua prediktor diasumsikan berinteraksi.
cukup kuat untuk masalah multikolinearitas. Pohon keputusan akan memilih variabel yang memiliki perolehan informasi tertinggi dalam satu pemisahan, sedangkan metode seperti regresi logistik akan menggunakan keduanya.
kuat dan tidak sensitif terhadap outlier. Pemisahan akan terjadi pada kondisi yang memaksimalkan homogenitas dalam kelompok yang dihasilkan. Pencilan akan mempunyai pengaruh yang kecil terhadap proses pemisahan.
#>
#> Model formula:
#> Wife.Religion ~ Wife.Age + Wife.Education + Husband.Education +
#> NumberOfChildren + WifeWorking + HusbandOccupation + StandardOfLiving +
#> MediaExposure + ContraceptiveMethod
#>
#> Fitted party:
#> [1] root
#> | [2] Wife.Education in 1, 2: 1 (n = 94, err = 23.4%)
#> | [3] Wife.Education in 3, 4
#> | | [4] Wife.Age <= 24: 1 (n = 41, err = 26.8%)
#> | | [5] Wife.Age > 24
#> | | | [6] NumberOfChildren <= 6: 0 (n = 217, err = 33.2%)
#> | | | [7] NumberOfChildren > 6: 1 (n = 10, err = 30.0%)
#>
#> Number of inner nodes: 3
#> Number of terminal nodes: 4
Dapat diliat dari pohon keputusan diatas - Root Node: Percabangan pertama dalam menentukan nilai target, biasa disebut sebagai predictor utama. -> Wife Education dengan p value < 0,001 - Interior Node: Percabangan selanjutnya yang menggunakan predictor lain apabila root node tidak cukup dalam menentukan target.-> Wife Age dengan p value <0.001 - Terminal/Leaf Node: Keputusan akhir berupa nilai target yang dipredik -> NumberOf Children dengan p-value 0.034
E valuasi cms_tree menggunakan confusion matrix
berdasarkan hasil prediksi di data test menggunakan fungsi
predict()
library(caret)
# prediksi label kelas di data test
pred_cms <- predict(object = cms_tree, newdata = cms_test, type = "response")
# confusion matrix data test
confusionMatrix(data = pred_cms, reference = cms_test$Wife.Religion, positive = "0")#> Confusion Matrix and Statistics
#>
#> Reference
#> Prediction 0 1
#> 0 32 104
#> 1 7 152
#>
#> Accuracy : 0.6237
#> 95% CI : (0.5657, 0.6792)
#> No Information Rate : 0.8678
#> P-Value [Acc > NIR] : 1
#>
#> Kappa : 0.2017
#>
#> Mcnemar's Test P-Value : <0.0000000000000002
#>
#> Sensitivity : 0.8205
#> Specificity : 0.5938
#> Pos Pred Value : 0.2353
#> Neg Pred Value : 0.9560
#> Prevalence : 0.1322
#> Detection Rate : 0.1085
#> Detection Prevalence : 0.4610
#> Balanced Accuracy : 0.7071
#>
#> 'Positive' Class : 0
#>
Sensitivity mengukur kemampuan model untuk mengidentifikasi dengan benar orang - orang yang sebenarnya positif non islam dari semua orang sebenarnya positif. Sensitivity yang lebih tinggi bahwa model memiliki kemampuan yang lebih baik untuk mengenali orang orang yang sesuai dengan kelas positif
Specificity mengukur kemampuan model untuk mengidentifikasi dengan benar orang orang yang sebenarnya negatif (islam) dari semua orang yang sebenarnya negatif. Specificity yang lebih tinggi berarti bahwa model memiliki kemampuan yang lebih baik untuk mengenali orang orang yang sesuai dengan kelas negatif
Karena fokus prioritas pada kelas positif (non islam) maka sensitivity pada model ini pada data dest adalah 79,56%.
Hal ini terjadi karena Decision tree mampu membagi-bagi data hingga amat detail (bahkan hingga dalam leaf node hanya terdapat 1 observasi). Pada keadaan ini, decision tree justru menghapal pola di data train, dan membuat aturan yang terlalu kompleks, bukan mempelajari pola tersebut. Alhasil model menjadi kurang general untuk diaplikasikan ke data yang bukan data train, sehingga cenderung overfit.
Solusi: Untuk mengatasinya, decision tree perlu tahu kapan ia berhenti membuat cabang sehingga pohon yang dihasilkan tidak terlalu kompleks. Pemotongan/pencegahan cabang pohon disebut Pruning.
Dapat dilakukan tuning terhadap cms_tree agar tidak
terlalu kompleks (lebih sederhana) dengan mengubah parameter berikut di
fungsi ctree():
Sehingga mari kita lakukan tuning terhadap cms_tree dengan mengubah parameter tersebut.
cms_model_complex <- ctree(formula = Wife.Religion~.,
data = cms_train,
control = ctree_control(mincriterion = 0.05,
minsplit = 15,
minbucket = 10))
plot(cms_model_complex, type='simple')kita coba bandingkan data train dan data test yang kita miliki apakah dia memiliki overfitting.
data test
pred_model <- predict(object = cms_model_complex, newdata = cms_test, type = "response")
confusionMatrix(data = pred_model, reference = cms_test$Wife.Religion, positive = "0")#> Confusion Matrix and Statistics
#>
#> Reference
#> Prediction 0 1
#> 0 27 98
#> 1 12 158
#>
#> Accuracy : 0.6271
#> 95% CI : (0.5692, 0.6825)
#> No Information Rate : 0.8678
#> P-Value [Acc > NIR] : 1
#>
#> Kappa : 0.16
#>
#> Mcnemar's Test P-Value : 0.0000000000000005299
#>
#> Sensitivity : 0.69231
#> Specificity : 0.61719
#> Pos Pred Value : 0.21600
#> Neg Pred Value : 0.92941
#> Prevalence : 0.13220
#> Detection Rate : 0.09153
#> Detection Prevalence : 0.42373
#> Balanced Accuracy : 0.65475
#>
#> 'Positive' Class : 0
#>
data train
pred_model <- predict(object = cms_model_complex, newdata = cms_train, type = "response")
confusionMatrix(data = pred_model, reference = cms_train$Wife.Religion, positive = "0")#> Confusion Matrix and Statistics
#>
#> Reference
#> Prediction 0 1
#> 0 144 53
#> 1 37 128
#>
#> Accuracy : 0.7514
#> 95% CI : (0.7035, 0.7951)
#> No Information Rate : 0.5
#> P-Value [Acc > NIR] : <0.0000000000000002
#>
#> Kappa : 0.5028
#>
#> Mcnemar's Test P-Value : 0.1138
#>
#> Sensitivity : 0.7956
#> Specificity : 0.7072
#> Pos Pred Value : 0.7310
#> Neg Pred Value : 0.7758
#> Prevalence : 0.5000
#> Detection Rate : 0.3978
#> Detection Prevalence : 0.5442
#> Balanced Accuracy : 0.7514
#>
#> 'Positive' Class : 0
#>
dari analisa data train dan data dest, kedua data tersebut tidak overfitting.
kita akan coba membuat model Random Forest dengan data train. Di R
ada fungsi yang dapat menggabungkan proses K-Fold Cross Validation
dengan berbagai model machine learning, yaitu fungsi
train() dari library caret.
Untuk random forest, parameter train(): -
form : y ~ x - data : data yang digunakan -
method : “rf” - trControl: kontrol untuk
metode resampling menggunakan fungsi trainControl() dengan
parameter: + method : metode resampling +
number : jumlah fold (k-fold) + repeats:
pengulangan k-fold cross-validation
Membuat model Random Forest menggunakan cms_train dengan
5-fold cross validation, kemudian proses tersebut diulang sebanyak 3
kali.
set.seed(417)
ctrl <- trainControl(method = "repeatedcv", #repeat k-fold cross validation, cv = kfold
number = 5, # k-fold
repeats = 3) # repetisi
#
cms_forest <- train(Wife.Religion ~ ., # formula model
data = cms_train, # data yg digunakan
method = "rf", # random forest
trControl = ctrl)
# SAVE AS RDS
saveRDS(cms_forest, file = ("cms_forest.RDS")) # .RDS = menyimpan model dalam bentuk RDSSalah satu kelemahan Random Forest adalah pembuatan model yang
membutuhkan waktu yang cukup lama. Practice yang baik saat 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
#>
#> 362 samples
#> 9 predictor
#> 2 classes: '0', '1'
#>
#> No pre-processing
#> Resampling: Cross-Validated (5 fold, repeated 3 times)
#> Summary of sample sizes: 290, 289, 290, 289, 290, 290, ...
#> Resampling results across tuning parameters:
#>
#> mtry Accuracy Kappa
#> 2 0.6841832 0.3683954
#> 10 0.6612253 0.3224894
#> 18 0.6500888 0.3001378
#>
#> Accuracy was used to select the optimal model using the largest value.
#> The final value used for the model was mtry = 2.
Penjelasan dari output summary model random Forest:
Pada kasus ini model yang dipilih adalah dengan mtry = 2, yang memiliki akurasi tertinggi ketika diujikan ke data hasil boostrap sampling (bisa dianggap sebagai data train pada pembuatan decision tree pada random forest).
#>
#> 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: 2
#>
#> OOB estimate of error rate: 32.87%
#> Confusion matrix:
#> 0 1 class.error
#> 0 132 49 0.2707182
#> 1 70 111 0.3867403
Nilai Eror CMS_Forest memiliki OOB 32,8%
prediksi_rf <- predict(object = cms_forest,newdata = cms_test)
confusionMatrix(data = prediksi_rf,reference = cms_test$Wife.Religion)#> Confusion Matrix and Statistics
#>
#> Reference
#> Prediction 0 1
#> 0 30 94
#> 1 9 162
#>
#> Accuracy : 0.6508
#> 95% CI : (0.5934, 0.7052)
#> No Information Rate : 0.8678
#> P-Value [Acc > NIR] : 1
#>
#> Kappa : 0.209
#>
#> Mcnemar's Test P-Value : <0.0000000000000002
#>
#> Sensitivity : 0.7692
#> Specificity : 0.6328
#> Pos Pred Value : 0.2419
#> Neg Pred Value : 0.9474
#> Prevalence : 0.1322
#> Detection Rate : 0.1017
#> Detection Prevalence : 0.4203
#> Balanced Accuracy : 0.7010
#>
#> 'Positive' Class : 0
#>
Pada prediksi model RF didapatkan akurasi 65,08% dengan Sensitivity 76,92% dimana kemampuan modelk untuk identifikasi dengan benar orang yang sebenarnya positif (non islam) dari semua orang yang sebenarnya positif
Dari hasil diatas prediktor yang mempengaruhi pada model Random Forest adalah Wife Age
Model yang digunakan sudah di proporsionalkan pada train 50 : 50 model yang baik digunakan adalah model naive bayes dengan sensitivity 87,18% dengan akurasi 69%. Pada kasus penggunaan kontrasepsi ini dikarenakan banyak pro kontranya, dari hasil prediksinya, kita akan menghindari kelas negatif dikarenakan ada hadist yang sebenarnya melarang penggunaan kontrasepsi didalam islam dikarenakan islam mendukung untuk melahirkan banyak anak sehingga dengan mengurangi FN.