Στα πλαίσια της έκτης εργασίας του μαθήματος χρησιμοποιήθηκε για την Λογιστική Παλινδρόμηση το dataset “Marketing Campaigns Logistic Regression” που υπάρχει στο Kaggle (https://www.kaggle.com/datasets/taseermehboob9/marketing-campaigns-logistic-regression/data)
Το παρόν dataset αφορά στην αξιολόγηση της αποτελεσματικότητας μιας ψηφιακής καμπάνιας μάρκετινγκ. Κύριος στόχος της συλλογής των δεδομένων είναι η ανάλυση της αλληλεπίδρασης των πελατών με την καμπάνια μέσω ηλεκτρονικού ταχυδρομείου (Email Marketing), καθώς και η μελέτη της επίδρασης των προσφορών (εκπτώσεων) στην τελική αγοραστική συμπεριφορά.
library(ggplot2)
data <- read.csv("Marketingcampaigns.csv")
cat("Το dataset έχει", nrow(data), "γραμμές και", ncol(data), "στήλες.")## Το dataset έχει 20 γραμμές και 9 στήλες.
## Customer.id Age Gender Location
## Min. : 1.00 Min. :15.00 Min. :0.00 Length:20
## 1st Qu.: 5.75 1st Qu.:24.50 1st Qu.:0.00 Class :character
## Median :10.50 Median :38.00 Median :1.00 Mode :character
## Mean :10.50 Mean :38.25 Mean :0.55
## 3rd Qu.:15.25 3rd Qu.:53.50 3rd Qu.:1.00
## Max. :20.00 Max. :62.00 Max. :1.00
## Email.Opened Email.Clicked Product.page.visit Discount.offered Purchased
## Min. :0.0 Min. :0.0 Min. :0.0 Min. :0.0 Min. :0.0
## 1st Qu.:0.0 1st Qu.:0.0 1st Qu.:1.0 1st Qu.:0.0 1st Qu.:0.0
## Median :0.5 Median :1.0 Median :2.0 Median :0.5 Median :0.5
## Mean :0.5 Mean :0.6 Mean :2.1 Mean :0.5 Mean :0.5
## 3rd Qu.:1.0 3rd Qu.:1.0 3rd Qu.:3.0 3rd Qu.:1.0 3rd Qu.:1.0
## Max. :1.0 Max. :1.0 Max. :5.0 Max. :1.0 Max. :1.0
Πιο αναλυτικά το dataset Με τις 20 μόλις εγγραφές περιλαμβάνει:
Age: Περιλαμβάνει ανθρώπους από 15 έως και 62 ετών με μέσο όρο περίπου τα 38 χρόνια
Gender: Είναι το φύλο των ατόμων του δείγματος και με μέσο όρο 0.55 βλέπουμε ότι οι δύο ομάδες είναι σχεδόν ισόποσες
Location: Περιλαμβάνει ονόματα πόλεων
Email Opened: Το 50% των πελατών άνοιξε το email
Email Clicked: Το 60% των πελατών έκανε κλικ σε κάποιον σύνδεσμο. Είναι ενδιαφέρον στατιστικά ότι το ποσοστό των κλικ είναι ελαφρώς υψηλότερο από το άνοιγμα, κάτι που ίσως υποδηλώνει ότι όσοι ανοίγουν το email είναι πολύ ενεργοί.
Product Page Visit: Περιγράφει το πόσες φορές επισκέφτηκαν την σελίδα του προϊόντος τα άτομα του δείγματος. Την επισκέπτονται από 0 έως και 5 φορές, με μέσο όρο 2.1 επισκέψεις.
Discount offered: Δείχνει εάν δόθηκε ή όχι κουπόνι προσφοράς στα πλαίσια του email marketing. Το κουπόνι δόθηκε στους μισούς ανθρώπους στο δείγμα.
Purchased: Είναι η ΕΞΑΡΤΗΜΕΝΗ μεταβλητή του δείγματος και δείχνει εάν προχώρησαν τα άτομα ή όχι σε αγορά του προϊόντος. Παίρνει την τιμή 1 αν προχώρησαν σε αγορά και την τιμή 0 εάν όχι.
# Μετατροπή σε factor
data$Purchased <- as.factor(data$Purchased)
# Ξανά το γράφημα (πλέον θα βγάλει δύο κουτιά)
print(ggplot(data, aes(x = Purchased, y = Age, fill = Purchased)) +
geom_boxplot(alpha = 0.7) +
scale_fill_manual(values = c("red", "blue"),
labels = c("Όχι (0)", "Ναι (1)")) +
labs(title = "Κατανομή Ηλικίας ανά Κατάσταση Αγοράς",
x = "Πραγματοποίηση Αγοράς",
y = "Ηλικία (Έτη)") +
theme_minimal())Από το παραπάνω γράφημα, αποκαλύπτεται η μέση ηλικία των ατόμων που προχωρούν σε αγορά του προϊόντος που τους έχει προωθηθεί μέσω email. Πιο συγκεκριμένα παρατηρούμε ότι τα άτομα που αγοράζουν έχουν μέση ηλικία τα 32 περίπου έτη ενώ αυτοί που δεν προχωρούν σε αγορά εμφανίζουν υψηλότερη διάμεση ηλικία, στα 40 έτη. Η διαφορά αυτή υποδεικνύει ότι το προϊόν ή η συγκεκριμένη καμπάνια έχει μεγαλύτερη απήχηση σε νεότερες ηλικίες.
Εστιάζοντας στο μέγεθος των κουτιών, παρατηρούμε ότι η ομάδα των αγοραστών παρουσιάζει μεγαλύτερη διασπορά προς τις μικρότερες ηλικίες. Το κατώτερο όριο του μπλε κουτιού φτάνει τα 22 χρόνια, κάτι που υποδεικνύει ότι ένα σημαντικό τμήμα των αγοραστών είναι νεαρά άτομα. Αντίθετα, η ομάδα που δεν αγόρασε είναι πιο “συγκεντρωμένη” σε μεγαλύτερες ηλικίες (μεταξύ 31 και 53 ετών), με το κουτί να είναι μετατοπισμένο προς τα πάνω.
data$Discount.offered <- as.factor(data$Discount.offered)
print(ggplot(data, aes(x = Discount.offered, fill = Purchased)) +
geom_bar(position = "fill") + # Το "fill" μετατρέπει τα ύψη σε ποσοστά 0-100%
scale_y_continuous(labels = scales::percent) +
scale_fill_manual(values = c("red", "blue"),
name = "Αγορά",
labels = c("Όχι (0)", "Ναι (1)")) +
labs(title = "Επίδραση Έκπτωσης στην Πραγματοποίηση Αγοράς",
subtitle = "Ανάλυση ποσοστού μετατροπής (Conversion Rate)",
x = "Προσφορά Έκπτωσης (0 = Όχι, 1 = Ναι)",
y = "Ποσοστό (%)") +
theme_minimal()
)Το παραπάνω ραβδόγραμμα απεικονίζει την διαφορά στην αγοραστική συμπεριφορά των πελατών ανάλογα με το εάν υπάρχει εκπτωτικός κωδικός. Στην ομάδα που δεν έλαβε έκπτωση, το ποσοστό των αγοραστών ανέρχεται περίπου στο 30%. Αντίθετα, στην ομάδα που προσφέρθηκε έκπτωση, το ποσοστό αγοράς εκτοξεύτηκε στα 70%. Αυτή η οπτική διαφορά επιβεβαιώνει ότι η έκπτωση αποτελεί βασικό κριτήριο για την ολοκλήρωση της αγοράς στο συγκεκριμένο δείγμα.
print(ggplot(data, aes(x = Product.page.visit, fill = Purchased)) +
geom_density(alpha = 0.5) + # alpha για διαφάνεια ώστε να φαίνεται η επικάλυψη
scale_fill_manual(values = c("red", "blue"),
labels = c("Όχι (0)", "Ναι (1)")) +
labs(title = "Πυκνότητα Επισκέψεων στη Σελίδα Προϊόντος",
subtitle = "Σχέση ενδιαφέροντος και τελικής αγοράς",
x = "Αριθμός Επισκέψεων στη Σελίδα",
y = "Πυκνότητα (Density)") +
theme_minimal()
)Το παραπάνω desnity plot αποκαλύπτει μια σαφή διάκριση στην αγοραστική συμπεριφορά με βάση τον αριθμό επισκέψεων στην σελίδα του προϊόντος. Η ομάδα που δεν προχώρησε στην αγορά, παρουσιάζει την μέγιστη πυκνότητα στις 0 έως 1 επισκέψεις, με την καμπύλη να φθίνει γρήγορα καθώς αυξάνονται οι επισκέψεις. Αντιθέτως, η ομάδα των αγοραστών εμφανίζει μια “δίκορφη” κατανομή με έντονη παρουσία στις 2 και 3 επισκέψεις, υποδεικνύοντας ότι η επαναλαμβανόμενη αλληλεπίδραση με το προϊόν είναι καθοριστική για την τελική απόφαση.
Είναι ιδιαίτερα ενδιαφέρον το σημείο τομής των δύο καμπυλών λίγο μετά τη 1 επίσκεψη. Παρατηρούμε ότι από τις 2 επισκέψεις και πάνω, η “γαλάζια” περιοχή κυριαρχεί ολοκληρωτικά έναντι της κόκκινης. Αυτό υποδηλώνει ότι υπάρχει ένα άτυπο “κατώφλι” ενδιαφέροντος: ένας πελάτης που επισκέπτεται τη σελίδα πάνω από μία φορά έχει εξαιρετικά υψηλές πιθανότητες να μετατραπεί σε αγοραστή. Το εύρημα αυτό αναδεικνύει τη μεταβλητή Product page visit ως έναν από τους πιο αξιόπιστους προγνωστικούς δείκτες της καμπάνιας.
Το πρώτο βήμα είναι ο διαxωρισμός της βάσης μας σε train και test με τυχαίο τρόπο.
## Warning: package 'caTools' was built under R version 4.5.3
set.seed(939)
split <- sample.split(data$Purchased, SplitRatio=0.65)
train = subset(data,split==TRUE)
test = subset(data,split==FALSE)
nrow(train)## [1] 12
## [1] 8
Λόγω του περιορισμένου όγκου δεδομένων του δείγματος, επιλέχθηκε ο χωρισμός των δεδομένων σε ποσοστό 65% για το Train set (12 δεδομένα) και 35% (8 δεδομένα) για το Test set. Παρόλο που το μέγεθος του Test Set είναι μικρό, η διαδικασία αυτή ακολουθείται για να διασφαλιστεί η μεθοδολογική ορθότητα της ανάλυσης και η αξιολόγηση του μοντέλου σε δεδομένα που δεν χρησιμοποιήθηκαν κατά την εκπαίδευσή του.
Ξεκινάμε με την εισαγωγή όλων των μεταβλητών στην μέθοδο εκτός από το Customer ID
Marketing1 <- glm(Purchased ~ Age + Gender + Email.Opened + Email.Clicked +
Product.page.visit + Discount.offered,
data = train, family = binomial)
print(summary(Marketing1))##
## Call:
## glm(formula = Purchased ~ Age + Gender + Email.Opened + Email.Clicked +
## Product.page.visit + Discount.offered, family = binomial,
## data = train)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 2.20593 4.51294 0.489 0.625
## Age -0.08017 0.12630 -0.635 0.526
## Gender 2.60318 5.96080 0.437 0.662
## Email.Opened -1.13915 2.63051 -0.433 0.665
## Email.Clicked -14.91895 3721.01614 -0.004 0.997
## Product.page.visit -0.20086 1.76024 -0.114 0.909
## Discount.offered1 16.66153 3721.02628 0.004 0.996
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 16.6355 on 11 degrees of freedom
## Residual deviance: 9.1879 on 5 degrees of freedom
## AIC: 23.188
##
## Number of Fisher Scoring iterations: 17
Στο παραπάνω μοντέλο έχουν προστεθεί όλες τις μεταβλητές εκτός από το Customer ID, η οποία απλά αριθμεί τα άτομα. Παρά την έλλειψη σημαντικότητας, τα πρόσημα των συντελεστών β, συμφωνούν με ότι ειπώθηκε στην παραπάνω ανάλυση.
Πιο συγκεκριμένα:
Η Discount Offered έχει τον υψηλότερο (θετικό) συντελεστή 16.66153, το οποίο σημαίνει ότι η προσφορά έκπτωσης συνδέεται με αυξημένη πιθανότητα αγοράς
Gender (2.603): Φαίνεται να υπάρχει θετική επίδραση του φύλου, υποδεικνύοντας ότι μια συγκεκριμένη κατηγορία φύλου πιθανώς αγοράζει περισσότερο.
Η Age έχει αρνητικό συντελεστή -0.08017 αλλά είναι πολύ μικρός, δείχνοντας μια ανεπαίσθητη τάση των νεότερων ηλικιών προς την αγορά στο συγκεκριμένο υποσύνολο δεδομένων.
Email.Clicked (-14.91895): Εδώ παρατηρούμε ένα παράδοξο (αρνητικό πρόσημο). Το αρνητικό πρόσημο θα σήμαινε ότι όσοι κάνουν κλικ στο email, αγοράζουν λιγότερο. Ωστόσο, το πολύ μεγάλο Std. Error (3721) μας λέει ότι αυτή η εκτίμηση είναι στατιστικά “άχρηστη” και οφείλεται πιθανώς στο ότι στο train set δεν υπήρχαν αρκετοί συνδυασμοί ατόμων που και έκαναν κλικ και αγόρασαν.
Η τιμή AIC ισούται με 23.188, η οποία θα πρέπει να μειωθεί για να υπάρχει ένα καλύτερο μοντέλο.
Στην συνέχεια, σε προσπάθεια μείωσης της AIC, αφαιρέθηκαν μια μια με
την σειρά οι μεταβλητές: Email Opened +
Email Clicked, Age, Product page visit και το
Gender όπως φαίνεται και παρακάτω
Marketing2 <- glm(Purchased ~ Age + Gender +
Product.page.visit + Discount.offered,
data = train, family = binomial)
Marketing3 <- glm(Purchased ~ Gender +
Product.page.visit + Discount.offered,
data = train, family = binomial)
Marketing4 <- glm(Purchased ~ Gender + Discount.offered,
data = train, family = binomial)
Marketing5 <- glm(Purchased ~ Discount.offered,
data = train, family = binomial)Τα αποτελέσματα ήταν:
| Μοντέλο | Μεταβλητές | AIC |
|---|---|---|
| Marketing2 | Age + Gender + Product page visit +
Discount offered |
19.625 |
| Marketing3 | Gender + Product page visit +
Discount offered |
19.163 |
| Marketing4 | Gender + Discount offered |
17.574 |
| Marketing5 | Discount offered |
17.38 |
Μετά την διαδικασία της σταδιακής αφαίρεσης μεταβλητών, το μοντέλο που προέκυψε ως το πλέον αποδοτικό περιλαμβάνει μόνο την μεταβλητή της Έκπτωσης (Discount offered). Η μείωση του AIC από 28.717 σε 23.833 υποδηλώνει ότι οι άλλες μεταβλητές πρόσθεταν περισσότερο “θόρυβο” παρά ουσιαστική πληροφορία.
Για τον σκοπό όμως της εργασίας κρατάμε μόνο το Marketing1 το οποίο περιλαμβάνει όλες τις μεταβλητές
Μετά την επιλογή του βέλτιστου μοντέλου, πραγματοποιήθηκε πρόβλεψη των πιθανοτήτων αγοράς στο Test set
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.500e-07 1.720e-06 3.881e-01 3.905e-01 6.489e-01 9.697e-01
Η συνάρτηση predict() με την παράμετρο type=“response” αποτελεί το εργαλείο μετάβασης από τη θεωρητική ανάλυση στην πρακτική εφαρμογή, καθώς εφαρμόζει τους συντελεστές που υπολογίστηκαν στο δείγμα εκπαίδευσης πάνω στα νέα δεδομένα του δείγματος ελέγχου (test set). Αντί για μια απλή κατηγοριοποίηση, η εντολή αυτή επιστρέφει την εκτιμώμενη πιθανότητα (\(P\)) πραγματοποίησης αγοράς για κάθε πελάτη, προσφέροντας μια λεπτομερή εικόνα για την “πεποίθηση” του μοντέλου. Οι τιμές αυτές κυμαίνονται αυστηρά στο διάστημα \([0, 1]\), όπου τιμές κοντά στην μονάδας υποδηλώνουν βεβαιότητα για αγορά, ενώ τιμές κοντά στο 0 υποδηλώνουν βεβαιότητα για μη ανταπόκριση.
Στην περίπτωση του μοντέλου Marketing1, τα αποτελέσματα του summary αποκαλύπτουν μια πολύ μεγάλη διασπορά στις προβλεπόμενες πιθανότητες, οι οποίες εκτείνονται από την οριακά μηδενική τιμή 1.500e-07 έως το εξαιρετικά υψηλό 96.97%. Η ύπαρξη τόσο ακραίων τιμών (Min και Max) υποδηλώνει ότι το μοντέλο, λόγω των μεγάλων συντελεστών που απέδωσε σε μεταβλητές όπως η έκπτωση, εμφανίζεται ιδιαίτερα “αποφασιστικό”.
Η διάμεσος τιμή (Median: 0.3881) υποδεικνύει ότι για την πλειονότητα των πελάτων του δείγματος ελέγχου, το μοντέλο εκτιμά μια πιθανότητα αγοράς χαμηλότερη του 40%, γεγονός που ταυτίζεται με τη γενικότερη τάση των δεδομένων.
Η εγγύτητα του μέσου όρου (Mean: 0.3905) με τη διάμεσο επιβεβαιώνει μια σχετικά ισορροπημένη κατανομή των προβλέψεων γύρω από το 39%, καθιστώντας το μοντέλο έτοιμο για την εφαρμογή του κατωφλίου ταξινόμησης \(T=0.5\) που θα ακολουθήσει για τον έλεγχο της τελικής ακρίβειας.
Επόμενο βήμα είναι η δημιουργία του confusion matrix με \(T= 0.5\)
##
## FALSE TRUE
## 0 2 2
## 1 3 1
# Δημιουργία του πίνακα από την εντολή σου
conf_matrix <- table(test$Purchased, predictTest > 0.5)
TN <- conf_matrix[1,1] # Πραγματικό 0, Πρόβλεψη 0 (2)
FP <- conf_matrix[1,2] # Πραγματικό 0, Πρόβλεψη 1 (2)
FN <- conf_matrix[2,1] # Πραγματικό 1, Πρόβλεψη 0 (3)
TP <- conf_matrix[2,2] # Πραγματικό 1, Πρόβλεψη 1 (1)
# Υπολογισμός Δεικτών Μοντέλου
Accuracy <- (TP + TN) / sum(conf_matrix)
Sensitivity <- TP / (TP + FN)
Specificity <- TN / (TN + FP)
# Υπολογισμός Baseline Accuracy
baseline_accuracy <- sum(test$Purchased == 0) / nrow(test)
# Εμφάνιση αποτελεσμάτων
data.frame(Accuracy, Sensitivity, Specificity, baseline_accuracy)## Accuracy Sensitivity Specificity baseline_accuracy
## 1 0.375 0.25 0.5 0.5
Για \(T=0.5\) έχουμε
| Predict = 0 | Predict = 1 |
|:----------|:-----------------------------|
|Actual = 0 | 2 | 2 |
|Actual = 1 | 3 | 1 |
Το μοντέλο κατάφερε να ταξινομήσει ορθά τις τρεις από τις οκτώ συνολικά παρατηρήσεις, επιβεβαιώνοντας ότι η προσθήκη όλων των μεταβλητών σε ένα τόσο μικρό δείγμα ελέγχου οδήγησε σε αρκετά σφάλματα.
Η εφαρμογή του κατωφλίου \(T=0.5\) στο πλήρες μοντέλο Marketing1 αποκάλυψε τις προκλήσεις που αντιμετωπίζει η λογιστική παλινδρόμηση όταν χρησιμοποιεί μεγάλο αριθμό μεταβλητών σε περιορισμένο δείγμα.
Η συνολική Ακρίβεια (Accuracy) του μοντέλου διαμορφώθηκε στο 37.5%, μια τιμή που κρίνεται χαμηλή. Συγκεκριμένα, το μοντέλο κατάφερε να εντοπίσει σωστά δύο περιπτώσεις μη-αγοράς (True Negatives) και μία περίπτωση αγοράς (True Positive), αποτυγχάνοντας όμως να ταξινομήσει ορθά τις υπόλοιπες πέντε παρατηρήσεις. Αναλύοντας τα σφάλματα, παρατηρούμε υψηλό αριθμό False Negatives (3), όπου το μοντέλο προέβλεψε μη-αγορά για πελάτες που τελικά αγόρασαν. Αυτό είχε ως αποτέλεσμα η Sensitivity να περιοριστεί στο 25%, δείχνοντας ότι το πλήρες μοντέλο δυσκολεύεται να αναγνωρίσει τους πραγματικούς αγοραστές. Παράλληλα, σημειώθηκαν δύο False Positives σφάλματα, γεγονός που μείωσε την Specificity στο *50% , υποδεικνύοντας ότι το μοντέλο “μπερδεύτηκε” από τον επιπλέον θόρυβο των πολλών μεταβλητών.
Το αποτέλεσμα αυτό αναδεικνύει το φαινόμενο του Overfitting, όπου το μοντέλο Marketing1, προσπαθώντας να συμπεριλάβει όλες τις πληροφορίες (ηλικία, φύλο, emails), έχασε τη γενικευτική του ικανότητα στο test set. Η σύγκριση αυτής της απόδοσης με το Baseline Model είναι καθοριστική, καθώς συχνά σε τόσο μικρά και “θορυβώδη” δείγματα, η απλή στατιστική κυριαρχία μιας κατηγορίας μπορεί να προσφέρει υψηλότερη ακρίβεια από ένα υπερβολικά πολύπλοκο μοντέλο.
Επόμενο βήμα είναι η δημιουργία της ROCpred και η δημιουργία 2 νέων σετ
## Warning: package 'ROCR' was built under R version 4.5.3
ROCRpred <- prediction(predictTest, test$Purchased)
train2 <- na.omit(train)
test2 <- na.omit(test)
# Καταγραφή των καταχωρήσεων
n_train2 <- nrow(train2)
n_test2 <- nrow(test2)
# Εμφάνιση των αριθμών
cat("Καταχωρήσεις στο train2:", n_train2, "\n")## Καταχωρήσεις στο train2: 12
## Καταχωρήσεις στο test2: 8
Δεδομένου ότι δεν υπάρχουν κενές τιμές στο dataset, το train και το test παραμένουν τα ίδια δηλαδή 12 εγγραφές στο train και 8 στο Test.
Στην συνέχεια δημιουργούμε πάλι το μοντέλο
Marketing <- glm(Purchased ~ Age + Gender + Email.Opened + Email.Clicked +
Product.page.visit + Discount.offered,
data = train2, family = binomial)
print(summary(Marketing))##
## Call:
## glm(formula = Purchased ~ Age + Gender + Email.Opened + Email.Clicked +
## Product.page.visit + Discount.offered, family = binomial,
## data = train2)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 2.20593 4.51294 0.489 0.625
## Age -0.08017 0.12630 -0.635 0.526
## Gender 2.60318 5.96080 0.437 0.662
## Email.Opened -1.13915 2.63051 -0.433 0.665
## Email.Clicked -14.91895 3721.01614 -0.004 0.997
## Product.page.visit -0.20086 1.76024 -0.114 0.909
## Discount.offered1 16.66153 3721.02628 0.004 0.996
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 16.6355 on 11 degrees of freedom
## Residual deviance: 9.1879 on 5 degrees of freedom
## AIC: 23.188
##
## Number of Fisher Scoring iterations: 17
Τέλος θα δημιουργήσουμε την ROC curve και να υπολογίσουμε τον δείκτη AUC.
ROCRpred2 <- prediction(predictTest2, test2$Purchased)
ROCRperf2 <- performance(ROCRpred2, "tpr", "fpr")
plot(ROCRperf2,colorize = TRUE, main = "ROC Curve: Logistic Regression",print.cutoffs.at=seq(0,1,0.1),text.adj=c(-0.2,1.7))## AUC = 0.375
Η παραπάνω καμπύλη ROC που παρήχθει για το παραπάνω πλήρες μοντέλο παρουσιάζει μια ιδιαίτερη μορφή καθώς κινείται κυρίως κάτω από τη διαγώνιο της τυχαίας πρόβλεψης. Το γεγονός αυτό οδηγεί στο συμπέρασμα ότι το μοντέλο έχει εξξαιρετικά χαμηλή διακριτική ικανότητα. Η “τετραγωνισμένη” μορφή της οφείλεται στο μικρό μέγεθος του test set (\(N=8\)), όπου κάθε λανθασμένη πρόβλεψη προκαλεί μεγάλες απότομες μεταβολές στους άξονες TPR και FPR.
Η χαμηλή τιμή του δείκτη AUC, ο οποίος ισούται με 0.375, επιβεβαιώνει στατιστικά την αδυναμία του μοντέλου. Όταν ο συγκεκριμένος δείκτης πέσει κάτω από 0.5, αυτόματα συνεπάγεται ότι το μοντέλο προβλέπει χειρότερα από μια λανθασμένη μαντεψιά. Στην πραγματικότητα , η τιμή 0.375 σημαίνει ότι αν επιλέξουμε τυχαία έναν αγοραστή και έναν μη-αγοραστή, το μοντέλο θα δόσει λανθασμένα υψηλότερη πιθανότητα αγοράς στον μη αγοραστή στις περισσότερες περιπτώσεις. Το αποτέλεσμα αυτό συνάδει απόλυτα με τη χαμηλή ακρίβεια (37.5%) που καταγράφηκε στον πίνακα συνάφειας.
Το χαμηλό αυτό AUC αποτελεί την τελική απόδειξη του φαινομένου του Overfitting. Η προσπάθεια του μοντέλου να ενσωματώσει πολλές ανεξάρτητες μεταβλητές (Age, Gender, Email interactions κ.α.) με ελάχιστα δεδομένα εκπαίδευσης, οδήγησε σε “θόρυβο” που αλλοίωσε τις προβλέψεις. Η χρωματική κωδικοποίηση (color-coding) στην καμπύλη αποκαλύπτει ότι το κατώφλι \(T=0.5\) (που εντοπίζεται στο κέντρο της κατακόρυφης γραμμής) δεν αποτελεί το “βέλτιστο” σημείο, καθώς το μοντέλο παραμένει σταθερά κάτω από τη διαγώνιο.
Ακόμα και αν μετακινούσαμε το κατώφλι απόφασης (π.χ. στο 0.3 ή στο 0.7), η απόδοση δεν βελτιώνεται ουσιαστικά, κάτι που αποδεικνύει ότι το πρόβλημα δεν εντοπίζεται στο επιλεγμένο κατώφλι, αλλά στη δομική αποτυχία του μοντέλου να ερμηνεύσει σωστά τις ανεξάρτητες μεταβλητές στο νέο δείγμα. Συμπερασματικά, η οπτικοποίηση αυτή ενισχύει την άποψη ότι για τη συγκεκριμένη βάση δεδομένων, ένα απλούστερο μοντέλο θα ήταν πολύ πιο αποτελεσματικό και στατιστικά ασφαλές.
Για τα Δέντρα Απόφασης θα χρησιμοποιήσω τις βιβλιοθήκες rpart για την δημιουργία του δέντρου και rpart.plot για την οπτικοποίηση. Γίνεται χρήση του train και του test dataset που ορίστηκαν στην λογιστική παλινδρόμηση με 12 και 8 παρατηρήσεις αντίστοιχα
## Warning: package 'rpart' was built under R version 4.5.3
## Warning: package 'rpart.plot' was built under R version 4.5.3
Θα εκπαιδεύσουμε το δέντρο προσθέτοντας όλες τις μεταβλητές στο μοντέλο εκτός από την CustomerID η οποία απλά απαριθμεί τα άτομα.
Στη δημιουργία ενός Δέντρου Απόφασης, οι παράμετροι αυτοί λειτουργούν ως «φρένα» στην ανάπτυξη του δέντρου. Λόγω του περιορισμένου μεγέθους του dataset (20 εγγραφές συνολικά, 12 στο training set), η χρήση των προκαθορισμένων (default) τιμών θα εμπόδιζε το δέντρο να δημιουργήσει οποιαδήποτε διακλάδωση.
minsplit = 2: Αυτή η παράμετρος ορίζει τον ελάχιστο αριθμό παρατηρήσεων που πρέπει να υπάρχουν σε έναν κόμβο για να επιχειρηθεί μια διαίρεση. Η προεπιλογή είναι συνήθως 20. Αν την αφήναμε στην προεπιλογή, το δέντρο δεν θα ξεκινούσε καν, αφού όλο το training set έχει μόνο 12 άτομα. Θέτοντας minsplit = 2, επιτρέπουμε στο μοντέλο να δημιουργήσει κλάδους ακόμα και για πολύ μικρές ομάδες πελατών.
cp = 0.001 (Complexity Parameter): Ο δείκτης πολυπλοκότητας σταματά τις διαιρέσεις που δεν βελτιώνουν την ορθότητα του μοντέλου κατά ένα συγκεκριμένο ποσοστό. Μια πολύ μικρή τιμή (κοντά στο μηδέν) επιτρέπει στο δέντρο να γίνει όσο πιο βαθύ και αναλυτικό “θέλει”, εξαντλώντας κάθε πληροφορία από το μικρό δείγμα.
Το παραπάνω διάγραμμα του δέντρου διαβάζεται από πάνω προς τα κάτω και κάθε κόμβος περιλαμβάνει 3 πληροφορίες: την επικρατούσα κατηγορία (0 ή 1), την πιθανότητα και το ποσοστό των δεδομένων που ανήκουν στον κόμβο. Πιο συγκεκριμένα:
1. Root Node (Ρίζα) - Age >=24:
Το δέντρο θεωρεί την Ηλικία ως την πιο σημαντική μεταβλητή για τον πρώτο διαχωρισμό.
Αν Ηλικία μικρότερη από 24 (δεξί σκέλος “no”), το μοντέλο προβλέπει με βεβαιότητα 100% ότι ο πελάτης θα αγοράσει(1). Αυτό αφορά το 25% του δείγματος.
2. Δεύτερο Επίπεδο - Email.Op = 1:
Για όσους είναι 24 ετών και άνω, το δέντρο εξετάζει αν άνοιξαν το email (Email.Op).
Αν δεν άνοιξαν το email (αριστερό σκέλος), η πρόβλεψη είναι μη αγορά (0) με βεβαιότητα 100% (το 33% του δείγματος).
3. Τρίτο Επίπεδο - Age < 42:
Αν ο πελάτης είναι >= 24 και άνοιξε το email, εξετάζεται πάλι η ηλικία.
Πελάτες 42 ετών και άνω (δεξί σκέλος “no”) προβλέπεται ότι θα αγοράσουν (1). Αυτό αφορά το 17% του δείγματος.
4. Τέταρτο Επίπεδο - Age >= 29:
Στο τελευταίο στάδιο για την ηλικιακή ομάδα 24-41 που άνοιξε το email:
Αν είναι άνω των 29 ετών, η πρόβλεψη είναι μη αγορά (0).
Αν είναι κάτω των 29 ετών (δηλαδή μεταξύ 24 και 28), η πρόβλεψη είναι αγορά (1).
Σύγκριση Μεθοδολογιών: Δέντρα vs Λογιστική Παλινδρόμηση
Παρατηρούμε ότι το δέντρο “αγνόησε” μεταβλητές όπως το Gender (Φύλο) ή το Discount.offered (Έκπτωση) σε αυτή τη συγκεκριμένη εκτέλεση, δίνοντας προτεραιότητα στην Ηλικία και το Email Opening.
Αυτό έρχεται σε μια ενδιαφέρουσα αντίθεση με τη Λογιστική Παλινδρόμηση, όπου η Έκπτωση φάνηκε πιο ισχυρή. Η διαφορά οφείλεται στη φύση των αλγορίθμων:
Τα Δέντρα Απόφασης αναζητούν “καθαρούς” διαχωρισμούς (splits) στο συγκεκριμένο training set, όπου εδώ η ηλικία προσέφερε την υψηλότερη καθαρότητα (Gini impurity/Information Gain).
Η Λογιστική Παλινδρόμηση υπολογίζει τη μέση επίδραση κάθε μεταβλητής συνολικά, προσπαθώντας να προσαρμόσει μια μαθηματική συνάρτηση σε όλα τα σημεία ταυτόχρονα.
Εφαρμόζουμε το μοντέλο στο test set για να δούμε πώς συμπεριφέρεται σε “άγνωστους” πελάτες.
# Πρόβλεψη κατηγορίας
tree_predict <- predict(tree_model, newdata = test, type = "class")
# Confusion Matrix
conf_matrix_tree <- table(test$Purchased, tree_predict)
print(conf_matrix_tree)## tree_predict
## 0 1
## 0 2 2
## 1 2 2
# Υπολογισμός Ακρίβειας (Accuracy)
accuracy_tree <- sum(diag(conf_matrix_tree)) / sum(conf_matrix_tree)
cat("Accuracy Δέντρου Απόφασης:", accuracy_tree * 100, "%")## Accuracy Δέντρου Απόφασης: 50 %
Ο πίνακας συνάφειας (Confusion Matrix) για το δείγμα ελέγχου (\(N=8\)) δείχνει τα εξής:
True Negatives (2): Το μοντέλο προέβλεψε σωστά 2 άτομα που δεν προχώρησαν σε αγορά.
True Positives (2): Το μοντέλο εντόπισε σωστά 2 άτομα που τελικά αγόρασαν το προϊόν.
False Positives (2): Το μοντέλο προέβλεψε λανθασμένα αγορά για 2 άτομα που δεν ανταποκρίθηκαν.
False Negatives (2): Το μοντέλο απέτυχε να εντοπίσει 2 πραγματικούς αγοραστές.
Η συνολική Ακρίβεια (Accuracy) του μοντέλου ανέρχεται στο 50% (4 σωστές προβλέψεις στις 8). Παρατηρούμε μια απόλυτα ισορροπημένη κατανομή στα σφάλματα, γεγονός που υποδηλώνει ότι το δέντρο, παρά το μικρό μέγεθος των δεδομένων, κατάφερε να “μάθει” ορισμένα μοτίβα καλύτερα από την τυχαία επιλογή, αλλά εξακολουθεί να περιορίζεται από την έλλειψη επαρκούς πληροφορίας στο test set.
Σύγκριση Μεθοδολογιών: Δέντρα vs Λογιστική Παλινδρόμηση
Η σύγκριση των δύο μοντέλων αποκαλύπτει ότι το Δέντρο Απόφασης υπερέχει σε ακρίβεια (50%) έναντι της Λογιστικής Παλινδρόμησης (37.5%) για το συγκεκριμένο dataset.
Η διαφορά αυτή εξηγείται από τον τρόπο λειτουργίας των αλγορίθμων:
Δέντρο Απόφασης: “Αγνόησε” μεταβλητές που εισήγαγαν θόρυβο, όπως το Gender ή το Discount.offered, και εστιάστηκε σε “καθαρούς” διαχωρισμούς (splits) με βάση την Ηλικία και το Email Opening. Αυτή η “χειρουργική” προσέγγιση επέτρεψε στο μοντέλο να κάνει πιο στοχευμένες προβλέψεις στο μικρό δείγμα.
Λογιστική Παλινδρόμηση: Προσπάθησε να ενσωματώσει τη μέση επίδραση όλων των μεταβλητών ταυτόχρονα. Παρόλο που η Έκπτωση αναγνωρίστηκε ως ισχυρός παράγοντας, η προσπάθεια προσαρμογής μιας μαθηματικής συνάρτησης σε πολλές ανεξάρτητες μεταβλητές με ελάχιστα δεδομένα οδήγησε σε έντονο Overfitting, μειώνοντας την ικανότητα γενίκευσης στο test set.
Συμπερασματικά, για το συγκεκριμένο case study, η μη-γραμμική προσέγγιση του Δέντρου Απόφασης αποδείχθηκε πιο ανθεκτική στον θόρυβο των δεδομένων.
Στα δέντρα απόφασης, για να σχεδιάσουμε την καμπύλη ROC, χρειαζόμαστε τις πιθανότητες (probabilities) και όχι μόνο την τελική κατηγοριοποίηση.
# 1. Πρόβλεψη πιθανοτήτων (αντί για κλάσεις)
tree_probs <- predict(tree_model, newdata = test, type = "prob")
# Κρατάμε την πιθανότητα για την κλάση "1" (αγορά)
probs_for_roc <- tree_probs[, 2]
# 2. Δημιουργία αντικειμένου πρόβλεψης για το ROCR
tree_prediction_obj <- prediction(probs_for_roc, test$Purchased)
# 3. Υπολογισμός απόδοσης (True Positive Rate & False Positive Rate)
tree_performance <- performance(tree_prediction_obj, "tpr", "fpr")
# 4. Σχεδιασμός ROC Curve
plot(tree_performance, colorize = TRUE,
main = "ROC Curve: Decision Tree",
lwd = 2)
abline(a = 0, b = 1, lty = 2, col = "gray") # Διαγώνιος τυχαίας πρόβλεψης # 5. Υπολογισμός AUC
tree_auc_value <- as.numeric(performance(tree_prediction_obj, "auc")@y.values)
cat("AUC Δέντρου Απόφασης =", round(tree_auc_value, 3))## AUC Δέντρου Απόφασης = 0.5
Η καμπύλη ROC για το Δέντρο Απόφασης παρουσιάζει μια ευθύγραμμη μορφή που συμπίπτει ακριβώς με τη διαγώνιο του διαγράμματος. Αυτό μεταφράζεται σε έναν δείκτη AUC ίσο με 0.500.
Στατιστική Ερμηνεία: Η τιμή 0.500 υποδηλώνει ότι η διακριτική ικανότητα του μοντέλου βρίσκεται στο επίπεδο της τυχαίας πρόβλεψης. Στο συγκεκριμένο test set, το μοντέλο δεν κατάφερε να διαχωρίσει τους αγοραστές από τους μη-αγοραστές με στατιστική υπεροχή.
Αιτιολογία Μορφής: Η “γραμμικότητα” της καμπύλης οφείλεται στο εξαιρετικά μικρό δείγμα ελέγχου (\(N=8\)) και στον περιορισμένο αριθμό τερματικών κόμβων (leaves) του δέντρου. Καθώς το μοντέλο παράγει πολύ συγκεκριμένες και λίγες τιμές πιθανοτήτων, η καμπύλη δεν μπορεί να αποκτήσει την τυπική κυρτή μορφή, αλλά περιορίζεται σε μια ευθεία γραμμή που συνδέει την αρχή (0,0) με το τέλος (1,1) των αξόνων.
Τελική Αξιολόγηση Μοντέλων: Σύγκριση Διακριτικής Ικανότητας (AUC/ROC)
Η παράλληλη εξέταση των δύο διαγραμμάτων ROC οδηγεί σε κρίσιμα συμπεράσματα για την αξιοπιστία των μοντέλων:
Βελτίωση από το “Λανθασμένο” στο “Ουδέτερο”: Η Λογιστική Παλινδρόμηση παρουσίασε AUC 0.375, τιμή που βρίσκεται κάτω από τη διαγώνιο. Αυτό σημαίνει ότι το μοντέλο λειτούργησε παραπλανητικά, δίνοντας υψηλότερες πιθανότητες αγοράς σε άτομα που τελικά δεν αγόρασαν. Το Δέντρο Απόφασης, με AUC 0.500, κατάφερε να εξαλείψει αυτή την αρνητική μεροληψία, φτάνοντας σε ένα ουδέτερο επίπεδο πρόβλεψης.
Διαχείριση Overfitting: Η καμπύλη της Λογιστικής Παλινδρόμησης παρουσιάζει απότομες μεταβολές και “σκαλοπάτια” κάτω από τη διαγώνιο, ένδειξη ότι το μοντέλο παρασύρθηκε από τον θόρυβο των πολλών μεταβλητών. Το Δέντρο Απόφασης, επιλέγοντας πιο απλούς κανόνες (όπως η Ηλικία), απέφυγε την “υπερβολική προσπάθεια” προσαρμογής, επιτυγχάνοντας μια πιο σταθερή, αν και ουδέτερη, συμπεριφορά.
Συμπέρασμα: Παρά το γεγονός ότι κανένα μοντέλο δεν πέτυχε υψηλή διακριτική ικανότητα (λόγω του περιορισμού των 20 εγγραφών), το Δέντρο Απόφασης αποδείχθηκε στατιστικά ασφαλέστερο. Σε συνθήκες έλλειψης δεδομένων, η απλότητα του δέντρου λειτούργησε ως ασπίδα κατά των συστηματικών λαθών που εμφάνισε η παλινδρόμηση.
Ολοκληρώνοντας τη μελέτη της καμπάνιας, η σύγκριση των δύο μεθοδολογιών προσφέρει πολύτιμα συμπεράσματα για τη συμπεριφορά των αλγορίθμων σε συνθήκες “ρηχών” δεδομένων (N=20). Παρακάτω συνοψίζονται τα βασικά ευρήματα της ανάλυσης.
| Χαρακτηριστικό | Λογιστική Παλινδρόμηση | Δέντρο Απόφασης |
|---|---|---|
| Προγνωστική Ικανότητα (Accuracy) | 37.5% | 50.0% |
| Δείκτης Διακριτότητας (AUC) | 0.375 | 0.500 |
| Κυρίαρχη Μεταβλητή | Discount Offered | Age |
| Αξιοπιστία Προβλέψεων | Χαμηλή (Overfitting) | Ουδέτερη (Baseline) |
Η σύγκριση των καμπυλών ROC αναδεικνύει μια σαφή ποιοτική διαφορά ανάμεσα στις δύο προσεγγίσεις:
Από την Παραπλάνηση στην Ουδετερότητα: Η Λογιστική Παλινδρόμηση “αποπέμφθηκε” από τη διαδικασία λόγω του δείκτη AUC (0.375), ο οποίος έδειξε ότι το μοντέλο έδινε λανθασμένες κατευθύνσεις. Αντίθετα, το Δέντρο Απόφασης κατάφερε να “διορθώσει” αυτή την εικόνα, φτάνοντας στο 0.500, το οποίο αν και ουδέτερο, είναι στατιστικά ασφαλέστερο.
Η “Παγίδα” της Πολυπλοκότητας: Η παλινδρόμηση προσπάθησε να ερμηνεύσει ταυτόχρονα όλες τις παραμέτρους (φύλο, κλικς, ηλικία), με αποτέλεσμα να παρασυρθεί από τον στατιστικό θόρυβο. Το Δέντρο Απόφασης, λειτουργώντας πιο “έξυπνα”, επέλεξε να εστιάσει μόνο στους καθοριστικούς παράγοντες, αποφεύγοντας το ακραίο Overfitting.
Τελικό Πόρισμα: Το Δέντρο Απόφασης λειτούργησε ως ένας πιο “νηφάλιος” κριτής. Σε περιβάλλοντα με ελάχιστα δεδομένα, η απλότητα των κανόνων του δέντρου υπερέχει της μαθηματικής πολυπλοκότητας της παλινδρόμησης.
Στρατηγική Marketing: Η ανάλυση υπέδειξε ότι η ηλικιακή ομάδα κάτω των 24 ετών παρουσιάζει την υψηλότερη δυναμική για αγορά. Αν αυτός ο παράγοντας συνδυαστεί με την Προσφορά Έκπτωσης (που φάνηκε ισχυρή στην αρχική μας οπτικοποίηση), η καμπάνια μπορεί να μεγιστοποιήσει την απόδοσή της.
Μεθοδολογικό Δίδαγμα: Η εργασία απέδειξε ότι η ακρίβεια ενός μοντέλου δεν εξαρτάται μόνο από τον αλγόριθμο, αλλά και από τον όγκο των δεδομένων. Η Λογιστική Παλινδρόμηση απαιτεί μεγαλύτερα δείγματα για να “στρώσει” τη συνάρτησή της, ενώ το Δέντρο Απόφασης είναι πιο ανθεκτικό σε μικρά σύνολα.
Πρόταση Βελτίωσης: Για μελλοντική χρήση, προτείνεται η συλλογή τουλάχιστον 100-200 εγγραφών, ώστε να μπορέσουμε να αξιοποιήσουμε πλήρως τις δυνατότητες των αλγορίθμων και να ξεπεράσουμε το τυχαίο επίπεδο πρόβλεψης (AUC > 0.5).