1. Intro

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.


2. Pre-Processing Data

2.1 Import Data

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

2.2 Data Wrangling

2.2.1 Cek Struktur Data

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:

      1. Person.ID : ID setiap individu
      1. Gender : Jenis kelamin seseorang
      1. Age : Usia seseorang
      1. Occupation : Profesi pekerjaan seseorang
      1. Sleep.Duration : Lama waktu tidur seseorang (jam per hari)
      1. Quality.of.Sleep : Penilaian subjektif kualitas tidur seseorang dari angka 1-10
      1. Physical.Activity.Level : Jumlah menit seseorang melakukan aktivitas fisik setiap hari (menit/hari)
      1. Stress.Level : Tingkat stress subjektif dari tingkat stress seseorang berkisar dari 1-10
      1. BMI.Category : Kategori BMI seseorang (Underweight : Kurus, Normal, Overweight)
      1. Blood.Pressure : Pengukuran tekanan darah seseorang, ditunjukkan sebagai tekanan sistolik di atas tekanan diastolik.
      1. Heart.Rate: Detak jantung istirahat seseorang dalam detak per menit.
      1. Daily.Step : Jumlah langkah yang dilakukan seseorang per hari.
      1. Sleep.Disorder : Ada tidaknya gangguan tidur pada orang tersebut (None, Insomnia, Sleep Apnea).
      • Tidak ada: Individu tidak menunjukkan gangguan tidur tertentu.
      • Insomnia: Individu mengalami kesulitan tidur atau tetap tertidur, menyebabkan tidur yang tidak memadai atau berkualitas buruk.
      • Sleep Apnea: Individu menderita jeda pernapasan selama tidur, mengakibatkan gangguan pola tidur dan potensi risiko kesehatan.

2.2.2 Menyesuaikan Struktur Data

# ubah tipe data
sleep <- sleep %>% 
  mutate_at(vars(Gender, Occupation, BMI.Category, Sleep.Disorder), as.factor)

2.2.3 Pemeriksaan Missing Value

# 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.


3. Eksploratory Data Analysis (EDA)

3.1 Split Kolom

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

3.2 Delete Kolom

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)

3.3 Cek Proporsi Persebaran Data

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:

  • seorang perempuan lebih banyak mengalami gangguan tidur (insomnia dan sleep apnea) daripada seorang laki-laki
  • Seorang laki-laki lebih banyak tidak mengalami gangguan tidur
  • Namun, laki-laki lebih banyak mengalami insomnia daripada perempuan sedangkan
  • Sedangkan yang mengalami apnea lebih banyak dari perempuan daripada laki-laki
  • Orang yang mengalami Insomnia adalah kebanyakan berjenis kelamin

3. Naive Bayes

Naive Bayes adalah metode klasifikasi yang berbasis peluang kejadian akan terjadi jika diketahui keadaan/kejadian yang lain. Workflow dalam membangun model Naive Bayes adalah :

3.1 Cross Validation

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, ]

3.2 Model Fitting

# 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.

3.3 Prediksi

# 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

3.4 Model Evaluasi

3.4.1 ConfusionMatrix

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 =

4. Decision Tree

4.1 Build Model Fitting

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")

4.2 Prediksi

#Melakukan Prediksi pada data test
pred_dctree <- predict(object = model_dctree , 
                       newdata = data_test, 
                       type =  "response")

4.3 Model Evaluation

# 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.

4.4 Performance Model

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.

4.4 Model Tunning

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.

5. Random Forest

5.1 Cross Validation

5.2 K-Fold

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

5.2 Prediction

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.

6. Model Comparassion

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))