Pada artikel ini saya akan menganalisis mengenai data Sleep Health and Lifestyle. Tidur merupakan saran untuk recharge dan beristirahat agar tubuh tetap berstamina ketika melakukan aktivitas. Namun, tidak jarang seseorang tidak dapat tidur dengan pulas dan susah tidur/insomnia. Kondisi kesehatan tidur seseorang dapat dipengaruhi oleh kualitas tidur, durasi tidur, dan gaya hidup seseorang. Sleep Disorder ini merupakan masalah krusial. Karena jika masalah gangguan tidur ini tidak segera ditangani akan berdampak pada kinerja, performasni, dan kefokusan sesorang ketika berkegiatan. Tidak hanya itu, yang lebih parah, jika terus menerus mendapatkan gangguan tidur yang berkepanjangan akan menganggu kesehatan juga dan dapat meningkatkan risiko munculnya berbagai penyakit kronis. seperti hipertensi, stroke, dan jantung. Oleh karena itu, dengan bantuan Machine Learning dapat diketahui mengenai kondisi tidur seseorang, dideteksi menggunakan automasi apakah seseorang mengalami sleep disorder atau tidak seperti insomnia atau apnea. Kondisi yang diinginkan adalah seorang tersebut tidak mengalami sleeping disorder.
Tahap pertama dalam melakukan pengolahan data adalah dengan melakukan import untuk membaca data set dalam bentuk csv kemudian assign ke dalam objek yang bernama sleep.
# membaca dataset
sleep <- read.csv("Sleep_health_and_lifestyle_dataset.csv")
head(sleep)
## Person.ID Gender Age Occupation Sleep.Duration Quality.of.Sleep
## 1 1 Male 27 Software Engineer 6.1 6
## 2 2 Male 28 Doctor 6.2 6
## 3 3 Male 28 Doctor 6.2 6
## 4 4 Male 28 Sales Representative 5.9 4
## 5 5 Male 28 Sales Representative 5.9 4
## 6 6 Male 28 Software Engineer 5.9 4
## Physical.Activity.Level Stress.Level BMI.Category Blood.Pressure Heart.Rate
## 1 42 6 Overweight 126/83 77
## 2 60 8 Normal 125/80 75
## 3 60 8 Normal 125/80 75
## 4 30 8 Obese 140/90 85
## 5 30 8 Obese 140/90 85
## 6 30 8 Obese 140/90 85
## Daily.Steps Sleep.Disorder
## 1 4200 None
## 2 10000 None
## 3 10000 None
## 4 3000 Sleep Apnea
## 5 3000 Sleep Apnea
## 6 3000 Insomnia
Tahap ini digunakan untuk mengetahui informasi data dan mengecek tipe data untuk setiap variabel/kolom data.
# cek informasi masi data
library(dplyr)
##
## 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
glimpse(sleep)
## Rows: 374
## Columns: 13
## $ Person.ID <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,…
## $ Gender <chr> "Male", "Male", "Male", "Male", "Male", "Male"…
## $ Age <int> 27, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29…
## $ Occupation <chr> "Software Engineer", "Doctor", "Doctor", "Sale…
## $ Sleep.Duration <dbl> 6.1, 6.2, 6.2, 5.9, 5.9, 5.9, 6.3, 7.8, 7.8, 7…
## $ Quality.of.Sleep <int> 6, 6, 6, 4, 4, 4, 6, 7, 7, 7, 6, 7, 6, 6, 6, 6…
## $ Physical.Activity.Level <int> 42, 60, 60, 30, 30, 30, 40, 75, 75, 75, 30, 75…
## $ Stress.Level <int> 6, 8, 8, 8, 8, 8, 7, 6, 6, 6, 8, 6, 8, 8, 8, 8…
## $ BMI.Category <chr> "Overweight", "Normal", "Normal", "Obese", "Ob…
## $ Blood.Pressure <chr> "126/83", "125/80", "125/80", "140/90", "140/9…
## $ Heart.Rate <int> 77, 75, 75, 85, 85, 85, 82, 70, 70, 70, 70, 70…
## $ Daily.Steps <int> 4200, 10000, 10000, 3000, 3000, 3000, 3500, 80…
## $ Sleep.Disorder <chr> "None", "None", "None", "Sleep Apnea", "Sleep …
Keterangan:
Terdapat 374 objek pengamatan/responden/baris
Terdapat 13 variabel/kolom diantaranya adalah:
Person.ID : ID setiap individuGender : Jenis kelamin seseorangAge : Usia seseorangOccupation : Profesi pekerjaan seseorangSleep.Duration : Lama waktu tidur seseorang (jam per hari)Quality.of.Sleep : Penilaian subjektif kualitas tidur seseorang dari angka 1-10Physical.Activity.Level : Jumlah menit seseorang melakukan aktivitas fisik setiap hari (menit/hari)Stress.Level : Tingkat stress subjektif dari tingkat stress seseorang berkisar dari 1-10BMI.Category : Kategori BMI seseorang (Underweight : Kurus, Normal, Overweight)Blood.Pressure : Pengukuran tekanan darah seseorang, ditunjukkan sebagai tekanan sistolik di atas tekanan diastolik.Heart.Rate: Detak jantung istirahat seseorang dalam detak per menit.Daily.Step : Jumlah langkah yang dilakukan seseorang per hari.Sleep.Disorder : Ada tidaknya gangguan tidur pada orang tersebut (None, Insomnia, Sleep Apnea).# ubah tipe data
sleep <- sleep %>%
mutate_at(vars(Gender, Occupation, BMI.Category, Sleep.Disorder), as.factor)
# cek missing value
colSums(is.na(sleep))
## Person.ID Gender Age
## 0 0 0
## Occupation Sleep.Duration Quality.of.Sleep
## 0 0 0
## Physical.Activity.Level Stress.Level BMI.Category
## 0 0 0
## Blood.Pressure Heart.Rate Daily.Steps
## 0 0 0
## Sleep.Disorder
## 0
Keterangan:
Data tidak memiliki missing value sehingga tidak perlu dihandle.
Dikarenakan kolomBlood.Pressure terdapat string “/” yang mengartikan bahwa tekanan darah sistole/distole nya. sehingga pelru dipisah sendiri-sendiri menjadi kolom sistole sendiri dak distole sendiri agar tekanan darah dalam bentuk numerik
# Memisahkan karakter string dan menjadikan nya 2 kolom terpisah
library(stringr)
sleep[c("Sistole", "Diastole")] <- str_split_fixed(sleep$Blood.Pressure, "/", 2)
head(sleep)
## Person.ID Gender Age Occupation Sleep.Duration Quality.of.Sleep
## 1 1 Male 27 Software Engineer 6.1 6
## 2 2 Male 28 Doctor 6.2 6
## 3 3 Male 28 Doctor 6.2 6
## 4 4 Male 28 Sales Representative 5.9 4
## 5 5 Male 28 Sales Representative 5.9 4
## 6 6 Male 28 Software Engineer 5.9 4
## Physical.Activity.Level Stress.Level BMI.Category Blood.Pressure Heart.Rate
## 1 42 6 Overweight 126/83 77
## 2 60 8 Normal 125/80 75
## 3 60 8 Normal 125/80 75
## 4 30 8 Obese 140/90 85
## 5 30 8 Obese 140/90 85
## 6 30 8 Obese 140/90 85
## Daily.Steps Sleep.Disorder Sistole Diastole
## 1 4200 None 126 83
## 2 10000 None 125 80
## 3 10000 None 125 80
## 4 3000 Sleep Apnea 140 90
## 5 3000 Sleep Apnea 140 90
## 6 3000 Insomnia 140 90
Setelah nilai Blood.Pressure menjadi 2 kolom terpisah kemudian variabel Blood.Pressure akan dibuang. Dan Karena kolom Person.ID hanya sebagai unique value ID setiap individu yang tidak menunjukkan nilai yang berarti maka akan didrop.
# membuang kolom Blood.Pressure
sleep <- sleep %>%
select(-Blood.Pressure, -Person.ID)
Karena kolom Sistole dan Diastole tipe data nya masih character maka perlu diubah menjadi numerik
# ubah tipe data as.int
sleep <- sleep %>%
mutate_at(vars(Sistole, Diastole), as.integer)
table(sleep$Sleep.Disorder, sleep$BMI.Category)
##
## Normal Normal Weight Obese Overweight
## Insomnia 7 2 4 64
## None 183 17 0 19
## Sleep Apnea 5 2 6 65
Keterangan :
Dikarenakan terdapat kelas yang prediktornya memiliki nilai frekuensi 0 maka menggunakan parameter laplace.
summary(sleep)
## Gender Age Occupation Sleep.Duration Quality.of.Sleep
## Female:185 Min. :27.00 Nurse :73 Min. :5.800 Min. :4.000
## Male :189 1st Qu.:35.25 Doctor :71 1st Qu.:6.400 1st Qu.:6.000
## Median :43.00 Engineer :63 Median :7.200 Median :7.000
## Mean :42.18 Lawyer :47 Mean :7.132 Mean :7.313
## 3rd Qu.:50.00 Teacher :40 3rd Qu.:7.800 3rd Qu.:8.000
## Max. :59.00 Accountant:37 Max. :8.500 Max. :9.000
## (Other) :43
## Physical.Activity.Level Stress.Level BMI.Category Heart.Rate
## Min. :30.00 Min. :3.000 Normal :195 Min. :65.00
## 1st Qu.:45.00 1st Qu.:4.000 Normal Weight: 21 1st Qu.:68.00
## Median :60.00 Median :5.000 Obese : 10 Median :70.00
## Mean :59.17 Mean :5.385 Overweight :148 Mean :70.17
## 3rd Qu.:75.00 3rd Qu.:7.000 3rd Qu.:72.00
## Max. :90.00 Max. :8.000 Max. :86.00
##
## Daily.Steps Sleep.Disorder Sistole Diastole
## Min. : 3000 Insomnia : 77 Min. :115.0 Min. :75.00
## 1st Qu.: 5600 None :219 1st Qu.:125.0 1st Qu.:80.00
## Median : 7000 Sleep Apnea: 78 Median :130.0 Median :85.00
## Mean : 6817 Mean :128.6 Mean :84.65
## 3rd Qu.: 8000 3rd Qu.:135.0 3rd Qu.:90.00
## Max. :10000 Max. :142.0 Max. :95.00
##
levels(sleep$Sleep.Disorder)
## [1] "Insomnia" "None" "Sleep Apnea"
Positive -> None
plot1 <- sleep %>%
group_by(Sleep.Disorder, Gender) %>%
summarise(Freq = n()) %>%
arrange(desc(Freq))
## `summarise()` has grouped output by 'Sleep.Disorder'. You can override using
## the `.groups` argument.
library(ggplot2)
ggplot(data = plot1, mapping = aes(x = Sleep.Disorder, y = Freq)) +
geom_col(aes(fill = Gender)) +
labs(title = "Jumlah Sleep Order berdasarkan Jenis Kelamin") +
theme_classic()
plot2 <- sleep %>%
group_by(Gender, Sleep.Disorder) %>%
summarise(Jumlah = n())
## `summarise()` has grouped output by 'Gender'. You can override using the
## `.groups` argument.
plot2
## # A tibble: 6 × 3
## # Groups: Gender [2]
## Gender Sleep.Disorder Jumlah
## <fct> <fct> <int>
## 1 Female Insomnia 36
## 2 Female None 82
## 3 Female Sleep Apnea 67
## 4 Male Insomnia 41
## 5 Male None 137
## 6 Male Sleep Apnea 11
ggplot(data= plot2, mapping = aes(x = Gender, y = Jumlah)) +
geom_col(aes(fill = Sleep.Disorder) , position = "fill") +
theme_classic() +
labs(title = "Proporsi Gender menurut status sleeping disorder nya")
Insight:
Naive Bayes adalah metode klasifikasi yang berbasis peluang kejadian akan terjadi jika diketahui keadaan/kejadian yang lain. Workflow dalam membangun model Naive Bayes adalah :
RNGkind(sample.kind = "Rounding")
## Warning in RNGkind(sample.kind = "Rounding"): non-uniform 'Rounding' sampler
## used
set.seed(100)
index <- sample(x = nrow(sleep) , size = nrow(sleep)*0.8 )
data_train <- sleep[index,]
data_test <- sleep[-index, ]
# membangun model menggunakan naive bayes
library(e1071)
## Warning: package 'e1071' was built under R version 4.2.3
model_nbayes <- naiveBayes(formula = Sleep.Disorder ~ .,
data = data_train,
laplace = 1)
# menampilkan summary model
model_nbayes
##
## Naive Bayes Classifier for Discrete Predictors
##
## Call:
## naiveBayes.default(x = X, y = Y, laplace = laplace)
##
## A-priori probabilities:
## Y
## Insomnia None Sleep Apnea
## 0.1939799 0.6020067 0.2040134
##
## Conditional probabilities:
## Gender
## Y Female Male
## Insomnia 0.51666667 0.48333333
## None 0.36813187 0.63186813
## Sleep Apnea 0.92063492 0.07936508
##
## Age
## Y [,1] [,2]
## Insomnia 43.68966 4.519769
## None 38.89444 7.578636
## Sleep Apnea 51.03279 8.382456
##
## Occupation
## Y Accountant Doctor Engineer Lawyer Manager
## Insomnia 0.101449275 0.043478261 0.086956522 0.043478261 0.014492754
## None 0.136125654 0.272251309 0.256544503 0.188481675 0.010471204
## Sleep Apnea 0.013888889 0.041666667 0.013888889 0.027777778 0.013888889
## Occupation
## Y Nurse Sales Representative Salesperson Scientist
## Insomnia 0.028985507 0.014492754 0.289855072 0.014492754
## None 0.036649215 0.005235602 0.015706806 0.010471204
## Sleep Apnea 0.736111111 0.041666667 0.013888889 0.027777778
## Occupation
## Y Software Engineer Teacher
## Insomnia 0.028985507 0.333333333
## None 0.015706806 0.052356021
## Sleep Apnea 0.013888889 0.055555556
##
## Sleep.Duration
## Y [,1] [,2]
## Insomnia 6.634483 0.4157225
## None 7.389444 0.6994409
## Sleep Apnea 7.095082 1.0020689
##
## Quality.of.Sleep
## Y [,1] [,2]
## Insomnia 6.655172 0.8282665
## None 7.655556 0.9294813
## Sleep Apnea 7.344262 1.6821142
##
## Physical.Activity.Level
## Y [,1] [,2]
## Insomnia 46.72414 11.79324
## None 58.43889 20.81500
## Sleep Apnea 76.09836 16.46988
##
## Stress.Level
## Y [,1] [,2]
## Insomnia 5.672414 1.491354
## None 5.055556 1.523456
## Sleep Apnea 5.475410 2.405595
##
## BMI.Category
## Y Normal Normal Weight Obese Overweight
## Insomnia 0.129032258 0.032258065 0.048387097 0.790322581
## None 0.842391304 0.081521739 0.005434783 0.070652174
## Sleep Apnea 0.030769231 0.046153846 0.092307692 0.830769231
##
## Heart.Rate
## Y [,1] [,2]
## Insomnia 69.77586 4.845121
## None 68.90556 2.466982
## Sleep Apnea 73.08197 5.289282
##
## Daily.Steps
## Y [,1] [,2]
## Insomnia 5939.655 868.9457
## None 6858.333 1322.2579
## Sleep Apnea 7573.770 2202.4155
##
## Sistole
## Y [,1] [,2]
## Insomnia 131.9138 3.894596
## None 123.8222 5.613387
## Sleep Apnea 138.7049 4.071626
##
## Diastole
## Y [,1] [,2]
## Insomnia 86.82759 3.212574
## None 80.85556 3.780459
## Sleep Apnea 93.50820 3.699653
Interpretasi :
Gender
Seorang laki-laki memiliki peluang insomnia sebesar 0.48275862, peluang tidak mengalami gangguan tidur sebesar 0.6255708, peluang mengalami sleep Apnea sebesar 0.06557377
Sedangkan seorang yang perempuan memiliki peluang insomnia sebesar 0.51724138, peluang tidak mengalami gangguan tidur sebesar 0.33333367, peluang mengalami sleep Apnea sebesar 0.93442623
Kondisi ini sama dengan insight yang didapat dari EDA diagram batang, yaitu perempuan memiliki peluang sleep Apnea lebih besar daripada laki-laki, laki-laki memiliki peluang lebih besar mengalami insomnia daripda perempuan laki-laki memilii peluang lebih besar tidak mengalami gangguan tidur daripada permpuan
BMI
Orang yang overweight memiliki peluang insomnia sebesar 0.82758621, peluang tidak memiliki gangguan tidur sebesar 0.0666667, dan memilki gangguan sleep apnea sebesar 0.86885246 yang artinya bahwa orang yang overwieght memiliki peluang yang besar untuk mengalai gangguan tidur, dikarenakan peluang None hsmpir sebsar 0.
Orang yang memiliki BMI obese dan Overweight akan berpeluang besar mengalami gangguan tidur. Sedangkan orang yang memiliki BMI normal memilki peluang besar tidak mengalami gangguan tidur.
# prediksi model untuk data test
pred_nbayes <- predict(object = model_nbayes ,newdata = data_test, type = "class")
pred_nbayes
## [1] Insomnia None Insomnia None None None
## [7] Insomnia None None None None None
## [13] None None Insomnia None None None
## [19] Insomnia None None Insomnia Insomnia Insomnia
## [25] None None None None None None
## [31] None None None None None None
## [37] Insomnia Insomnia None None None Insomnia
## [43] Insomnia Insomnia Insomnia Insomnia Insomnia Insomnia
## [49] Insomnia Insomnia Insomnia Insomnia Insomnia Sleep Apnea
## [55] Sleep Apnea Sleep Apnea Sleep Apnea Sleep Apnea Sleep Apnea Sleep Apnea
## [61] Sleep Apnea Sleep Apnea Sleep Apnea Insomnia None None
## [67] None None None None None Sleep Apnea
## [73] Sleep Apnea Sleep Apnea Sleep Apnea
## Levels: Insomnia None Sleep Apnea
library(caret)
## Warning: package 'caret' was built under R version 4.2.3
## Loading required package: lattice
confusionMatrix(data = pred_nbayes ,
reference = data_test$Sleep.Disorder,
mode = "everything",
positive = "None")
## Confusion Matrix and Statistics
##
## Reference
## Prediction Insomnia None Sleep Apnea
## Insomnia 17 2 4
## None 0 34 4
## Sleep Apnea 2 3 9
##
## Overall Statistics
##
## Accuracy : 0.8
## 95% CI : (0.6917, 0.8835)
## No Information Rate : 0.52
## P-Value [Acc > NIR] : 4.645e-07
##
## Kappa : 0.6756
##
## Mcnemar's Test P-Value : 0.4219
##
## Statistics by Class:
##
## Class: Insomnia Class: None Class: Sleep Apnea
## Sensitivity 0.8947 0.8718 0.5294
## Specificity 0.8929 0.8889 0.9138
## Pos Pred Value 0.7391 0.8947 0.6429
## Neg Pred Value 0.9615 0.8649 0.8689
## Precision 0.7391 0.8947 0.6429
## Recall 0.8947 0.8718 0.5294
## F1 0.8095 0.8831 0.5806
## Prevalence 0.2533 0.5200 0.2267
## Detection Rate 0.2267 0.4533 0.1200
## Detection Prevalence 0.3067 0.5067 0.1867
## Balanced Accuracy 0.8938 0.8803 0.7216
Dikarenakan nilai positive adalah “None” sehingga kita ingin model banyak memprediksi benar pada kelas “None” dan salah prediksi “None” yang sedikit. Namun di sini tidak menggunakan akurasi ROC atau AUC karena target memiiki 3 kelas. dan ketika dicoba dilakukan code hasilnya eror. sehingga evaluasi nya memakai confusion matrix.
FN : diprediksi negatif (mengalami gangguan tidur) padahal sebenarnya tidak mengalami gangguan tidur (None). -> tidak ingin model eror/salah banyak dalam memprediksi kelas none [concern] FP : diprediksi tidak mengalami gangguan tidur (None) padahal sebenarnya mengalami gangguan tidur.
Sehingga matrix yang digunakan adalah matrix sensitifity yaitu sebesar 0.8718.
atau bisa menggunakan cf1. jika ingin semua melihat kesalahan dalam memprediksi yang negatif dan kesalahan dalam memprediksi yang positif. f1 sebesar =
library(partykit)
## Warning: package 'partykit' was built under R version 4.2.3
## Loading required package: grid
## Loading required package: libcoin
## Warning: package 'libcoin' was built under R version 4.2.3
## Loading required package: mvtnorm
model_dctree <- ctree(formula = Sleep.Disorder ~ . ,
data = data_train)
model_dctree
##
## Model formula:
## Sleep.Disorder ~ Gender + Age + Occupation + Sleep.Duration +
## Quality.of.Sleep + Physical.Activity.Level + Stress.Level +
## BMI.Category + Heart.Rate + Daily.Steps + Sistole + Diastole
##
## Fitted party:
## [1] root
## | [2] Occupation in Accountant, Doctor, Engineer, Lawyer, Manager, Salesperson, Software Engineer, Teacher
## | | [3] BMI.Category in Normal, Normal Weight
## | | | [4] Occupation in Accountant, Doctor, Engineer, Lawyer: None (n = 165, err = 4.2%)
## | | | [5] Occupation in Software Engineer, Teacher: None (n = 8, err = 12.5%)
## | | [6] BMI.Category in Obese, Overweight
## | | | [7] Sleep.Duration <= 6.7: Insomnia (n = 52, err = 11.5%)
## | | | [8] Sleep.Duration > 6.7: Sleep Apnea (n = 11, err = 54.5%)
## | [9] Occupation in Nurse, Sales Representative, Scientist
## | | [10] Sistole <= 131: None (n = 7, err = 28.6%)
## | | [11] Sistole > 131: Sleep Apnea (n = 56, err = 5.4%)
##
## Number of inner nodes: 5
## Number of terminal nodes: 6
plot(model_dctree, type = "simple")
#Melakukan Prediksi pada data test
pred_dctree <- predict(object = model_dctree ,
newdata = data_test,
type = "response")
# melakukan evaluasi model
confusionMatrix(data = pred_dctree,
reference = data_test$Sleep.Disorder,
mode = "everything",
positive = "None")
## Confusion Matrix and Statistics
##
## Reference
## Prediction Insomnia None Sleep Apnea
## Insomnia 16 1 2
## None 1 33 5
## Sleep Apnea 2 5 10
##
## Overall Statistics
##
## Accuracy : 0.7867
## 95% CI : (0.6768, 0.8729)
## No Information Rate : 0.52
## P-Value [Acc > NIR] : 1.656e-06
##
## Kappa : 0.6526
##
## Mcnemar's Test P-Value : 1
##
## Statistics by Class:
##
## Class: Insomnia Class: None Class: Sleep Apnea
## Sensitivity 0.8421 0.8462 0.5882
## Specificity 0.9464 0.8333 0.8793
## Pos Pred Value 0.8421 0.8462 0.5882
## Neg Pred Value 0.9464 0.8333 0.8793
## Precision 0.8421 0.8462 0.5882
## Recall 0.8421 0.8462 0.5882
## F1 0.8421 0.8462 0.5882
## Prevalence 0.2533 0.5200 0.2267
## Detection Rate 0.2133 0.4400 0.1333
## Detection Prevalence 0.2533 0.5200 0.2267
## Balanced Accuracy 0.8943 0.8397 0.7338
Dikarenakan nilai positive adalah “None” sehingga kita ingin model banyak memprediksi benar pada kelas “None” dan salah prediksi “None” yang sedikit. Namun di sini tidak menggunakan akurasi ROC atau AUC karena target memiiki 3 kelas. dan ketika dicoba dilakukan code hasilnya eror. namun bisa menggunakan nilai f1 untuk mengetahui eror dalam memprediksi false positif dan false negatif.
FN : diprediksi negatif (mengalami gangguan tidur) padahal sebenarnya tidak mengalami gangguan tidur (None). -> tidak ingin model eror/salah banyak dalam memprediksi kelas none [concern] FP : diprediksi tidak mengalami gangguan tidur (None) padahal sebenarnya mengalami gangguan tidur.
Sehingga matrix yang digunakan adalah matrix sensitifity/f1 yaitu sebesar 0.8462.
Untuk mengetahui permofrma model pada data train dan pada data test untuk mengetahui model lebih bagus di data train atau data test.
# Prediksi pada data train
pred_dctree_train <- predict(object = model_dctree,
newdata = data_train ,
type = "response")
# Cek akurasi pada data train
confusionMatrix(data = pred_dctree_train,
reference = data_train$Sleep.Disorder ,
mode = "everything",
positive = "None")
## Confusion Matrix and Statistics
##
## Reference
## Prediction Insomnia None Sleep Apnea
## Insomnia 46 6 0
## None 7 170 3
## Sleep Apnea 5 4 58
##
## Overall Statistics
##
## Accuracy : 0.9164
## 95% CI : (0.879, 0.9452)
## No Information Rate : 0.602
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.8502
##
## Mcnemar's Test P-Value : 0.1564
##
## Statistics by Class:
##
## Class: Insomnia Class: None Class: Sleep Apnea
## Sensitivity 0.7931 0.9444 0.9508
## Specificity 0.9751 0.9160 0.9622
## Pos Pred Value 0.8846 0.9444 0.8657
## Neg Pred Value 0.9514 0.9160 0.9871
## Precision 0.8846 0.9444 0.8657
## Recall 0.7931 0.9444 0.9508
## F1 0.8364 0.9444 0.9062
## Prevalence 0.1940 0.6020 0.2040
## Detection Rate 0.1538 0.5686 0.1940
## Detection Prevalence 0.1739 0.6020 0.2241
## Balanced Accuracy 0.8841 0.9302 0.9565
Perbadingan Akurasi:
Data Train: 0.9444
Data Test: 0.8462
Kondisi Model:
Model diindikasikan overfitting, dikarenakan model memiliki nilai akurasi yang lebih besar di data train daripada di data test.
Mengatur Parameter agar model tidak terlalu kompleks dalam membuat node/cabang. sehingga dilakukan putning untuk membatasi node-node tersebut.
#mincriterion 0.97
# minsplit 70
# minbusket 30
# melakukan purnjng pada model
model_dctree_purned <- ctree(formula = Sleep.Disorder ~ . ,
data = data_train,
control = ctree_control (
mincriterion = 0.97,
minsplit = 70,
minbucket = 30
))
# menampilkan plot
plot(model_dctree_purned, type = "simple")
Evaluasi data test yang sudah dilakukan purning model
# melakukan prediksi dengnan menggunakana model yang sudah dilakukan purning
pred_dctree_purned <- predict(object = model_dctree_purned,
newdata = data_test,
type = "response")
# melihat akurasi model yang sudah dipurning
confusionMatrix(data = pred_dctree_purned,
reference = data_test$Sleep.Disorder ,
mode = "everything",
positive = "None")
## Confusion Matrix and Statistics
##
## Reference
## Prediction Insomnia None Sleep Apnea
## Insomnia 17 3 3
## None 0 32 4
## Sleep Apnea 2 4 10
##
## Overall Statistics
##
## Accuracy : 0.7867
## 95% CI : (0.6768, 0.8729)
## No Information Rate : 0.52
## P-Value [Acc > NIR] : 1.656e-06
##
## Kappa : 0.6583
##
## Mcnemar's Test P-Value : 0.3618
##
## Statistics by Class:
##
## Class: Insomnia Class: None Class: Sleep Apnea
## Sensitivity 0.8947 0.8205 0.5882
## Specificity 0.8929 0.8889 0.8966
## Pos Pred Value 0.7391 0.8889 0.6250
## Neg Pred Value 0.9615 0.8205 0.8814
## Precision 0.7391 0.8889 0.6250
## Recall 0.8947 0.8205 0.5882
## F1 0.8095 0.8533 0.6061
## Prevalence 0.2533 0.5200 0.2267
## Detection Rate 0.2267 0.4267 0.1333
## Detection Prevalence 0.3067 0.4800 0.2133
## Balanced Accuracy 0.8938 0.8547 0.7424
# mencoba prediksi pada data_train
pred_dctree_train_purned <- predict(object = model_dctree_purned,
newdata = data_train,
type = "response")
# akurasi data train
confusionMatrix(data = pred_dctree_train_purned,
reference = data_train$Sleep.Disorder,
positive = "None",
mode ="everything")
## Confusion Matrix and Statistics
##
## Reference
## Prediction Insomnia None Sleep Apnea
## Insomnia 50 8 5
## None 7 165 1
## Sleep Apnea 1 7 55
##
## Overall Statistics
##
## Accuracy : 0.903
## 95% CI : (0.8637, 0.9341)
## No Information Rate : 0.602
## P-Value [Acc > NIR] : < 2e-16
##
## Kappa : 0.8292
##
## Mcnemar's Test P-Value : 0.06482
##
## Statistics by Class:
##
## Class: Insomnia Class: None Class: Sleep Apnea
## Sensitivity 0.8621 0.9167 0.9016
## Specificity 0.9461 0.9328 0.9664
## Pos Pred Value 0.7937 0.9538 0.8730
## Neg Pred Value 0.9661 0.8810 0.9746
## Precision 0.7937 0.9538 0.8730
## Recall 0.8621 0.9167 0.9016
## F1 0.8264 0.9348 0.8871
## Prevalence 0.1940 0.6020 0.2040
## Detection Rate 0.1672 0.5518 0.1839
## Detection Prevalence 0.2107 0.5786 0.2107
## Balanced Accuracy 0.9041 0.9247 0.9340
Keterangan:
Akurasi data train setelah purning: 0.9348
Akurasi data test setelah purning: 0.8533
Akurasi Data Train sebelum purning : 0.9444
Akurasi dara Test sebelum purning : 0.8462
setelah dilakuka purning data train mengalami penurunan sedangkan pada data test mengalami peningkatan, itu artinya performa model setelah dilakukan purning meningkat lebih baik daripada tanpa dilakukan purning.
set.seed(100)
control <- trainControl(method = "repeatedcv", number = 4, repeats = 2, verboseIter = TRUE)
# Pembuatan model random forest
model_rforest <- train(form = Sleep.Disorder ~ . ,
data = sleep,
method = "rf",
trainControl = control)
Agar ketika ada data baru tidak perlu run model dari awal karena membtutuhkan waktu komputasi yang lama sehingga best practice disimpan dalam bentuk RDS
# menyimpan hasil model dalam bentuk RDS
saveRDS(model_rforest, "Model Random FOrest Sleep.RDS")
# improt file model RDS
rds_rforest <- readRDS("Model Random FOrest Sleep.RDS")
# memanggil model
rds_rforest
## Random Forest
##
## 374 samples
## 12 predictor
## 3 classes: 'Insomnia', 'None', 'Sleep Apnea'
##
## No pre-processing
## Resampling: Bootstrapped (25 reps)
## Summary of sample sizes: 374, 374, 374, 374, 374, 374, ...
## Resampling results across tuning parameters:
##
## mtry Accuracy Kappa
## 2 0.9123949 0.8445599
## 12 0.8973835 0.8188381
## 23 0.8792519 0.7861788
##
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was mtry = 2.
Dalam random forest memilih variabel mtry yang dapat menghasilkan akurasi paling bagus
library(randomForest)
## Warning: package 'randomForest' was built under R version 4.2.3
## randomForest 4.7-1.1
## Type rfNews() to see new features/changes/bug fixes.
##
## Attaching package: 'randomForest'
## The following object is masked from 'package:ggplot2':
##
## margin
## The following object is masked from 'package:dplyr':
##
## combine
# final model
rds_rforest$finalModel
##
## Call:
## randomForest(x = x, y = y, mtry = param$mtry, trainControl = ..1)
## Type of random forest: classification
## Number of trees: 500
## No. of variables tried at each split: 2
##
## OOB estimate of error rate: 8.56%
## Confusion matrix:
## Insomnia None Sleep Apnea class.error
## Insomnia 64 7 6 0.16883117
## None 4 210 5 0.04109589
## Sleep Apnea 5 5 68 0.12820513
Interpretasi: - Number of tree sebanyak 500 - Number of variable tried at each split: 2 -> mtry - OOB estimate of error rate: 8.56% (error dari sample yang out of bag (sample yang tidak dipilih saat boostrap sampling)) - ConfusionMatrix Nilai OOB sebesar 8.56% artinya nilai akurasi sebesar 91.44%
100-8.56
## [1] 91.44
Salah satu kelebihan dari randomforest adalah dapat memilih variabel mana yang memiliki peluang besar untuk dapat menghasilkan akurasi model yang bagus
# menampilkan kontribusi variabel
varImp(rds_rforest)
## rf variable importance
##
## only 20 most important variables shown (out of 23)
##
## Overall
## Sistole 100.000
## Diastole 84.688
## BMI.CategoryOverweight 63.943
## Age 57.259
## Daily.Steps 42.089
## Sleep.Duration 39.689
## Physical.Activity.Level 38.066
## OccupationNurse 37.227
## Heart.Rate 33.529
## Quality.of.Sleep 27.793
## Stress.Level 24.003
## OccupationSalesperson 20.987
## OccupationTeacher 11.003
## GenderMale 10.635
## OccupationDoctor 9.845
## OccupationEngineer 7.491
## BMI.CategoryObese 4.254
## OccupationLawyer 4.044
## BMI.CategoryNormal Weight 1.741
## OccupationSales Representative 1.676
Variabel yang memiliki kontribusi tinggi dalam model ini adalah variabel sistole
pred_rforest <- predict(object = rds_rforest,
newdata = data_test,
type = "raw")
confusionMatrix(data = pred_rforest,
reference = data_test$Sleep.Disorder,
positive = "None",
mode = "everything")
## Confusion Matrix and Statistics
##
## Reference
## Prediction Insomnia None Sleep Apnea
## Insomnia 18 0 2
## None 0 36 4
## Sleep Apnea 1 3 11
##
## Overall Statistics
##
## Accuracy : 0.8667
## 95% CI : (0.7684, 0.9342)
## No Information Rate : 0.52
## P-Value [Acc > NIR] : 2.224e-10
##
## Kappa : 0.7813
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: Insomnia Class: None Class: Sleep Apnea
## Sensitivity 0.9474 0.9231 0.6471
## Specificity 0.9643 0.8889 0.9310
## Pos Pred Value 0.9000 0.9000 0.7333
## Neg Pred Value 0.9818 0.9143 0.9000
## Precision 0.9000 0.9000 0.7333
## Recall 0.9474 0.9231 0.6471
## F1 0.9231 0.9114 0.6875
## Prevalence 0.2533 0.5200 0.2267
## Detection Rate 0.2400 0.4800 0.1467
## Detection Prevalence 0.2667 0.5333 0.2000
## Balanced Accuracy 0.9558 0.9060 0.7890
Nilai akurasi random forest sebesar recall/sensitivity sebesar 0.9231 dan f1 score 0.9114.
Dari ke tiga model yang sudah dibuat di atas maka perbandingan akurasi nya adalah sebagai berikut:
# summary akurasi model
komparasi <- data.frame(Model = c("Naive Bayes", "Decision Tree", "Random Forest"),
Recall = c(0.8718, 0.8642, 0.9231),
F1 = c(0.8831, 0.8462, 0.9114))