Apa itu Logistic regression ?
Logistic regression adalah salah satu jenis analisis regresi yang digunakan untuk memprediksi hasil biner (ya/tidak, benar/salah, 1/0, selamat/tidak selamat) dari suatu variabel independen atau prediktor. Metode ini sering digunakan untuk memodelkan hubungan antara satu variabel dependen biner dengan satu atau lebih variabel independen.
Logistic regression memperkirakan probabilitas dari hasil biner dengan menghitung logit dari variabel independen. Logit adalah logaritma dari odds, yang merupakan rasio probabilitas keberhasilan dan kegagalan dari suatu peristiwa. Dalam logistic regression, variabel independen ditransformasi menjadi logit, dan kemudian model regresi digunakan untuk memperkirakan nilai logit dari variabel dependen.
Tujuan dari logistic regression adalah untuk mengidentifikasi variabel independen yang paling signifikan dalam memprediksi hasil biner, dan untuk menentukan faktor-faktor apa yang berkontribusi pada hasil tersebut. Metode ini sering digunakan dalam berbagai aplikasi seperti prediksi peluang kredit, prediksi kemungkinan keberhasilan dalam suatu perawatan medis, atau dalam pengambilan keputusan bisnis dan pemasaran. pada kesempatan kali ini saya akan mengolah data heart deases dataset framingham menggunakan logistic regression, bahasa utama yang digunakan adalah bahasa indonesia, dataset dapat diakses melalui kaggle.
Penyakit jantung merupakan penyakit kardiovaskular yang sangat umum terjadi di seluruh dunia. Menurut World Health Organization (WHO), penyakit jantung dan pembuluh darah adalah penyebab kematian nomor satu di dunia, dengan sekitar 17,9 juta kematian setiap tahunnya. Penyakit jantung meliputi berbagai kondisi yang memengaruhi jantung, seperti penyakit arteri koroner, gagal jantung, penyakit katup jantung, aritmia, dan penyakit jantung bawaan.
Beberapa faktor risiko yang dapat meningkatkan kemungkinan seseorang terkena penyakit jantung antara lain gaya hidup yang tidak sehat seperti kurangnya aktivitas fisik, merokok, konsumsi alkohol yang berlebihan, serta diet yang tidak sehat yang tinggi lemak jenuh, gula dan garam. Selain faktor gaya hidup, faktor risiko lainnya termasuk faktor genetik, usia, dan riwayat keluarga.
Penyakit jantung dapat berdampak serius pada kesehatan dan kualitas hidup seseorang. Dampak penyakit jantung pada kesehatan termasuk serangan jantung, stroke, gagal jantung, dan masalah kesehatan lainnya. Oleh karena itu, deteksi dini dan pencegahan penyakit jantung sangat penting. Pencegahan dapat dilakukan dengan mengadopsi gaya hidup sehat seperti melakukan olahraga secara teratur, menjaga berat badan yang sehat, serta mengonsumsi makanan yang seimbang dan bergizi. seperti yang dilansir dari berita WHO: Lima miliar orang tidak terlindungi dari lemak trans/ lemak jenuh yang menyebabkan penyakit jantung.
Cardiovascular diseases (CVDs) merujuk pada sekelompok kondisi medis yang mempengaruhi jantung dan pembuluh darah. CVD dapat mencakup berbagai penyakit dan gangguan, seperti penyakit arteri koroner, gagal jantung, penyakit katup jantung, aritmia, penyakit jantung bawaan, penyakit arteri perifer, dan stroke. CVD sering disebabkan oleh kombinasi faktor genetik, lingkungan, dan gaya hidup, termasuk diet yang tidak sehat, kurangnya aktivitas fisik, merokok, konsumsi alkohol berlebihan, dan tekanan darah, kolesterol, dan kadar glukosa yang tinggi. CVD merupakan penyebab utama kematian dan cacat di seluruh dunia, dan deteksi dini serta pencegahan sangat penting untuk mengurangi dampaknya pada kesehatan masyarakat.
Apabila anda tertarik untuk sharing terkait Data Science & AI (Artificial Intelligence) dapat menghubungi saya di Linkedin Anthony & silahkan kunjungi Github Anthony untuk melihat project lainnya.
Pada File AnthonyLab digunakan dataset
heartdeasesdatasetframingham.csv dan disajikan dalam bentuk
data table, sebagai berikut :
Menggunakan fungsi glimpse() untuk mengecek struktur dan
tipe data dari setiap kolom, sangat berguna untuk memastikan kembali
tipe data sudah sesuai dengan kebutuhan anda. berikut ini output dari
glimpse(jantung):
glimpse(jantung1)#> Rows: 3,656
#> Columns: 15
#> $ sex <chr> "Laki-laki", "Perempuan", "Laki-laki", "Perempuan", "P…
#> $ age <int> 39, 46, 48, 61, 46, 43, 63, 45, 52, 43, 50, 43, 46, 41…
#> $ CSmoker <chr> "Tidak", "Tidak", "Ya", "Ya", "Ya", "Tidak", "Tidak", …
#> $ cigsPerDay <int> 0, 0, 20, 30, 23, 0, 0, 20, 0, 30, 0, 0, 15, 0, 20, 10…
#> $ BPMeds <chr> "Tidak", "Tidak", "Tidak", "Tidak", "Tidak", "Tidak", …
#> $ prevalentStroke <chr> "Tidak", "Tidak", "Tidak", "Tidak", "Tidak", "Tidak", …
#> $ prevalentHyp <chr> "Tidak", "Tidak", "Tidak", "Hipertensi", "Tidak", "Hip…
#> $ diabetes <chr> "Tidak", "Tidak", "Tidak", "Tidak", "Tidak", "Tidak", …
#> $ totChol <int> 195, 250, 245, 225, 285, 228, 205, 313, 260, 225, 254,…
#> $ sysBP <dbl> 106.0, 121.0, 127.5, 150.0, 130.0, 180.0, 138.0, 100.0…
#> $ diaBP <dbl> 70.0, 81.0, 80.0, 95.0, 84.0, 110.0, 71.0, 71.0, 89.0,…
#> $ BMI <dbl> 26.97, 28.73, 25.34, 28.58, 23.10, 30.30, 33.11, 21.68…
#> $ heartRate <int> 80, 95, 75, 65, 85, 77, 60, 79, 76, 93, 75, 72, 98, 65…
#> $ glucose <int> 77, 76, 70, 103, 85, 99, 85, 78, 79, 88, 76, 61, 64, 8…
#> $ CHD10Y <chr> "Healthy", "Healthy", "Healthy", "CHD", "Healthy", "He…
Deskripsi Data :
Laki-laki atau 0 = Perempuan
(Nominal)Perilaku
Ya atau 0 = Tidak untuk
status pasien masih merokokMedis(Riwayat kesehatan)
Ada atau 0 = Tidak untuk
status pasien dalam pengobatan tekanan darah (Nominal)Stroke atau 0 =
Tidak untuk status pasien menderita stroke (Nominal)Hipertensi atau 0 =
Tidak untuk status pasien menderita hipertensi
(Nominal)Diabetes atau 0 = Tidak
untuk status pasien menderita diabetes (Nominal)Medis (saat ini)
CHD atau 0 = Healthy untuk
risiko penyakit jantung koroner (CHD) selama 10 Tahun. CHD adalah
kepanjangan dari Coronary Heart Disease (Penyakit Jantung Koroner)Apabila anda tertarik untuk sharing terkait Data Science & AI (Artificial Intelligence) dapat menghubungi saya di Linkedin Anthony & silahkan kunjungi Github Anthony untuk melihat project lainnya.
stats : library dasar yang menyediakan fungsi untuk
statistik dasar, seperti regresi linier.
glm : library untuk melakukan Generalized Linear
Models, termasuk logistic regression.
MASS : library yang menyediakan fungsi untuk regresi
dan analisis data multivariat.
caret : library yang menyediakan fungsi untuk
pre-processing data dan membangun model prediktif.
tidyverse : library yang menyediakan fungsi untuk
melakukan manipulasi, transformasi data, visualisasi dan pemodelan,
seperti menghapus kolom, mengubah nama kolom, atau mengurutkan baris,
visualisasi plot, dan fungsi lainnya.
ggplot2 : library yang menyediakan fungsi untuk
membuat visualisasi data, seperti histogram atau scatter plot.
ROCR : library yang menyediakan fungsi untuk
menghitung metrik evaluasi model, seperti AUC atau ROC curve.
Apabila anda tertarik untuk sharing terkait Data Science & AI (Artificial Intelligence) dapat menghubungi saya di Linkedin Anthony & silahkan kunjungi Github Anthony untuk melihat project lainnya.
jantung <- read.csv("ALabs/heartdeasesdatasetframingham.csv")
head(jantung)#> male age education currentSmoker cigsPerDay BPMeds prevalentStroke
#> 1 1 39 4 0 0 0 0
#> 2 0 46 2 0 0 0 0
#> 3 1 48 1 1 20 0 0
#> 4 0 61 3 1 30 0 0
#> 5 0 46 3 1 23 0 0
#> 6 0 43 2 0 0 0 0
#> prevalentHyp diabetes totChol sysBP diaBP BMI heartRate glucose TenYearCHD
#> 1 0 0 195 106.0 70 26.97 80 77 0
#> 2 0 0 250 121.0 81 28.73 95 76 0
#> 3 0 0 245 127.5 80 25.34 75 70 0
#> 4 1 0 225 150.0 95 28.58 65 103 1
#> 5 0 0 285 130.0 84 23.10 85 85 0
#> 6 1 0 228 180.0 110 30.30 77 99 0
sum(is.na(jantung))#> [1] 645
Proses seleksi data yang hilang dapat diselesaikan dengan sangat
mudah menggunakan fungsi na.omit(xxxx), setelah itu
disimpan dalam dataframe, pada proyek ini saya simpan dengan nama
jantung. setelah selesai prosesnya panggil
jantung dan cek data hilang dengan menggunakan fungsi
sum(is.na(jantung)) untuk memastikan data sudah bersih dan
siap digunakan.
jantung <- na.omit(jantung)
head(jantung)#> male age education currentSmoker cigsPerDay BPMeds prevalentStroke
#> 1 1 39 4 0 0 0 0
#> 2 0 46 2 0 0 0 0
#> 3 1 48 1 1 20 0 0
#> 4 0 61 3 1 30 0 0
#> 5 0 46 3 1 23 0 0
#> 6 0 43 2 0 0 0 0
#> prevalentHyp diabetes totChol sysBP diaBP BMI heartRate glucose TenYearCHD
#> 1 0 0 195 106.0 70 26.97 80 77 0
#> 2 0 0 250 121.0 81 28.73 95 76 0
#> 3 0 0 245 127.5 80 25.34 75 70 0
#> 4 1 0 225 150.0 95 28.58 65 103 1
#> 5 0 0 285 130.0 84 23.10 85 85 0
#> 6 1 0 228 180.0 110 30.30 77 99 0
sum(is.na(jantung))#> [1] 0
Setelah dipastikan data bersih dapat melanjutkan ke proses selanjutnya.
Seleksi data yang dibutuhkan saja :
jantung <-jantung %>%
select(-education)Menyesuaikan nama kolom sesuai dengan kebutuhan, male
menjadi sex :
jantung <- jantung %>%
rename(sex = male,
CHD10Y = TenYearCHD,
CSmoker = currentSmoker)Kita ingin mengetahui persebaran data, kita dapat menggunakan fungsi
summary(), fungsi ini akan memberikan kita gambaran ringkas
tentang variabel-variabel,jumlah, nilai rata-rata, nilai minimum, nilai
maksimum, dan nilai-nilai kuartil. dalam dataset, output dari
summary(jantung) sebagai berikut :
summary(jantung)#> sex age CSmoker cigsPerDay
#> Min. :0.0000 Min. :32.00 Min. :0.0000 Min. : 0.000
#> 1st Qu.:0.0000 1st Qu.:42.00 1st Qu.:0.0000 1st Qu.: 0.000
#> Median :0.0000 Median :49.00 Median :0.0000 Median : 0.000
#> Mean :0.4437 Mean :49.56 Mean :0.4891 Mean : 9.022
#> 3rd Qu.:1.0000 3rd Qu.:56.00 3rd Qu.:1.0000 3rd Qu.:20.000
#> Max. :1.0000 Max. :70.00 Max. :1.0000 Max. :70.000
#> BPMeds prevalentStroke prevalentHyp diabetes
#> Min. :0.00000 Min. :0.000000 Min. :0.0000 Min. :0.00000
#> 1st Qu.:0.00000 1st Qu.:0.000000 1st Qu.:0.0000 1st Qu.:0.00000
#> Median :0.00000 Median :0.000000 Median :0.0000 Median :0.00000
#> Mean :0.03036 Mean :0.005744 Mean :0.3115 Mean :0.02708
#> 3rd Qu.:0.00000 3rd Qu.:0.000000 3rd Qu.:1.0000 3rd Qu.:0.00000
#> Max. :1.00000 Max. :1.000000 Max. :1.0000 Max. :1.00000
#> totChol sysBP diaBP BMI
#> Min. :113.0 Min. : 83.5 Min. : 48.00 Min. :15.54
#> 1st Qu.:206.0 1st Qu.:117.0 1st Qu.: 75.00 1st Qu.:23.08
#> Median :234.0 Median :128.0 Median : 82.00 Median :25.38
#> Mean :236.9 Mean :132.4 Mean : 82.91 Mean :25.78
#> 3rd Qu.:263.2 3rd Qu.:144.0 3rd Qu.: 90.00 3rd Qu.:28.04
#> Max. :600.0 Max. :295.0 Max. :142.50 Max. :56.80
#> heartRate glucose CHD10Y
#> Min. : 44.00 Min. : 40.00 Min. :0.0000
#> 1st Qu.: 68.00 1st Qu.: 71.00 1st Qu.:0.0000
#> Median : 75.00 Median : 78.00 Median :0.0000
#> Mean : 75.73 Mean : 81.86 Mean :0.1524
#> 3rd Qu.: 82.00 3rd Qu.: 87.00 3rd Qu.:0.0000
#> Max. :143.00 Max. :394.00 Max. :1.0000
head(jantungclean)#> sex age CSmoker cigsPerDay BPMeds prevalentStroke prevalentHyp diabetes
#> 1 Laki-laki 39 Tidak 0 Tidak Tidak Tidak Tidak
#> 2 Perempuan 46 Tidak 0 Tidak Tidak Tidak Tidak
#> 3 Laki-laki 48 Ya 20 Tidak Tidak Tidak Tidak
#> 4 Perempuan 61 Ya 30 Tidak Tidak Hipertensi Tidak
#> 5 Perempuan 46 Ya 23 Tidak Tidak Tidak Tidak
#> 6 Perempuan 43 Tidak 0 Tidak Tidak Hipertensi Tidak
#> totChol sysBP diaBP BMI heartRate glucose CHD10Y
#> 1 195 106.0 70 26.97 80 77 Healthy
#> 2 250 121.0 81 28.73 95 76 Healthy
#> 3 245 127.5 80 25.34 75 70 Healthy
#> 4 225 150.0 95 28.58 65 103 CHD
#> 5 285 130.0 84 23.10 85 85 Healthy
#> 6 228 180.0 110 30.30 77 99 Healthy
Lakukan explorasi data kembali dengan menggunakan
summary() untuk mengetahui detail pada dataset kita,
setelah proses transformasi data pastinya akan menghasilkan data yang
lebih bersih dan baik untuk digunakan, seperti contoh dibawah ini :
summary(jantungclean)#> sex age CSmoker cigsPerDay BPMeds
#> Laki-laki:1622 Min. :32.00 Tidak:1868 Min. : 0.000 Ada : 111
#> Perempuan:2034 1st Qu.:42.00 Ya :1788 1st Qu.: 0.000 Tidak:3545
#> Median :49.00 Median : 0.000
#> Mean :49.56 Mean : 9.022
#> 3rd Qu.:56.00 3rd Qu.:20.000
#> Max. :70.00 Max. :70.000
#> prevalentStroke prevalentHyp diabetes totChol
#> Stroke: 21 Hipertensi:1139 Diabetes: 99 Min. :113.0
#> Tidak :3635 Tidak :2517 Tidak :3557 1st Qu.:206.0
#> Median :234.0
#> Mean :236.9
#> 3rd Qu.:263.2
#> Max. :600.0
#> sysBP diaBP BMI heartRate
#> Min. : 83.5 Min. : 48.00 Min. :15.54 Min. : 44.00
#> 1st Qu.:117.0 1st Qu.: 75.00 1st Qu.:23.08 1st Qu.: 68.00
#> Median :128.0 Median : 82.00 Median :25.38 Median : 75.00
#> Mean :132.4 Mean : 82.91 Mean :25.78 Mean : 75.73
#> 3rd Qu.:144.0 3rd Qu.: 90.00 3rd Qu.:28.04 3rd Qu.: 82.00
#> Max. :295.0 Max. :142.50 Max. :56.80 Max. :143.00
#> glucose CHD10Y
#> Min. : 40.00 CHD : 557
#> 1st Qu.: 71.00 Healthy:3099
#> Median : 78.00
#> Mean : 81.86
#> 3rd Qu.: 87.00
#> Max. :394.00
Sebelum pembuatan model kita lakukan proses pengecekan korelasi
menggunakan ggcorr fungsi library(GGally),
untuk mengetahui korelasi setiap variable/prediktor :
jantung.logit <- glm(formula = CHD10Y ~ 1, data = jantung,
family = binomial(link = "logit"))
summary(jantung.logit)#>
#> Call:
#> glm(formula = CHD10Y ~ 1, family = binomial(link = "logit"),
#> data = jantung)
#>
#> Deviance Residuals:
#> Min 1Q Median 3Q Max
#> -0.575 -0.575 -0.575 -0.575 1.940
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) -1.71627 0.04602 -37.3 <0.0000000000000002 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> (Dispersion parameter for binomial family taken to be 1)
#>
#> Null deviance: 3120.5 on 3655 degrees of freedom
#> Residual deviance: 3120.5 on 3655 degrees of freedom
#> AIC: 3122.5
#>
#> Number of Fisher Scoring iterations: 3
Berdasarkan output diatas hasil dari pemodelan logistic regression dengan formula CHD10Y ~ 1, variabel response-nya adalah CHD10Y, dan hanya menggunakan satu variabel prediktor, yaitu intercept/constant (dengan nilai -1.71627). Model tersebut menggunakan family “binomial” karena variabel response-nya adalah binomial (0/1).
Pada bagian Coefficients, terdapat informasi mengenai estimasi koefisien dan standard error dari intercept/constant, serta nilai z-value dan p-value (Pr(>|z|)) dari uji statistik untuk mengetahui signifikansi koefisien tersebut. Pada output tersebut, koefisien intercept/constant sangat signifikan secara statistik karena memiliki p-value yang sangat kecil (kurang dari 0.0001).
Deviance Residuals menunjukkan nilai deviasi dari residual (selisih antara nilai prediksi dan nilai sebenarnya dari variabel response) dari model. Null deviance menunjukkan deviasi residual pada model null (model tanpa variabel prediktor), sedangkan residual deviance menunjukkan deviasi residual pada model dengan variabel prediktor.
Output logit diatas menghasilkan nilai AIC (Akaike Information Criterion), yang merupakan suatu ukuran untuk membandingkan model yang berbeda, dengan nilai yang lebih rendah menunjukkan model yang lebih baik. Jumlah iterasi Fisher Scoring yang digunakan untuk mengestimasi parameter model juga ditampilkan pada output tersebut.
jantung.logit1 <- glm(CHD10Y ~ sex + age + cigsPerDay + totChol + sysBP + glucose + sysBP, data = jantung ,
family= binomial(link ="logit" ))
summary(jantung.logit1)#>
#> Call:
#> glm(formula = CHD10Y ~ sex + age + cigsPerDay + totChol + sysBP +
#> glucose + sysBP, family = binomial(link = "logit"), data = jantung)
#>
#> Deviance Residuals:
#> Min 1Q Median 3Q Max
#> -2.0074 -0.5966 -0.4315 -0.2864 2.8811
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) -9.129843 0.475530 -19.199 < 0.0000000000000002 ***
#> sex 0.561446 0.106845 5.255 0.000000148213436697 ***
#> age 0.065896 0.006426 10.254 < 0.0000000000000002 ***
#> cigsPerDay 0.019226 0.004176 4.604 0.000004142080084965 ***
#> totChol 0.002272 0.001123 2.024 0.043 *
#> sysBP 0.017534 0.002149 8.159 0.000000000000000338 ***
#> glucose 0.007280 0.001677 4.342 0.000014129887726954 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> (Dispersion parameter for binomial family taken to be 1)
#>
#> Null deviance: 3120.5 on 3655 degrees of freedom
#> Residual deviance: 2762.5 on 3649 degrees of freedom
#> AIC: 2776.5
#>
#> Number of Fisher Scoring iterations: 5
Model regresi logistik kedua (jantung.logit1) ini
menunjukkan variabel yang signifikan dalam memprediksi risiko penyakit
jantung adalah jenis kelamin (sex), usia (age), status merokok
(CSmoker), total kolesterol (totChol), tekanan darah sistolik (sysBP),
dan kadar glukosa darah (glucose). Koefisien estimasi positif pada
variabel sex, age, CSmoker, totChol, sysBP, dan glucose menunjukkan
bahwa semakin tinggi nilai variabel tersebut, semakin tinggi risiko
terkena penyakit jantung.
Disamping itu, model ini memiliki nilai AIC yang lebih kecil dibandingkan dengan model pertama, yang menunjukkan bahwa model kedua lebih baik dalam menjelaskan hubungan antara variabel prediktor dengan variabel target. Namun, kita perlu mengingat bahwa model yang paling cocok adalah model yang dihasilkan dari validasi silang dan perlu dilakukan evaluasi lebih lanjut untuk menentukan kualitas model yang lebih baik.
jantung.logit2 <- glm(CHD10Y ~ ., data = jantung ,
family= binomial(link ="logit" ))
summary(jantung.logit2)#>
#> Call:
#> glm(formula = CHD10Y ~ ., family = binomial(link = "logit"),
#> data = jantung)
#>
#> Deviance Residuals:
#> Min 1Q Median 3Q Max
#> -1.9935 -0.5954 -0.4269 -0.2842 2.8462
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) -8.489544 0.694682 -12.221 < 0.0000000000000002 ***
#> sex 0.554042 0.109015 5.082 0.000000373 ***
#> age 0.064193 0.006634 9.676 < 0.0000000000000002 ***
#> CSmoker 0.071318 0.156671 0.455 0.64896
#> cigsPerDay 0.018000 0.006235 2.887 0.00389 **
#> BPMeds 0.157576 0.233969 0.673 0.50063
#> prevalentStroke 0.706043 0.489107 1.444 0.14887
#> prevalentHyp 0.233160 0.138076 1.689 0.09129 .
#> diabetes 0.042959 0.315212 0.136 0.89160
#> totChol 0.002262 0.001126 2.009 0.04453 *
#> sysBP 0.015706 0.003795 4.139 0.000034888 ***
#> diaBP -0.004608 0.006418 -0.718 0.47275
#> BMI 0.008057 0.012681 0.635 0.52517
#> heartRate -0.003074 0.004206 -0.731 0.46494
#> glucose 0.007124 0.002237 3.185 0.00145 **
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> (Dispersion parameter for binomial family taken to be 1)
#>
#> Null deviance: 3120.5 on 3655 degrees of freedom
#> Residual deviance: 2755.1 on 3641 degrees of freedom
#> AIC: 2785.1
#>
#> Number of Fisher Scoring iterations: 5
Berdasrkan hasi ini dapat disimpulkan bahwa variabel yang signifikan
dalam memprediksi risiko penyakit jantung adalah sex, age, CSmoker,
totChol, sysBP, dan glucose. Pada model pertama, variabel cigsPerDay dan
prevalentHyp tidak signifikan, sedangkan pada model
jantung.logit2, variabel cigsPerDay, prevalentStroke,
prevalentHyp, diabetes, diaBP, BMI, dan heartRate tidak signifikan.
Selain itu, model ketiga memiliki nilai AIC yang lebih tinggi
dibandingkan model jantung.logit1, sehingga model
jantung.logit1 lebih baik dalam menjelaskan data.
boxplot(jantungclean$CSmoker, jantungclean$CHD10Y, ylim = c(0,4),
medcol = "green",
main = "Boxplot Kolom CSmoker dan CHD10Y",
xlab = NULL, ylab = "Angka Distribusi" ,
col = "blue",
boxwex = 0.5,
whisklty = 2,
staplelty = 0,
outpch = 19,
outcol = "red")Boxplot yang dihasilkan menunjukkan distribusi CHD10Y (hasil diagnosis penyakit jantung dalam 10 tahun terakhir) berdasarkan status merokok (CSmoker). Pada sumbu x, terdapat dua kotak yang merepresentasikan kedua kategori status merokok, yaitu 0 (tidak merokok) dan 1 (merokok). Pada sumbu y, terdapat skala nilai 0 hingga 4, yang mengindikasikan tingkat risiko CHD10Y.
Dari boxplot ini, kita dapat melihat perbedaan distribusi CHD10Y antara kelompok yang tidak merokok (0) dan merokok (1). Median CHD10Y pada kelompok yang merokok lebih tinggi dibandingkan dengan kelompok yang tidak merokok. Selain itu, kita juga dapat melihat bahwa kelompok yang merokok memiliki variasi yang lebih besar dalam CHD10Y, ditunjukkan dengan kotak yang lebih tinggi dan whisker yang lebih panjang pada kelompok merokok. Oleh karena itu, dari boxplot ini dapat disimpulkan bahwa status merokok berpotensi menjadi faktor risiko yang berpengaruh pada tingkat risiko CHD10Y (Penyakit Jantung Koroner).
table(jantungclean$CSmoker , jantungclean$CHD10Y)#>
#> CHD Healthy
#> Tidak 272 1596
#> Ya 285 1503
Hasil output ini menunjukkan terdapat 272 pasien yang tidak memiliki CHD dan juga dalam keadaan sehat, 1596 pasien tidak memiliki CHD namun dalam keadaan tidak sehat, 285 pasien memiliki CHD dan dalam keadaan sehat, serta 1503 pasien memiliki CHD dan dalam keadaan tidak sehat. jumlah pasien lebih besar yang tidak memiliki CHD namun dalam keadaan tidak sehat, dan jumlah pasien relatif sama antara yang memiliki CHD namun dalam keadaan sehat dan tidak sehat.
Proporsi data yang seimbang penting untuk mendukung proses selanjutnya model dapat mempelajari kelas postif dan negatif secara seimbang, dalam kasus ini melihat 10 tahun siapa yang potensi terjangkit jantung koroner Para perokok, bukan perokok, Laki-laki atau perempuan, proporsi data yang seimbang umumnya antara 90-100% dari data itu sendiri, semakin seimbang proposinya akan semakin bagus hasil latihan modelnya.
prop.table(table(jantung$CSmoker))#>
#> 0 1
#> 0.5109409 0.4890591
prop.table(table(jantung$CHD10Y))#>
#> 0 1
#> 0.8476477 0.1523523
prop.table(table(jantung$sex))#>
#> 0 1
#> 0.5563457 0.4436543
Hasil dari proses kode
prop.table(table(jantung$CSmoker)) menghasilkan data yang
menunjukkan proporsi dari masing-masing kategori dalam variabel CSmoker.
- Kategori 0 (Ya) memiliki proporsi sebesar 0.5109409 atau sekitar 51%
dari total data. - Kategori 1 (Tidak) memiliki proporsi sebesar
0.4890591 atau sekitar 49% dari total data. Hal ini menunjukkan bahwa
data dalam variabel CSmoker hampir seimbang antara kategori 0 (Tidak)
dan 1 (Ya).
Hasil dari proses kode
prop.table(table(jantung$CHD10Y))menghasilkan data sebanyak
84.76% memiliki nilai 0 (tidak terkena penyakit jantung dalam 10 tahun
ke depan) dan 15.23% memiliki nilai 1 (terkena penyakit jantung dalam 10
tahun ke depan), hasil dari proses kode
prop.table(table(jantung$sex)) menghasilkan proporsi data
bahwa laki-laki sekitar 44.37% dan proporsi perempuan sekitar 55.63%
dengan kata lain dapat ditarik kesimpulan dari analisa sementara
berdasarkan data proporsi bahwa wanita lebih rentan terkena penyakit
jantung koroner.
sex 0.635375 0.102990 6.169 0.000000000686 age 0.064216
0.006376 10.072 < 0.0000000000000002 CSmoker 0.372150
0.103664 3.590 0.000331 totChol 0.002381 0.001120 2.125
0.033551
sysBP 0.017725 0.002149 8.250 < 0.0000000000000002
glucose 0.007178 0.001671 4.297 0.000017296915 **
Bedasarkan data yang memiliki korelasi terkuat kita lakukan proses Eksponensial, sebagai berikut
exp(0.635375)#> [1] 1.88773
exp(0.064216)#> [1] 1.066323
exp(0.372150)#> [1] 1.450851
exp(0.002381)#> [1] 1.002384
exp(0.017725)#> [1] 1.017883
exp(0.007178)#> [1] 1.007204
Kesimpulan dari hasil eksponensial diatas adalah dalam 10 tahun kedepan Laki-laki dan Perempuan berpotensi Jantung koroner (CHD) 1.9 kali berpotensi jantung koroner, setiap bertambahnya umur 1.1 kali berpotensi jantung koroner, perokok akan 1.5 kali berpotensi jantung koroner, semakin bertambah tingkat kolestrol 1 kali berpotensi jantung koroner, semakin bertambah tekanan darah sistolik 1 kali berpotensi jantung koroner, semakinn bertambah glukosa seseorang 1 kali berpotensi jantung koroner.
Pada jantungmodel menggunakan tambahan fungsi
family = binomial(link = "logit") untuk hasil logstic
regression yang lebih baik dan memaparkan kesimpulan dengan lebih
lengkap berdasarkan konteks bisnis case dan permasalahan yang ingin
dipecahkan. penjelasan prosesnya sebagai berikut :
# Logistic regression analysis
jantungmodel <- glm(CHD10Y ~ age + sex + totChol + CSmoker + cigsPerDay + sysBP + diaBP + BMI + heartRate + glucose,
data = jantungclean,
family = binomial(link = "logit"))
# Exponential of coefficients
exp_coef <- exp(coef(jantungmodel))
# Print results
cat("Intercept: ", exp_coef[1], "\n")#> Intercept: 4966.022
cat("age: ", exp_coef[2], "\n")#> age: 0.9367937
cat("sex: ", exp_coef[3], "\n")#> sex: 1.742271
cat("totChol: ", exp_coef[4], "\n")#> totChol: 0.9976919
cat("CSmoker: ", exp_coef[5], "\n")#> CSmoker: 0.9342694
cat("cigsPerDay: ", exp_coef[6], "\n")#> cigsPerDay: 0.9823528
cat("sysBP: ", exp_coef[7], "\n")#> sysBP: 0.9815345
cat("diaBP: ", exp_coef[8], "\n")#> diaBP: 1.002987
cat("BMI: ", exp_coef[9], "\n")#> BMI: 0.9897061
cat("heartRate: ", exp_coef[10], "\n")#> heartRate: 1.00302
cat("glucose: ", exp_coef[11], "\n")#> glucose: 0.9927435
Kesimpulan dari hasil output jantungmodel sebagai
berikut:
Intercept (konstanta) memiliki nilai 4966.022, yang berarti jika seluruh variabel independen pada model tersebut adalah nol, maka probabilitas kasus positif pada variabel dependen adalah sekitar 4966 kali lebih besar dari pada kasus negatif.
Variabel age memiliki nilai koefisien sebesar 0.9367937, yang berarti jika nilai umur seseorang bertambah satu satuan, maka probabilitas kasus positif pada variabel dependen akan meningkat sebesar sekitar 0.9367937 kali.
Variabel sex memiliki nilai koefisien sebesar 1.742271, yang berarti jika seseorang adalah perempuan (dalam data ini, perempuan direpresentasikan dengan nilai 0 dan laki-laki dengan nilai 1), maka probabilitas kasus positif pada variabel dependen akan meningkat sebesar sekitar 1.742271 kali.
Variabel totChol memiliki nilai koefisien sebesar 0.9976919, yang berarti jika nilai total kolesterol seseorang bertambah satu satuan, maka probabilitas kasus positif pada variabel dependen akan meningkat sebesar sekitar 0.9976919 kali.
Variabel CSmoker memiliki nilai koefisien sebesar 0.9342694, yang berarti jika seseorang adalah perokok (dalam data ini, perokok direpresentasikan dengan nilai 1 dan bukan perokok dengan nilai 0), maka probabilitas kasus positif pada variabel dependen akan meningkat sebesar sekitar 0.9342694 kali.
Variabel cigsPerDay memiliki nilai koefisien sebesar 0.9823528, yang berarti jika seseorang merokok lebih banyak dalam sehari, maka probabilitas kasus positif pada variabel dependen akan meningkat sebesar sekitar 0.9823528 kali.
Variabel sysBP memiliki nilai koefisien sebesar 0.9815345, yang berarti jika nilai tekanan darah sistolik seseorang bertambah satu satuan, maka probabilitas kasus positif pada variabel dependen akan meningkat sebesar sekitar 0.9815345 kali.
Variabel diaBP memiliki nilai koefisien sebesar 1.002987, yang berarti jika nilai tekanan darah diastolik seseorang bertambah satu satuan, maka probabilitas kasus positif pada variabel dependen akan meningkat sebesar sekitar 1.002987 kali.
Variabel BMI memiliki nilai koefisien sebesar 0.9897061, yang berarti jika nilai indeks massa tubuh (BMI) seseorang bertambah satu satuan, maka probabilitas kasus positif pada variabel dependen akan meningkat sebesar sekitar 0.9897061 kali.
Variabel heartRate memiliki nilai koefisien sebesar 1.00302, yang berarti jika nilai detak jantung seseorang bertambah satu satuan, maka probabilitas kasus positif pada variabel dependen akan meningkat sebesar sekitar 1.00302 kali.
Variabel glucose memiliki nilai koefisien sebesar 0.9927435, yang berarti jika nilai
Pada proses pembuatan model logistic regression, kita
perlu melakukan pemisahan data menjadi 2, yaitu : - data training =
jantungtrain - data testing = jantungtest
Proses balancing data menggunakan Smote
#>
#> Healthy CHD
#> 0.4907002 0.5092998
#>
#> Healthy CHD
#> 1614 1675
#>
#> Healthy CHD
#> 180 187
#>
#> Healthy CHD
#> 0.4907267 0.5092733
#>
#> Healthy CHD
#> 0.4904632 0.5095368
jantungtrain <- jantungtrain %>%
mutate(CHD10Y = factor(if_else(CHD10Y == "CHD", "1", "0")))
head(jantungtrain)#> sex age CSmoker cigsPerDay BPMeds prevalentStroke prevalentHyp
#> 1795 Perempuan 65.90935 Ya 8.746677 Tidak Tidak Hipertensi
#> 1796 Perempuan 51.90291 Ya 25.523917 Tidak Tidak Tidak
#> 1797 Perempuan 66.34744 Tidak -4.768426 Tidak Tidak Hipertensi
#> 1798 Perempuan 38.46475 Ya 14.750600 Tidak Tidak Tidak
#> 1799 Laki-laki 41.20041 Tidak -1.657172 Tidak Tidak Hipertensi
#> 1800 Laki-laki 63.13709 Ya 16.009522 Tidak Tidak Hipertensi
#> diabetes totChol sysBP diaBP BMI heartRate glucose CHD10Y
#> 1795 Tidak 289.7975 135.7860 72.67143 17.08316 74.60308 97.45688 1
#> 1796 Tidak 248.6947 137.1785 75.64958 26.90544 113.68614 30.99285 1
#> 1797 Tidak 172.9682 153.5431 85.05143 21.89799 77.75150 78.59796 1
#> 1798 Tidak 156.5080 170.3949 108.50791 26.37810 82.22015 73.53092 1
#> 1799 Tidak 354.0025 136.0731 101.04672 24.95177 67.82686 67.02950 1
#> 1800 Tidak 297.6713 167.2256 88.35411 22.38392 68.15366 71.07473 1
jantungtest <- jantungtest %>%
mutate(CHD10Y = factor(if_else(CHD10Y == "CHD", "1", "0")))
head(jantungtest)#> sex age CSmoker cigsPerDay BPMeds prevalentStroke prevalentHyp
#> 20 Perempuan 63.71421 Tidak -5.071874857 Tidak Tidak Hipertensi
#> 22 Perempuan 52.62017 Ya 6.401415477 Tidak Tidak Tidak
#> 35 Perempuan 56.54596 Tidak -0.006117538 Tidak Tidak Tidak
#> 37 Laki-laki 41.16977 Ya 21.032114941 Tidak Tidak Tidak
#> 41 Laki-laki 38.97026 Tidak -2.716866199 Tidak Tidak Tidak
#> 54 Perempuan 50.01943 Ya 18.237529588 Tidak Tidak Tidak
#> diabetes totChol sysBP diaBP BMI heartRate glucose CHD10Y
#> 20 Tidak 208.6902 125.3978 89.23277 31.76407 69.50732 91.83217 0
#> 22 Tidak 251.9565 124.0292 87.74859 27.54413 60.24610 81.21698 0
#> 35 Tidak 270.7039 123.3179 73.44412 16.91763 59.48453 80.38058 0
#> 37 Tidak 401.0210 116.2130 82.55464 20.17187 86.33851 85.93374 0
#> 41 Tidak 278.3153 106.3526 85.63073 26.62281 57.85309 51.29710 0
#> 54 Tidak 319.0862 118.4014 81.83750 20.38970 72.45755 85.75295 0
JM1 <- glm(CHD10Y ~ ., data = jantungtrain ,
family= binomial(link ="logit" ))
summary(JM1)#>
#> Call:
#> glm(formula = CHD10Y ~ ., family = binomial(link = "logit"),
#> data = jantungtrain)
#>
#> Deviance Residuals:
#> Min 1Q Median 3Q Max
#> -2.3381 -1.0135 0.4047 1.0086 2.3221
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) -3.8245151 0.7641874 -5.005 0.00000055954 ***
#> sexPerempuan -0.4910588 0.0820550 -5.985 0.00000000217 ***
#> age 0.0584169 0.0046232 12.636 < 0.0000000000000002 ***
#> CSmokerYa 0.1083913 0.1101950 0.984 0.32530
#> cigsPerDay 0.0110626 0.0039436 2.805 0.00503 **
#> BPMedsTidak -0.3498065 0.2133545 -1.640 0.10110
#> prevalentStrokeTidak -0.3189986 0.3865547 -0.825 0.40924
#> prevalentHypTidak -0.3017210 0.1042664 -2.894 0.00381 **
#> diabetesTidak -1.1787139 0.2792159 -4.222 0.00002426672 ***
#> totChol 0.0020390 0.0007673 2.657 0.00788 **
#> sysBP 0.0096189 0.0020504 4.691 0.00000271693 ***
#> diaBP 0.0004844 0.0036282 0.134 0.89378
#> BMI 0.0343654 0.0086886 3.955 0.00007646806 ***
#> heartRate 0.0012834 0.0029173 0.440 0.65998
#> glucose 0.0008287 0.0014585 0.568 0.56992
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> (Dispersion parameter for binomial family taken to be 1)
#>
#> Null deviance: 4558.4 on 3288 degrees of freedom
#> Residual deviance: 3965.8 on 3274 degrees of freedom
#> AIC: 3995.8
#>
#> Number of Fisher Scoring iterations: 4
JM2 <- glm(CHD10Y ~ sex + age + cigsPerDay + totChol + sysBP + glucose + sysBP, data = jantungtrain ,
family= binomial(link ="logit" ))
summary(JM2)#>
#> Call:
#> glm(formula = CHD10Y ~ sex + age + cigsPerDay + totChol + sysBP +
#> glucose + sysBP, family = binomial(link = "logit"), data = jantungtrain)
#>
#> Deviance Residuals:
#> Min 1Q Median 3Q Max
#> -2.1447 -1.0333 0.4467 1.0226 2.3528
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) -5.896668 0.330545 -17.839 < 0.0000000000000002 ***
#> sexPerempuan -0.523248 0.080221 -6.523 0.0000000000691 ***
#> age 0.059460 0.004468 13.307 < 0.0000000000000002 ***
#> cigsPerDay 0.011891 0.002950 4.030 0.0000556598540 ***
#> totChol 0.002597 0.000748 3.472 0.000516 ***
#> sysBP 0.014566 0.001492 9.760 < 0.0000000000000002 ***
#> glucose 0.004804 0.001156 4.158 0.0000321742237 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> (Dispersion parameter for binomial family taken to be 1)
#>
#> Null deviance: 4558.4 on 3288 degrees of freedom
#> Residual deviance: 4023.7 on 3282 degrees of freedom
#> AIC: 4037.7
#>
#> Number of Fisher Scoring iterations: 4
unique(jantungtest$CHD10Y)#> [1] 0 1
#> Levels: 0 1
Menambahkan kolom baru berisikan prediksi berdasarkan peluang
prediksi dengan nama predRCHD (Risk Coronary Heart
Disease).
jantungtest$predRCHD <- predict(object = JM2 ,
newdata = jantungtest,
type = "response")Selanjutnya buat klasifikasi jantungtest berdasarkan
predRCHD disimpan dikolom baru predLCHD
diberikan label dengan ifelse apabila nila
predRCHD > 4 maka berpotensi jantung koroner (CHD).
jantungtest$predLCHD <- ifelse(jantungtest$predRCHD > 0.1 , yes = 1 , no = 0)cek kembali tipe data, untuk proses confussionMatrix
kita membutuhkan data factor, dikarenakan tipe data numeric
maka harus diubah menjadi tipe data factor.
class(jantungtest$predLCHD)#> [1] "numeric"
Pastikan tipe data factor untuk confusionMatrix berjalan
dengan baik.
jantungtest$predLCHD <- as.factor(jantungtest$predLCHD)
head(jantungtest)#> sex age CSmoker cigsPerDay BPMeds prevalentStroke prevalentHyp
#> 20 Perempuan 63.71421 Tidak -5.071874857 Tidak Tidak Hipertensi
#> 22 Perempuan 52.62017 Ya 6.401415477 Tidak Tidak Tidak
#> 35 Perempuan 56.54596 Tidak -0.006117538 Tidak Tidak Tidak
#> 37 Laki-laki 41.16977 Ya 21.032114941 Tidak Tidak Tidak
#> 41 Laki-laki 38.97026 Tidak -2.716866199 Tidak Tidak Tidak
#> 54 Perempuan 50.01943 Ya 18.237529588 Tidak Tidak Tidak
#> diabetes totChol sysBP diaBP BMI heartRate glucose CHD10Y
#> 20 Tidak 208.6902 125.3978 89.23277 31.76407 69.50732 91.83217 0
#> 22 Tidak 251.9565 124.0292 87.74859 27.54413 60.24610 81.21698 0
#> 35 Tidak 270.7039 123.3179 73.44412 16.91763 59.48453 80.38058 0
#> 37 Tidak 401.0210 116.2130 82.55464 20.17187 86.33851 85.93374 0
#> 41 Tidak 278.3153 106.3526 85.63073 26.62281 57.85309 51.29710 0
#> 54 Tidak 319.0862 118.4014 81.83750 20.38970 72.45755 85.75295 0
#> predRCHD predLCHD
#> 20 0.5294627 1
#> 22 0.4100396 1
#> 35 0.4570420 1
#> 37 0.4871318 1
#> 41 0.2509840 1
#> 54 0.4344925 1
jantungtest %>%
select(CHD10Y, predRCHD, predLCHD) %>%
head(10)#> CHD10Y predRCHD predLCHD
#> 20 0 0.5294627 1
#> 22 0 0.4100396 1
#> 35 0 0.4570420 1
#> 37 0 0.4871318 1
#> 41 0 0.2509840 1
#> 54 0 0.4344925 1
#> 58 0 0.2377900 1
#> 86 0 0.2343998 1
#> 95 0 0.3693670 1
#> 106 0 0.6121429 1
confusionMatrix merupakan sebuah tabel yang digunakan
untuk mengevaluasi performa model klasifikasi dengan membandingkan nilai
prediksi dari model dengan nilai aktual pada data yang telah diketahui.
Confusion matrix memuat empat jenis nilai, yaitu true positive (TP),
false positive (FP), false negative (FN), dan true negative (TN).
confusionMatrix(data = jantungtest$predLCHD, reference = jantungtest$CHD10Y, positive = "1")#> Confusion Matrix and Statistics
#>
#> Reference
#> Prediction 0 1
#> 0 0 0
#> 1 180 187
#>
#> Accuracy : 0.5095
#> 95% CI : (0.4571, 0.5618)
#> No Information Rate : 0.5095
#> P-Value [Acc > NIR] : 0.5209
#>
#> Kappa : 0
#>
#> Mcnemar's Test P-Value : <0.0000000000000002
#>
#> Sensitivity : 1.0000
#> Specificity : 0.0000
#> Pos Pred Value : 0.5095
#> Neg Pred Value : NaN
#> Prevalence : 0.5095
#> Detection Rate : 0.5095
#> Detection Prevalence : 1.0000
#> Balanced Accuracy : 0.5000
#>
#> 'Positive' Class : 1
#>
unique(jantungtest$predLCHD)#> [1] 1
#> Levels: 1
unique(jantungtest$CHD10Y)#> [1] 0 1
#> Levels: 0 1
Apabila anda tertarik untuk sharing terkait *Data Science & AI (Artificial Intelligence)** dapat menghubungi saya di Linkedin Anthony & silahkan kunjungi Github Anthony untuk melihat project lainnya.