Προέλευση και Περιεχόμενο: Το συγκεκριμένο σύνολο δεδομένων περιέχει ιστορικά στοιχεία πωλήσεων από 45 καταστήματα της Walmart που βρίσκονται σε διαφορετικές περιοχές των ΗΠΑ. Περιλαμβάνει εβδομαδιαία δεδομένα για μια περίοδο περίπου 3 ετών (2010-2012) και προέρχεται αρχικά από έναν διαγωνισμό του Kaggle (Walmart Recruiting - Store Sales Forecasting). Περιλαμβάνει τις πωλήσεις, καθώς και εξωτερικούς δείκτες όπως η θερμοκρασία, η τιμή των καυσίμων, η ανεργία και ο δείκτης τιμών καταναλωτή (CPI), επιτρέποντας μια ολιστική προσέγγιση της επιχειρηματικής απόδοσης και των συνθηκών κάτω από τις οποίες λειτουργεί η εταιρεία.
Προσαρμογή για Διωνυμική Λογιστική Παλινδρόμηση: Καθώς για τους σκοπούς της παρούσας εργασίας επιλέχθηκε η εφαρμογή της Διωνυμικής Λογιστικής Παλινδρόμησης, πραγματοποιήθηκε επεξεργασία των αρχικών δεδομένων. Συγκεκριμένα, προστέθηκε μια επιπλέον στήλη η οποία λειτουργεί ως εξαρτημένη μεταβλητή και καθορίζει το αν μια εβδομάδα είναι εμπορικά «επιτυχημένη» ή όχι. Δόθηκε η τιμή 1 (επιτυχία) αν οι πωλήσεις της εβδομάδας ξεπέρασαν τον γενικό μέσο όρο και η τιμή 0 (αποτυχία) αν κυμάνθηκαν κάτω από αυτόν, διαμορφώνοντας έτσι το dataset κατάλληλα για τη δημιουργία του μοντέλου στο συγκεκριμένο case study.
# Φόρτωση βιβλιοθηκών
library(caTools)
library(ROCR)
# Φόρτωση
Walmart <- read.csv("Walmart.csv")
#Δημιουργία Binary μεταβλητής(επιτυχία/αποτυχία)
# Βρίσκουμε τον μέσο όρο των πωλήσεων
mean_sales <- mean(Walmart$Weekly_Sales)
Walmart$Success <- ifelse(Walmart$Weekly_Sales > mean_sales, 1, 0)
# Επισκόπηση της δομής των δεδομένων
str(Walmart)## 'data.frame': 6435 obs. of 9 variables:
## $ Store : int 1 1 1 1 1 1 1 1 1 1 ...
## $ Date : chr "5/2/2010" "12/2/2010" "19-02-2010" "26-02-2010" ...
## $ Weekly_Sales: num 1643691 1641957 1611968 1409728 1554807 ...
## $ Holiday_Flag: int 0 1 0 0 0 0 0 0 0 0 ...
## $ Temperature : num 42.3 38.5 39.9 46.6 46.5 ...
## $ Fuel_Price : num 2.57 2.55 2.51 2.56 2.62 ...
## $ CPI : num 211 211 211 211 211 ...
## $ Unemployment: num 8.11 8.11 8.11 8.11 8.11 ...
## $ Success : num 1 1 1 1 1 1 1 1 1 1 ...
## Store Date Weekly_Sales Holiday_Flag
## Min. : 1 Length:6435 Min. : 209986 Min. :0.00000
## 1st Qu.:12 Class :character 1st Qu.: 553350 1st Qu.:0.00000
## Median :23 Mode :character Median : 960746 Median :0.00000
## Mean :23 Mean :1046965 Mean :0.06993
## 3rd Qu.:34 3rd Qu.:1420159 3rd Qu.:0.00000
## Max. :45 Max. :3818687 Max. :1.00000
## Temperature Fuel_Price CPI Unemployment
## Min. : -2.06 Min. :2.472 Min. :126.1 Min. : 3.879
## 1st Qu.: 47.46 1st Qu.:2.933 1st Qu.:131.7 1st Qu.: 6.891
## Median : 62.67 Median :3.445 Median :182.6 Median : 7.874
## Mean : 60.66 Mean :3.359 Mean :171.6 Mean : 7.999
## 3rd Qu.: 74.94 3rd Qu.:3.735 3rd Qu.:212.7 3rd Qu.: 8.622
## Max. :100.14 Max. :4.468 Max. :227.2 Max. :14.313
## Success
## Min. :0.0000
## 1st Qu.:0.0000
## Median :0.0000
## Mean :0.4469
## 3rd Qu.:1.0000
## Max. :1.0000
# 3. Διαχωρισμός σε train και test set (65% - 35%)
set.seed(946)
# Χωρίζω με βάση τη νέα μεταβλητή (Success)
split <- sample.split(Walmart$Success, SplitRatio = 0.65)
# Δημιουργία των sets
train <- subset(Walmart, split == TRUE)
test <- subset(Walmart, split == FALSE)
# Καταγραφή των καταχωρήσεων σε κάθε set
nrow(train)## [1] 4182
## [1] 2253
# 1. Δημιουργία του μοντέλου στο train set (WalmartModel)
WalmartModel <- glm(Success ~ Holiday_Flag + Temperature + Fuel_Price + CPI + Unemployment,
data = train,
family = "binomial")
# 2. Εμφάνιση των αποτελεσμάτων του μοντέλου (εδώ θα δεις τα αστεράκια!)
summary(WalmartModel)##
## Call:
## glm(formula = Success ~ Holiday_Flag + Temperature + Fuel_Price +
## CPI + Unemployment, family = "binomial", data = train)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.5518910 0.3571880 1.545 0.1223
## Holiday_Flag 0.2293118 0.1235963 1.855 0.0635 .
## Temperature 0.0007519 0.0017985 0.418 0.6759
## Fuel_Price 0.0300000 0.0706214 0.425 0.6710
## CPI -0.0020042 0.0008701 -2.303 0.0213 *
## Unemployment -0.0733237 0.0181751 -4.034 5.48e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 5750.3 on 4181 degrees of freedom
## Residual deviance: 5728.4 on 4176 degrees of freedom
## AIC: 5740.4
##
## Number of Fisher Scoring iterations: 4
Με βάση τα αποτελέσματα του μοντέλου λογιστικής παλινδρόμησης στο train set, η μεταβλητή Unemployment (Ανεργία) παρουσιάζει p-value = 5.48e-05 (**), γεγονός που υποδηλώνει ισχυρή στατιστικά σημαντική συσχέτιση σε επίπεδο σημαντικότητας μικρότερο του 0.001, με αρνητική επίδραση στην πιθανότητα επιτυχίας.
Η μεταβλητή CPI (Δείκτης Τιμών Καταναλωτή) έχει p-value = 0.0213 (), άρα είναι στατιστικά σημαντική σε επίπεδο μικρότερο του 0.05 και παρουσιάζει επίσης αρνητική επίδραση. Η μεταβλητή Holiday_Flag (Αργίες) εμφανίζει p-value = 0.0635 (.), γεγονός που δείχνει οριακά στατιστικά σημαντική συσχέτιση σε επίπεδο μικρότερο του 0.1, με θετική επίδραση στην πιθανότητα επιτυχίας.
Αντίθετα, η μεταβλητή Temperature έχει p-value = 0.6759 και δεν είναι στατιστικά σημαντική, ενώ η μεταβλητή Fuel_Price με p-value = 0.6710 επίσης δεν παρουσιάζει στατιστικά σημαντική επίδραση στο μοντέλο.
Οι μεταβλητές με ισχυρή συσχέτιση με την εξαρτημένη μεταβλητή είναι η Unemployment (πολύ ισχυρή) και η CPI (στατιστικά σημαντική), ενώ η Holiday_Flag παρουσιάζει μόνο οριακή συσχέτιση. Οι μεταβλητές Temperature και Fuel_Price δεν επηρεάζουν στατιστικά σημαντικά το μοντέλο.
## 2 4 5 8 10 12
## 0.4672612 0.4123852 0.4128120 0.4146549 0.4230813 0.4231670
Η συνάρτηση predict εφαρμόζει το μοντέλο λογιστικής παλινδρόμησης στα δεδομένα του test set και επιστρέφει, για κάθε παρατήρηση, την εκτιμώμενη πιθανότητα να ανήκει στην κατηγορία Success = 1. Οι τιμές αυτές κυμαίνονται από 0 έως 1 και δεν αποτελούν τελικές κατηγορίες, αλλά πιθανότητες που εκφράζουν το πόσο «σίγουρο» είναι το μοντέλο για την πρόβλεψή του.
Στη συγκεκριμένη περίπτωση, παρατηρείται ότι οι περισσότερες τιμές κυμαίνονται περίπου μεταξύ 0.4 και 0.49, δηλαδή κοντά στο όριο του 0.5. Αυτό δείχνει ότι το μοντέλο δεν διαχωρίζει με μεγάλη βεβαιότητα τις δύο κατηγορίες (επιτυχημένη ή μη εβδομάδα), καθώς αποδίδει παρόμοιες πιθανότητες σε πολλές παρατηρήσεις.
# Μετατροπή πιθανοτήτων σε κατηγορίες (threshold = 0.5)
predictClass <- ifelse(predictTest > 0.5, 1, 0)
# Confusion Matrix
table(test$Success, predictClass)## predictClass
## 0 1
## 0 1162 84
## 1 882 125
## [1] 0.5712383
# Sensitivity (Recall για Success = 1)
sensitivity <- sum(predictClass == 1 & test$Success == 1) / sum(test$Success == 1)
sensitivity## [1] 0.1241311
# Specificity (για Success = 0)
specificity <- sum(predictClass == 0 & test$Success == 0) / sum(test$Success == 0)
specificity## [1] 0.9325843
# Baseline accuracy (πάντα προβλέπουμε την πιο συχνή κλάση)
baseline <- max(mean(test$Success == 1), mean(test$Success == 0))
baseline## [1] 0.5530404
Για την αξιολόγηση του μοντέλου δημιουργήθηκε confusion matrix με κατώφλι 0.5, μετατρέποντας τις πιθανότητες σε δυαδικές προβλέψεις. Τα αποτελέσματα δείχνουν ότι το μοντέλο ταξινομεί σωστά μεγάλο αριθμό μη επιτυχημένων εβδομάδων (1162), ενώ εντοπίζει σωστά πολύ μικρό αριθμό επιτυχημένων εβδομάδων (125). Αντίθετα, παρατηρείται μεγάλος αριθμός σφαλμάτων όπου επιτυχημένες εβδομάδες προβλέπονται ως μη επιτυχημένες (882 περιπτώσεις).
Η συνολική ακρίβεια (accuracy) του μοντέλου είναι 57.1%, ενώ η ακρίβεια του baseline μοντέλου είναι 55.3%. Αυτό δείχνει ότι το μοντέλο βελτιώνει ελάχιστα την πρόβλεψη σε σχέση με μια απλή στρατηγική που προβλέπει πάντα την πιο συχνή κατηγορία.
Το sensitivity είναι ιδιαίτερα χαμηλό (12.4%), γεγονός που σημαίνει ότι το μοντέλο αποτυγχάνει να εντοπίσει τις περισσότερες επιτυχημένες εβδομάδες. Αντίθετα, το specificity είναι πολύ υψηλό (93.3%), δείχνοντας ότι το μοντέλο αναγνωρίζει με μεγάλη ακρίβεια τις μη επιτυχημένες εβδομάδες.
Συνολικά, το μοντέλο παρουσιάζει έντονη μεροληψία προς την κατηγορία 0 (μη επιτυχημένες εβδομάδες) και δεν καταφέρνει να διαχωρίσει αποτελεσματικά τις δύο κατηγορίες. Αυτό επιβεβαιώνει και την προηγούμενη παρατήρηση ότι οι προβλεπόμενες πιθανότητες βρίσκονται κοντά στο 0.5, γεγονός που υποδηλώνει χαμηλή διακριτική ικανότητα του μοντέλου.
# Δημιουργία ROCRpred αντικειμένου
ROCRpred <- prediction(predictTest, test$Success)
# Αφαίρεση missing values
Walmart2 <- na.omit(Walmart)
# Νέος διαχωρισμός
set.seed(946)
split2 <- sample.split(Walmart2$Success, SplitRatio = 0.65)
train2 <- subset(Walmart2, split2 == TRUE)
test2 <- subset(Walmart2, split2 == FALSE)
# Πλήθος παρατηρήσεων
nrow(train2)## [1] 4182
## [1] 2253
Για την αντιμετώπιση πιθανών ελλιπών τιμών χρησιμοποιήθηκε η εντολή na.omit, ωστόσο δεν παρατηρήθηκε αλλαγή στον αριθμό των καταχωρήσεων. Αυτό δείχνει ότι το dataset δεν περιείχε missing values ή είχε ήδη καθαριστεί προηγουμένως.
Στη συνέχεια πραγματοποιήθηκε εκ νέου διαχωρισμός σε training και test set, όπου το train2 περιλαμβάνει 4182 παρατηρήσεις και το test2 2253 παρατηρήσεις.
# Δημιουργία performance για ROC curve
ROCRperf <- performance(ROCRpred, "tpr", "fpr")
# Plot ROC curve με χρωματισμό
plot(ROCRperf, colorize = TRUE, main = "ROC Curve")## [1] 0.5456496
Για την αξιολόγηση της διακριτικής ικανότητας του μοντέλου κατασκευάστηκε η καμπύλη ROC, η οποία απεικονίζει τη σχέση μεταξύ του True Positive Rate (sensitivity) και του False Positive Rate για διαφορετικά κατώφλια ταξινόμησης. Η καμπύλη σχεδιάστηκε με χρήση color-coding για καλύτερη οπτικοποίηση.
Η τιμή του AUC υπολογίστηκε ίση με 0.5465. Η τιμή αυτή είναι αρκετά κοντά στο 0.5, γεγονός που υποδηλώνει ότι το μοντέλο έχει πολύ χαμηλή διακριτική ικανότητα και η απόδοσή του προσεγγίζει αυτή μιας τυχαίας πρόβλεψης.
Συνολικά, το αποτέλεσμα αυτό επιβεβαιώνει τα προηγούμενα ευρήματα από το confusion matrix και τις τιμές sensitivity και specificity, όπου φάνηκε ότι το μοντέλο δεν καταφέρνει να διαχωρίσει αποτελεσματικά τις επιτυχημένες από τις μη επιτυχημένες εβδομάδες. Συνεπώς, το μοντέλο κρίνεται περιορισμένης χρησιμότητας για προβλεπτικούς σκοπούς στη συγκεκριμένη μορφή του.
Στην παρούσα ενότητα εφαρμόζεται η μέθοδος CART στο ίδιο dataset της Walmart, με στόχο να προβλεφθεί αν μια εβδομάδα πωλήσεων μπορεί να χαρακτηριστεί ως επιτυχημένη ή μη επιτυχημένη. Το μοντέλο CART θα συγκριθεί με το μοντέλο λογιστικής παλινδρόμησης που εφαρμόστηκε προηγουμένως.
## Warning: package 'rpart' was built under R version 4.5.3
## Warning: package 'rpart.plot' was built under R version 4.5.3
# Δημιουργία της μεταβλητής Success
mean_sales <- mean(Walmart$Weekly_Sales)
Walmart$Success <- ifelse(Walmart$Weekly_Sales > mean_sales, 1, 0)
# Μετατροπή σε factor για classification
Walmart$Success <- as.factor(Walmart$Success)
# Μετατροπή Store και Holiday_Flag σε κατηγορικές μεταβλητές
Walmart$Store <- as.factor(Walmart$Store)
Walmart$Holiday_Flag <- as.factor(Walmart$Holiday_Flag)
# Έλεγχος κατανομής της εξαρτημένης μεταβλητής
table(Walmart$Success)##
## 0 1
## 3559 2876
##
## 0 1
## 0.5530692 0.4469308
# Διαχωρισμός σε train και test set
set.seed(946)
split_cart <- sample.split(Walmart$Success, SplitRatio = 0.65)
train_cart <- subset(Walmart, split_cart == TRUE)
test_cart <- subset(Walmart, split_cart == FALSE)
nrow(train_cart)## [1] 4182
## [1] 2253
cart_model<- rpart( Success ~ Store + Holiday_Flag + Temperature + Fuel_Price + CPI + Unemployment,
data = train_cart,
method = "class",
control = rpart.control(cp = 0.001, minsplit = 30, xval = 10) )
prp(cart_model)Αρχικά, το μοντέλο χωρίζει τα δεδομένα με βάση το κατάστημα και εντοπίζει ότι το Store 18 έχει διαφορετική συμπεριφορά από τα υπόλοιπα, οπότε το απομονώνει.
Στη συνέχεια, για το Store 18 χρησιμοποιεί κυρίως τον δείκτη CPI και την ανεργία για να προβλέψει αν μια εβδομάδα είναι επιτυχημένη.
Για τα υπόλοιπα καταστήματα, το μοντέλο βασίζεται κυρίως στον CPI και τη θερμοκρασία. Επιπλέον, εντοπίζει ότι τα καταστήματα 22 και 26 παρουσιάζουν διαφορετική συμπεριφορά και τα εξετάζει ξεχωριστά.
Συνολικά, το μοντέλο δείχνει ότι η επιτυχία των πωλήσεων δεν εξαρτάται από έναν μόνο παράγοντα, αλλά από συνδυασμό μεταβλητών όπως το κατάστημα, ο CPI, η θερμοκρασία και η ανεργία.
# Πρόβλεψη πιθανοτήτων με το CART
PredictROC_CART <- predict(cart_model, newdata = test_cart)
# Εμφάνιση των πρώτων προβλέψεων
head(PredictROC_CART)## 0 1
## 2 0.008240141 0.9917599
## 4 0.008240141 0.9917599
## 5 0.008240141 0.9917599
## 8 0.008240141 0.9917599
## 10 0.008240141 0.9917599
## 12 0.008240141 0.9917599
# Δημιουργία αντικειμένου prediction για ROC
pred_cart <- prediction(PredictROC_CART[, "1"], test_cart$Success)
# Δημιουργία ROC performance
perf_cart <- performance(pred_cart, "tpr", "fpr")
# Σχεδίαση ROC Curve
plot(perf_cart, main = "ROC Curve - CART Decision Tree")# Δημιουργία performance για ROC curve Logistic Regression
ROCRperf <- performance(ROCRpred, "tpr", "fpr")
# Plot ROC curve με χρωματισμό
plot(ROCRperf, colorize = TRUE, main = "ROC Curve- Logistic Regression ")Η καμπύλη ROC του μοντέλου CART βρίσκεται πολύ κοντά στην πάνω αριστερή γωνία του διαγράμματος. Αυτό δείχνει ότι το μοντέλο έχει πολύ καλή διακριτική ικανότητα, δηλαδή μπορεί να ξεχωρίσει σε μεγάλο βαθμό τις επιτυχημένες από τις μη επιτυχημένες εβδομάδες. Σε αντίθεση με τη λογιστική παλινδρόμηση, όπου η καμπύλη ROC είναι πιο κοντά στη διαγώνιο και το AUC ήταν χαμηλό, το CART φαίνεται να αποδίδει σημαντικά καλύτερα. Η μορφή της καμπύλης δείχνει ότι το μοντέλο πετυχαίνει υψηλό True Positive Rate, δηλαδή αναγνωρίζει πολλές επιτυχημένες εβδομάδες, χωρίς να αυξάνει υπερβολικά το False Positive Rate. Συνεπώς, το CART παρουσιάζει καλύτερη ικανότητα ταξινόμησης στο συγκεκριμένο dataset.
## [1] 0.9709203
Η τιμή του AUC που προκύπτει από το μοντέλο CART είναι υψηλή. Αυτό δείχνει ότι το μοντέλο έχει πολύ καλή διακριτική ικανότητα, δηλαδή μπορεί να ξεχωρίσει αποτελεσματικά τις επιτυχημένες από τις μη επιτυχημένες εβδομάδες. Επομένως, σε σχέση με τη λογιστική παλινδρόμηση, το CART φαίνεται να αποδίδει καλύτερα στο συγκεκριμένο dataset.
Στην παρούσα εργασία χρησιμοποιήθηκε το dataset της Walmart με σκοπό
την πρόβλεψη του αν μια εβδομάδα πωλήσεων μπορεί να χαρακτηριστεί ως
επιτυχημένη ή μη επιτυχημένη. Για τον σκοπό αυτό δημιουργήθηκε η
μεταβλητή Success, η οποία παίρνει την τιμή 1 όταν οι
εβδομαδιαίες πωλήσεις ξεπερνούν τον γενικό μέσο όρο και την τιμή 0 όταν
βρίσκονται κάτω από αυτόν.
Αρχικά εφαρμόστηκε μοντέλο Logistic Regression. Τα αποτελέσματα έδειξαν ότι η λογιστική παλινδρόμηση είχε περιορισμένη προβλεπτική ικανότητα. Παρότι το μοντέλο αναγνώριζε αρκετά καλά τις μη επιτυχημένες εβδομάδες, δυσκολευόταν να εντοπίσει τις επιτυχημένες εβδομάδες. Αυτό φάνηκε από το χαμηλό sensitivity και από την τιμή AUC, η οποία ήταν κοντά στο 0.5. Συνεπώς, το μοντέλο Logistic Regression δεν κατάφερε να διαχωρίσει αποτελεσματικά τις δύο κατηγορίες.
Στη συνέχεια εφαρμόστηκε μοντέλο δέντρου απόφασης με τη μέθοδο CART.
Το CART χρησιμοποίησε κυρίως τις μεταβλητές Store,
CPI, Temperature και Unemployment
για να δημιουργήσει τους διαχωρισμούς του. Αυτό δείχνει ότι η επιτυχία
των εβδομαδιαίων πωλήσεων δεν εξαρτάται από έναν μόνο παράγοντα, αλλά
από συνδυασμό χαρακτηριστικών που σχετίζονται τόσο με το κάθε κατάστημα
όσο και με οικονομικούς και περιβαλλοντικούς δείκτες.
Σε σύγκριση με τη λογιστική παλινδρόμηση, το CART παρουσίασε καλύτερη διακριτική ικανότητα. Η καμπύλη ROC του CART βρέθηκε πιο κοντά στην πάνω αριστερή γωνία και η τιμή AUC ήταν υψηλή, γεγονός που δείχνει ότι το μοντέλο μπορεί να ξεχωρίσει αποτελεσματικά τις επιτυχημένες από τις μη επιτυχημένες εβδομάδες. Επιπλέον, το CART είναι πιο εύκολα ερμηνεύσιμο, καθώς παρουσιάζει τη διαδικασία πρόβλεψης μέσα από απλούς κανόνες τύπου “αν-τότε”.
Συνολικά, το μοντέλο CART αποδείχθηκε πιο κατάλληλο για το συγκεκριμένο case study σε σχέση με τη λογιστική παλινδρόμηση. Η λογιστική παλινδρόμηση προσέφερε μια βασική γραμμική προσέγγιση, όμως το CART μπόρεσε να εντοπίσει πιο σύνθετα μοτίβα στα δεδομένα και να προσφέρει καλύτερη ταξινόμηση. Επομένως, για το συγκεκριμένο dataset της Walmart, το δέντρο απόφασης αποτελεί πιο αποτελεσματική και πιο ερμηνεύσιμη μέθοδο πρόβλεψης.