Penyakit jantung merupakan salah satu penyebab utama kematian di dunia. Menurut World Health Organization, penyakit kardiovaskular menyumbang jutaan kematian setiap tahun. Oleh karena itu, diperlukan metode analisis yang dapat membantu memprediksi kemungkinan seseorang mengalami penyakit jantung berdasarkan data klinis. Salah satu metode yang umum digunakan untuk klasifikasi biner adalah Logistic Regression.
Analisis ini bertujuan untuk:
Membangun model prediksi penyakit jantung menggunakan Logistic Regression.
Mengevaluasi performa model menggunakan ROC Curve dan nilai AUC.
Mengidentifikasi variabel yang paling berpengaruh terhadap risiko penyakit jantung.
Dataset yang digunakan adalah Heart Failure Prediction Dataset dari Kaggle yang dipublikasikan oleh Federico Soriano. Dataset ini berisi sekitar 918 observasi dengan 11 variabel prediktor dan 1 variabel target (HeartDisease). Variabel dalam dataset mencakup sebagai berikut :
| Variabel | Deskripsi |
|---|---|
| Age | Usia pasien (tahun) |
| Sex | Jenis kelamin pasien (M = Male, F = Female) |
| ChestPainType | Jenis nyeri dada (TA, ATA, NAP, ASY) |
| RestingBP | Tekanan darah saat istirahat (mm Hg) |
| Cholesterol | Kadar kolesterol serum (mg/dl) |
| FastingBS | Gula darah puasa (>120 mg/dl = 1, lainnya = 0) |
| RestingECG | Hasil elektrokardiogram saat istirahat |
| MaxHR | Detak jantung maksimum yang dicapai |
| ExerciseAngina | Angina akibat olahraga (Y/N) |
| Oldpeak | Depresi ST yang diinduksi oleh olahraga |
| ST_Slope | Kemiringan segmen ST pada puncak latihan |
| HeartDisease | Variabel target (0 = tidak ada penyakit jantung, 1 = ada penyakit jantung) |
# Logistic regression menggunakan fungsi bawaan R
# sehingga tidak memerlukan library tambahan
Logistic Regression merupakan metode klasifikasi yang digunakan untuk memprediksi probabilitas suatu kejadian biner. Pada analisis ini, metode logistic regression digunakan untuk memprediksi apakah seorang pasien memiliki penyakit jantung atau tidak.
data <- read.csv("heart.csv")
head(data)
## Age Sex ChestPainType RestingBP Cholesterol FastingBS RestingECG MaxHR
## 1 40 M ATA 140 289 0 Normal 172
## 2 49 F NAP 160 180 0 Normal 156
## 3 37 M ATA 130 283 0 ST 98
## 4 48 F ASY 138 214 0 Normal 108
## 5 54 M NAP 150 195 0 Normal 122
## 6 39 M NAP 120 339 0 Normal 170
## ExerciseAngina Oldpeak ST_Slope HeartDisease
## 1 N 0.0 Up 0
## 2 N 1.0 Flat 1
## 3 N 0.0 Up 0
## 4 Y 1.5 Flat 1
## 5 N 0.0 Up 0
## 6 N 0.0 Up 0
str(data)
## 'data.frame': 918 obs. of 12 variables:
## $ Age : int 40 49 37 48 54 39 45 54 37 48 ...
## $ Sex : chr "M" "F" "M" "F" ...
## $ ChestPainType : chr "ATA" "NAP" "ATA" "ASY" ...
## $ RestingBP : int 140 160 130 138 150 120 130 110 140 120 ...
## $ Cholesterol : int 289 180 283 214 195 339 237 208 207 284 ...
## $ FastingBS : int 0 0 0 0 0 0 0 0 0 0 ...
## $ RestingECG : chr "Normal" "Normal" "ST" "Normal" ...
## $ MaxHR : int 172 156 98 108 122 170 170 142 130 120 ...
## $ ExerciseAngina: chr "N" "N" "N" "Y" ...
## $ Oldpeak : num 0 1 0 1.5 0 0 0 0 1.5 0 ...
## $ ST_Slope : chr "Up" "Flat" "Up" "Flat" ...
## $ HeartDisease : int 0 1 0 1 0 0 0 0 1 0 ...
summary(data)
## Age Sex ChestPainType RestingBP
## Min. :28.00 Length:918 Length:918 Min. : 0.0
## 1st Qu.:47.00 Class :character Class :character 1st Qu.:120.0
## Median :54.00 Mode :character Mode :character Median :130.0
## Mean :53.51 Mean :132.4
## 3rd Qu.:60.00 3rd Qu.:140.0
## Max. :77.00 Max. :200.0
## Cholesterol FastingBS RestingECG MaxHR
## Min. : 0.0 Min. :0.0000 Length:918 Min. : 60.0
## 1st Qu.:173.2 1st Qu.:0.0000 Class :character 1st Qu.:120.0
## Median :223.0 Median :0.0000 Mode :character Median :138.0
## Mean :198.8 Mean :0.2331 Mean :136.8
## 3rd Qu.:267.0 3rd Qu.:0.0000 3rd Qu.:156.0
## Max. :603.0 Max. :1.0000 Max. :202.0
## ExerciseAngina Oldpeak ST_Slope HeartDisease
## Length:918 Min. :-2.6000 Length:918 Min. :0.0000
## Class :character 1st Qu.: 0.0000 Class :character 1st Qu.:0.0000
## Mode :character Median : 0.6000 Mode :character Median :1.0000
## Mean : 0.8874 Mean :0.5534
## 3rd Qu.: 1.5000 3rd Qu.:1.0000
## Max. : 6.2000 Max. :1.0000
Dataset yang digunakan adalah Heart Disease Dataset yang berisi informasi karakteristik pasien dan status penyakit jantung.
Variabel target dalam dataset ini adalah:
HeartDisease
Dimana:
data$Sex <- as.factor(data$Sex)
data$ChestPainType <- as.factor(data$ChestPainType)
data$RestingECG <- as.factor(data$RestingECG)
data$ExerciseAngina <- as.factor(data$ExerciseAngina)
data$ST_Slope <- as.factor(data$ST_Slope)
data$HeartDisease <- as.factor(data$HeartDisease)
str(data)
## 'data.frame': 918 obs. of 12 variables:
## $ Age : int 40 49 37 48 54 39 45 54 37 48 ...
## $ Sex : Factor w/ 2 levels "F","M": 2 1 2 1 2 2 1 2 2 1 ...
## $ ChestPainType : Factor w/ 4 levels "ASY","ATA","NAP",..: 2 3 2 1 3 3 2 2 1 2 ...
## $ RestingBP : int 140 160 130 138 150 120 130 110 140 120 ...
## $ Cholesterol : int 289 180 283 214 195 339 237 208 207 284 ...
## $ FastingBS : int 0 0 0 0 0 0 0 0 0 0 ...
## $ RestingECG : Factor w/ 3 levels "LVH","Normal",..: 2 2 3 2 2 2 2 2 2 2 ...
## $ MaxHR : int 172 156 98 108 122 170 170 142 130 120 ...
## $ ExerciseAngina: Factor w/ 2 levels "N","Y": 1 1 1 2 1 1 1 1 2 1 ...
## $ Oldpeak : num 0 1 0 1.5 0 0 0 0 1.5 0 ...
## $ ST_Slope : Factor w/ 3 levels "Down","Flat",..: 3 2 3 2 3 3 3 3 2 3 ...
## $ HeartDisease : Factor w/ 2 levels "0","1": 1 2 1 2 1 1 1 1 2 1 ...
Pada tahap ini beberapa variabel diubah menjadi factor karena merupakan variabel kategorikal.
Variabel yang dikonversi antara lain:
Konversi ini penting agar model dapat mengenali variabel sebagai kategori, bukan sebagai nilai numerik.
Dataset ini berisi informasi kesehatan pasien yang digunakan untuk memprediksi kemungkinan penyakit jantung.
Variabel yang digunakan dalam pemodelan antara lain:
Variabel HeartDisease menjadi variabel target yang akan diprediksi oleh model.
set.seed(123)
trainIndex <- sample(seq_len(nrow(data)), size = 0.8*nrow(data))
train <- data[trainIndex, ]
test <- data[-trainIndex, ]
Dataset dibagi menjadi dua bagian yaitu:
Pembagian data ini bertujuan agar model dapat diuji menggunakan data yang belum pernah digunakan saat proses pelatihan.
model_logistic <- glm(
HeartDisease ~ Age + Sex + ChestPainType + RestingBP +
Cholesterol + FastingBS + RestingECG + MaxHR +
ExerciseAngina + Oldpeak + ST_Slope,
data = train,
family = binomial
)
summary(model_logistic)
##
## Call:
## glm(formula = HeartDisease ~ Age + Sex + ChestPainType + RestingBP +
## Cholesterol + FastingBS + RestingECG + MaxHR + ExerciseAngina +
## Oldpeak + ST_Slope, family = binomial, data = train)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -1.557926 1.601580 -0.973 0.330681
## Age 0.020877 0.014825 1.408 0.159064
## SexM 1.520755 0.299142 5.084 3.70e-07 ***
## ChestPainTypeATA -1.863610 0.365098 -5.104 3.32e-07 ***
## ChestPainTypeNAP -1.852727 0.290314 -6.382 1.75e-10 ***
## ChestPainTypeTA -1.238357 0.472661 -2.620 0.008794 **
## RestingBP 0.002802 0.006461 0.434 0.664576
## Cholesterol -0.003754 0.001177 -3.189 0.001430 **
## FastingBS 0.960752 0.297533 3.229 0.001242 **
## RestingECGNormal -0.199598 0.298963 -0.668 0.504366
## RestingECGST -0.158395 0.397002 -0.399 0.689909
## MaxHR -0.003407 0.005569 -0.612 0.540755
## ExerciseAnginaY 0.757258 0.270937 2.795 0.005191 **
## Oldpeak 0.402619 0.130097 3.095 0.001970 **
## ST_SlopeFlat 1.701060 0.471528 3.608 0.000309 ***
## ST_SlopeUp -0.669212 0.486933 -1.374 0.169336
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1007.44 on 733 degrees of freedom
## Residual deviance: 486.08 on 718 degrees of freedom
## AIC: 518.08
##
## Number of Fisher Scoring iterations: 5
Model dibangun menggunakan fungsi glm() dengan parameter family = binomial, yang menunjukkan bahwa model yang digunakan adalah logistic regression.
Model ini memprediksi kemungkinan seseorang mengalami penyakit jantung berdasarkan berbagai faktor kesehatan seperti usia, tekanan darah, kadar kolesterol, dan kondisi klinis lainnya.
Output dari summary() menampilkan:
Variabel dengan p-value < 0.05 dianggap memiliki pengaruh signifikan terhadap kemungkinan penyakit jantung.
exp(coef(model_logistic))
## (Intercept) Age SexM ChestPainTypeATA
## 0.2105723 1.0210967 4.5756806 0.1551117
## ChestPainTypeNAP ChestPainTypeTA RestingBP Cholesterol
## 0.1568089 0.2898601 1.0028056 0.9962528
## FastingBS RestingECGNormal RestingECGST MaxHR
## 2.6136607 0.8190596 0.8535125 0.9965991
## ExerciseAnginaY Oldpeak ST_SlopeFlat ST_SlopeUp
## 2.1324207 1.4957364 5.4797552 0.5121122
Koefisien logistic regression dapat dikonversi menjadi Odds Ratio untuk mempermudah interpretasi.
Interpretasi Odds Ratio:
Sebagai contoh, jika suatu variabel memiliki odds ratio sebesar 1.5, maka variabel tersebut meningkatkan kemungkinan terjadinya penyakit jantung sebesar 50% dibandingkan kategori referensi.
prob_pred <- predict(model_logistic, test, type = "response")
class_pred <- ifelse(prob_pred > 0.5, 1, 0)
class_pred <- as.factor(class_pred)
Model logistic regression menghasilkan nilai probabilitas antara 0 hingga 1.
Probabilitas tersebut kemudian dikonversi menjadi kelas menggunakan threshold 0.5:
conf_matrix <- table(Predicted = class_pred,
Actual = test$HeartDisease)
conf_matrix
## Actual
## Predicted 0 1
## 0 73 6
## 1 13 92
Confusion matrix digunakan untuk mengevaluasi performa model klasifikasi.
Komponen dalam confusion matrix meliputi:
accuracy <- mean(class_pred == test$HeartDisease)
accuracy
## [1] 0.8967391
Accuracy menunjukkan tingkat ketepatan model dalam melakukan klasifikasi. Nilai accuracy yang diperoleh sekitar 0.89, maka dapat diinterpretasikan bahwa:
Model Logistic Regression mampu memprediksi status penyakit jantung dengan tingkat ketepatan sekitar 89%. Nilai ini menunjukkan bahwa model memiliki performa yang cukup baik dalam membedakan pasien yang memiliki penyakit jantung dan yang tidak.
ROC Curve (Receiver Operating Characteristic Curve) digunakan untuk mengevaluasi performa model klasifikasi dengan melihat kemampuan model dalam membedakan antara dua kelas.
library(pROC)
## Warning: package 'pROC' was built under R version 4.3.3
## Type 'citation("pROC")' for a citation.
##
## Attaching package: 'pROC'
## The following objects are masked from 'package:stats':
##
## cov, smooth, var
roc_curve <- roc(test$HeartDisease, prob_pred)
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
plot(roc_curve, col="blue", main="ROC Curve - Logistic Regression")
auc_value <- auc(roc_curve)
auc_value
## Area under the curve: 0.9394
Nilai AUC (Area Under Curve) menunjukkan kemampuan model dalam membedakan antara kelas positif dan negatif.
Pada grafik ROC:
Sumbu Y (Sensitivity) menunjukkan kemampuan model dalam mendeteksi pasien yang benar-benar memiliki penyakit jantung.
Sumbu X (Specificity) menunjukkan kemampuan model dalam mengenali pasien yang tidak memiliki penyakit jantung.
Garis diagonal abu-abu pada grafik menunjukkan model klasifikasi acak. Jika kurva ROC berada dekat dengan garis diagonal tersebut, maka model tidak memiliki kemampuan prediksi yang baik.
Pada hasil yang diperoleh, kurva ROC terlihat melengkung jauh di atas garis diagonal dan mendekati sudut kiri atas grafik. Hal ini menunjukkan bahwa model Logistic Regression memiliki kemampuan yang baik dalam membedakan antara pasien yang memiliki penyakit jantung dan yang tidak.
Selain itu, nilai AUC (Area Under Curve) yang dihasilkan berada pada kategori tinggi. Nilai AUC yang mendekati 1 menunjukkan bahwa model memiliki performa klasifikasi yang sangat baik.
hist(prob_pred,
main = "Distribution of Predicted Probabilities",
xlab = "Predicted Probability",
col = "lightblue")
Histogram ini menunjukkan distribusi probabilitas yang dihasilkan oleh
model logistic regression.
Distribusi probabilitas ini menggambarkan seberapa yakin model dalam memprediksi kemungkinan pasien memiliki penyakit jantung.
Jika sebagian besar probabilitas berada di dekat 0 atau 1, maka model memiliki kemampuan klasifikasi yang baik dalam membedakan kedua kelas.
Dari histogram yang dihasilkan terlihat bahwa sebagian besar probabilitas terkonsentrasi pada dua area utama:
Area dekat 0, yang menunjukkan pasien dengan kemungkinan rendah mengalami penyakit jantung.
Area dekat 1, yang menunjukkan pasien dengan kemungkinan tinggi mengalami penyakit jantung.
Distribusi yang cukup terpisah antara kedua kelompok ini menunjukkan bahwa model mampu membedakan kelas dengan cukup jelas, sehingga menghasilkan performa klasifikasi yang baik.
Berdasarkan output summary(model_logistic), variabel yang dianggap signifikan secara statistik adalah variabel yang memiliki p-value < 0.05.
summary(model_logistic)
##
## Call:
## glm(formula = HeartDisease ~ Age + Sex + ChestPainType + RestingBP +
## Cholesterol + FastingBS + RestingECG + MaxHR + ExerciseAngina +
## Oldpeak + ST_Slope, family = binomial, data = train)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -1.557926 1.601580 -0.973 0.330681
## Age 0.020877 0.014825 1.408 0.159064
## SexM 1.520755 0.299142 5.084 3.70e-07 ***
## ChestPainTypeATA -1.863610 0.365098 -5.104 3.32e-07 ***
## ChestPainTypeNAP -1.852727 0.290314 -6.382 1.75e-10 ***
## ChestPainTypeTA -1.238357 0.472661 -2.620 0.008794 **
## RestingBP 0.002802 0.006461 0.434 0.664576
## Cholesterol -0.003754 0.001177 -3.189 0.001430 **
## FastingBS 0.960752 0.297533 3.229 0.001242 **
## RestingECGNormal -0.199598 0.298963 -0.668 0.504366
## RestingECGST -0.158395 0.397002 -0.399 0.689909
## MaxHR -0.003407 0.005569 -0.612 0.540755
## ExerciseAnginaY 0.757258 0.270937 2.795 0.005191 **
## Oldpeak 0.402619 0.130097 3.095 0.001970 **
## ST_SlopeFlat 1.701060 0.471528 3.608 0.000309 ***
## ST_SlopeUp -0.669212 0.486933 -1.374 0.169336
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1007.44 on 733 degrees of freedom
## Residual deviance: 486.08 on 718 degrees of freedom
## AIC: 518.08
##
## Number of Fisher Scoring iterations: 5
Berdasarkan hasil evaluasi model Regresi Logistik:
Model memiliki akurasi sekitar 89%, yang menunjukkan tingkat prediksi yang cukup tinggi.
Kurva ROC menunjukkan performa klasifikasi yang baik, dengan kemampuan model dalam membedakan pasien dengan dan tanpa penyakit jantung.
Distribusi probabilitas prediksi menunjukkan pemisahan yang cukup jelas antara kedua kelas.
Variabel seperti jenis kelamin, jenis nyeri dada, kadar kolesterol, gula darah puasa, angina saat olahraga, serta indikator ECG merupakan faktor yang paling berpengaruh dalam menentukan kemungkinan penyakit jantung.
Dengan demikian, model Logistic Regression yang dibangun dapat digunakan sebagai pendekatan analitis untuk membantu mengidentifikasi faktor risiko penyakit jantung berdasarkan karakteristik pasien.
World Health Organization. (2023). Cardiovascular Diseases (CVDs).
David W. Hosmer, Stanley Lemeshow, & Rodney X. Sturdivant. (2013). Applied Logistic Regression. Wiley.
Tom Fawcett. (2006). An Introduction to ROC Analysis. Pattern Recognition Letters.
Federico Soriano. (2021). Heart Failure Prediction Dataset. Kaggle.