1. Περιγραφή Dataset

Το σύνολο δεδομένων Heart Disease UCI περιλαμβάνει ιατρικές και δημογραφικές πληροφορίες από 297 ασθενείς, με στόχο την πρόβλεψη της ύπαρξης καρδιοπάθειας. Περιλαμβάνει μεταβλητές όπως ηλικία, φύλο, πίεση, χοληστερίνη και αποτελέσματα ηλεκτροκαρδιογραφήματος. Η εξαρτημένη μεταβλητή είναι δυαδική (1 = υπάρχει καρδιοπάθεια, 0 = δεν υπάρχει), κάτι που το καθιστά ιδανικό για λογιστική παλινδρόμηση. Μέσα από την ανάλυση του, μπορούμε να εντοπίσουμε τους πιο σημαντικούς παράγοντες κινδύνου και να δημιουργήσουμε προγνωστικά μοντέλα, προσφέροντας υποστήριξη σε ιατρικές αποφάσεις και πρόληψη ασθενειών.

Link(Kaggle.com)

df<-read.csv("heart_cleveland_upload.csv") #Ανάγνωση του αρχείου

2. Περιγραφή Μεταβλητών

Όνομα Μεταβλητής Τύπος Περιγραφή
age Αριθμητική Ηλικία ασθενούς σε έτη
sex Κατηγορική

Φύλο

(0=Γυναίκα, 1=Άνδρας)

cp Κατηγορική

Τύπος θωρακικού πόνου:

1 = Τυπικός στηθαγχικός πόνος
2 = Άτυπος στηθαγχικός
3 = Μη στηθαγχικός πόνος
4 = Ασυμπτωματικός

trestbps Αριθμητική Αρτηριακή πίεση (σε mm Hg
chol Αριθμητική Ολική χοληστερίνη στο αίμα (mg/dl)
fbs Δυαδική

Σάκχαρο νηστείας > 120 mg/dl

(0=Όχι, 1=Ναι)

restecg Κατηγορική

Αποτελέσματα ηρεμίας ηλεκτροκαρδιογραφήματος:

0 = Κανονικό

1 = Ανωμαλία ST-T κυμάτων

2 = Υπερτροφία κοιλιών

thalach Αριθμητική Μέγιστος καρδιακός ρυθμός (σε παλμούς ανά λεπτό)
exang Δυαδική

Πόνος στο στήθος λόγω άσκησης

(0=Όχι, 1=Ναι)

oldpeak Αριθμητική Κατάθλιψη ST κατά την άσκηση σε σύγκριση με την ηρεμία
slope Κατηγορική

Κλίση ST τμήματος κατά την άσκηση:

1 = ανερχόμενη

2 = επίπεδη

3 = κατερχόμενη

ca Κατηγορική Αριθμός κύριων αιμοφόρων αγγείων με χρώση φλουοροσκόπησης
thal Κατηγορική

Αποτελέσματα σπινθηρογραφήματος με θάλλιο:

3 = Κανονικό

6 = Σταθερό ελάττωμα

7 = Αντιστρέψιμο ελάττωμα

condition Κατηγορική

Ένδειξη ύπαρξης καρδιοπάθειας

(0=Όχι, 1=Ναι)

3. Έλεγχος για ελλιπείς και διπλότυπες τιμές

cat("Σύνολο ελλιπών τιμών:", sum(is.na(df)), "\n") #Έλεγχος για ελλιπείς τιμές (NA). Αν αποτέλεσμα > 0 τότε έχουμε ελλιπείς τιμές
## Σύνολο ελλιπών τιμών: 0
cat("Διπλότυπες γραμμές:", sum(duplicated(df)), "\n") #Έλεγχος για διπλότυπες εγγραφές. Αν το αποτέλεσμα είναι > 0, τότε υπάρχουν διπλές εγγραφές.
## Διπλότυπες γραμμές: 0

4. Δημιουργία Train και Test Set

Διαχωρίζουμε τα δεδομένα σε training και testing set με τυχαίο τρόπο. Το 70% των δεδομένων θα χρησιμοποιηθεί για το training set και το υπόλοιπο 30% για το testing set.

set.seed(960)

split <- sample.split(df$condition, SplitRatio = 0.7)
train <- subset(df, split == TRUE)
test <- subset(df, split == FALSE)

cat("Καταχωρήσεις στο training set:", nrow(train), "\n")
## Καταχωρήσεις στο training set: 208
cat("Καταχωρήσεις στο test set:", nrow(test), "\n")
## Καταχωρήσεις στο test set: 89
# Μετατροπή κατηγορικών μεταβλητών σε factors
factor_vars <- c("sex", "cp", "fbs", "restecg", "exang", "slope", "ca", "thal", "condition")
df[factor_vars] <- lapply(df[factor_vars], factor)

5. Δημιουργία Δέντρου Απόφασης Cart

Σκοπός του μοντέλου είναι να προβλέψει εάν ένας άνθρωπος είναι καρδιοπαθής(condition=1) ή όχι (condition=0) με βάση το φύλο, την ηλικία, τον αριθμό των αιμοφόρων αγγείων και το αποτέλεσμα του σπινθηρογραφήματος.
heartTree<-rpart(condition~age+sex+ca+thal, data = train, method="class", minbucket=10)
prp(heartTree)

Ρίζα (root node):

Αν thal < 1 → πάμε αριστερά (yes). Αλλιώς (thal ≥ 1) → πάμε δεξιά.

Αριστερό υποδέντρο (thal < 1)

Μεταβλητή ca (αριθμός αγγείων με στένωση):

• Αν ca < 1 → τελικό φύλλο condition = 0 (προβλέπεται ότι δεν υπάρχει καρδιοπάθεια).

• Αν ca ≥ 1 → συνεχίζουμε με sex.

Μεταβλητή sex (φύλο):

• Αν sex = 0 (γυναίκα) → τελικό φύλλο condition = 0.

• Αν sex = 1 (άνδρας) → τελικό φύλλο condition = 1.

Δεξί υποδέντρο (thal ≥ 1)

Μεταβλητή ca:

• Αν ca < 1 → τελικό φύλλο condition = 1.

• Αν ca ≥ 1 → συνεχίζουμε με age.

Μεταβλητή age:

• Αν age < 52 → τελικό φύλλο condition = 0.

• Αν age ≥ 52 → τελικό φύλλο condition = 1.

6. Προβλέψεις στο Test Set με το Δέντρο Απόφασης

Στο επόμενο βήμα εφαρμόζουμε το μοντέλο λογιστικής παλινδρόμησης στο σύνολο ελέγχου (test set) με τη χρήση της συνάρτησης predict(). Η συνάρτηση αυτή επιστρέφει την πιθανότητα κάθε παρατήρησης να ανήκει στην κατηγορία “1” (δηλαδή παρουσία καρδιοπάθειας). Το μοντέλο προβλέπει σωστά το 83.15% των 297 εγγραφών.

heartPrediction<-predict(heartTree, newdata=test, type="class")
table(test$condition, heartPrediction)
##    heartPrediction
##      0  1
##   0 46  2
##   1 13 28
PredictROC<- predict(heartTree, newdata = test)

pred <- prediction(PredictROC[,2], test$condition)
perf <- performance(pred, "tpr", "fpr")
plot(perf)

as.numeric(performance(pred, "auc")@y.values)
## [1] 0.9037093

Η ROC καμπύλη επιβεβαιώνει ότι το δέντρο αποφάσεων διαφοροποιεί αποτελεσματικά ασθενείς με και χωρίς καρδιοπάθεια. Η καμπύλη ανασηκώνεται γρήγορα προς το επάνω‑αριστερό τμήμα του γραφήματος· αυτό σημαίνει ότι το μοντέλο επιτυγχάνει υψηλούς πραγματικούς θετικούς ρυθμούς (sensitivity) με σχετικά χαμηλούς ψευδώς θετικούς ρυθμούς. Ο υπολογισμένος AUC είναι 0,90, ένδειξη πολύ καλής διακριτικής ικανότητας. Με άλλα λόγια, υπάρχει περίπου 90% πιθανότητα το μοντέλο να ταξινομήσει σωστά ένα τυχαίο ζεύγος (έναν ασθενή με καρδιοπάθεια και έναν χωρίς). Συνεπώς, το συγκεκριμένο δέντρο θεωρείται ιδιαίτερα αποδοτικό για τη διάγνωση καρδιοπάθειας στο διαθέσιμο σύνολο δεδομένων.

7. Μοντέλο Λογιστικής Παλινδρόμησης

heartLogistic<- glm(condition~age+sex+ca+thal,
                   data =train,
                   family = "binomial")

predictTest <- predict(heartLogistic, type="response", newdata=test)

table(test$condition, predictTest > 0.75)
##    
##     FALSE TRUE
##   0    48    0
##   1    22   19

Δημιουργώντας ένα μοντέλο λογιστικής παλινδρόμησης με τις ίδιες μεταβλητές, παρατηρούμε ότι η απόδοση μειώνεται στο 75.30%, καθώς κάνει περισσότερα σφάλματα σχετικά με την κατηγορία σε αντίθεση με το δέντρο απόφασης. Δηλαδή χαρακτηρίζει πολλές εγγραφές ως υγιείς, ενώ στην πραγματικότητα δεν είναι.

8. Σύγκριση Μοντέλων

Συγκρίνοντας τα δύο μοντέλα πρόβλεψης καρδιοπάθειας διαπιστώνουμε πως το μοντέλο CART έχει καλύτερη επίδοση και απόδοση (83.15%) σε σχέση με τη λογιστική παλινδρόμηση (75.30%). Επομένως, τα δέντρα απόφασης αποτελεί την καλύτερη επιλογή για το συγκεκριμένο πρόβλημα.