Walmart Sales Analysis

Athanasios Tratselas - iis23079

1. Περιγραφή Dataset και Πηγής

2. Αιτιολόγηση Επιλογής Dataset σε σχέση με την Επιχειρηματική Αναλυτική

3. Πιθανά Επιχειρηματικά Ερωτήματα

4. Περιγραφή των μεταβλητών

Το dataset περιλαμβάνει μεταβλητές που περιγράφουν τις πωλήσεις, τα χαρακτηριστικά των καταστημάτων και παράγοντες που μπορεί να επηρεάζουν τη ζήτηση. Η μεταβλητή Store δηλώνει το κατάστημα, η Date την ημερομηνία της παρατήρησης και η Dept το τμήμα προϊόντων μέσα στο κατάστημα. Η Weekly_Sales αποτελεί τη βασική μεταβλητή του dataset, καθώς εκφράζει τις εβδομαδιαίες πωλήσεις.

Η μεταβλητή IsHoliday δείχνει αν η συγκεκριμένη εβδομάδα ανήκει σε περίοδο αργιών, ώστε να μπορεί να μελετηθεί η επίδραση της εποχικότητας στις πωλήσεις. Οι μεταβλητές MarkDown1 έως MarkDown5 αντιπροσωπεύουν διαφορετικές μορφές προωθητικών ενεργειών και βοηθούν στην αξιολόγηση της αποτελεσματικότητας των προσφορών.

Επιπλέον, το dataset περιλαμβάνει εξωτερικούς παράγοντες που ενδέχεται να επηρεάζουν την αγοραστική συμπεριφορά, όπως η Temperature (θερμοκρασία), η Fuel_Price (τιμή καυσίμων), η CPI (δείκτης τιμών καταναλωτή) και η Unemployment (ποσοστό ανεργίας). Τέλος, οι μεταβλητές Type και Size περιγράφουν βασικά χαρακτηριστικά των καταστημάτων, όπως ο τύπος και το μέγεθός τους, επιτρέποντας συγκρίσεις στην απόδοσή τους.

Περιγραφικά Στατιστικά

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

vars <- c("Weekly_Sales", "Temperature", "Fuel_Price",
          "MarkDown1", "MarkDown2", "MarkDown3",
          "MarkDown4", "MarkDown5", "Unemployment", "Size")

mode_fun <- function(x) {
  x <- na.omit(x)
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

desc_stats <- data.frame(
  Variable = vars,
  Mean = sapply(walmart[vars], function(x) mean(x, na.rm = TRUE)),
  Median = sapply(walmart[vars], function(x) median(x, na.rm = TRUE)),
  Mode = sapply(walmart[vars], mode_fun),
  SD = sapply(walmart[vars], function(x) sd(x, na.rm = TRUE)),
  Variance = sapply(walmart[vars], function(x) var(x, na.rm = TRUE)),
  Range = sapply(walmart[vars], function(x) max(x, na.rm = TRUE) - min(x, na.rm = TRUE))
)

desc_stats[, -1] <- round(desc_stats[, -1], 2)
rownames(desc_stats) <- NULL

colnames(desc_stats) <- c("Μεταβλητή", "Μέσος Όρος", "Διάμεσος", "Επικρατούσα Τιμή",
                          "Τυπική Απόκλιση", "Διακύμανση", "Εύρος")

kable(
  desc_stats,
  format = "html",
  caption = "Περιγραφικά στατιστικά βασικών ποσοτικών μεταβλητών",
  align = "c"
) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE,
    position = "center"
  )
Περιγραφικά στατιστικά βασικών ποσοτικών μεταβλητών
Μεταβλητή Μέσος Όρος Διάμεσος Επικρατούσα Τιμή Τυπική Απόκλιση Διακύμανση Εύρος
Weekly_Sales 15981.26 7612.03 10.00 22711.18 515797856.84 698088.30
Temperature 60.09 62.09 50.43 18.45 340.33 102.20
Fuel_Price 3.36 3.45 3.64 0.46 0.21 2.00
MarkDown1 2590.07 0.00 0.00 6052.39 36631375.49 88646.76
MarkDown2 879.97 0.00 0.00 5084.54 25852534.81 104785.30
MarkDown3 468.09 0.00 0.00 5528.87 30568441.65 141659.71
MarkDown4 1083.13 0.00 0.00 3894.53 15167363.50 67474.85
MarkDown5 1662.77 0.00 0.00 4207.63 17704144.50 108519.28
Unemployment 7.96 7.87 8.10 1.86 3.47 10.43
Size 136727.92 140167.00 39690.00 60980.58 3718631543.04 184747.00

Ερμηνεία Αποτελεσμάτων

Από τα περιγραφικά στατιστικά προκύπτει ότι η μεταβλητή Weekly_Sales παρουσιάζει σημαντική διασπορά, γεγονός που δείχνει μεγάλες διαφοροποιήσεις στις εβδομαδιαίες πωλήσεις μεταξύ των παρατηρήσεων. Επιπλέον, ο μέσος όρος είναι αρκετά υψηλότερος από τη διάμεσο, κάτι που υποδηλώνει ότι υπάρχουν ορισμένες πολύ υψηλές τιμές πωλήσεων που επηρεάζουν τον μέσο όρο.

Για τις μεταβλητές MarkDown1 έως MarkDown5, η διάμεσος και η επικρατούσα τιμή είναι ίσες με μηδέν, γεγονός που δείχνει ότι σε πολλές περιπτώσεις δεν εφαρμόζονταν προωθητικές ενέργειες. Αντίθετα, μεταβλητές όπως η Temperature, η Fuel_Price και η Unemployment εμφανίζουν μικρότερη μεταβλητότητα, ενώ η μεταβλητή Size δείχνει ότι υπάρχει αξιοσημείωτη διαφοροποίηση στο μέγεθος των καταστημάτων.

Διερεύνηση Συσχετίσεων

Στην ενότητα αυτή υπολογίζονται οι συντελεστές συσχέτισης Pearson μεταξύ των βασικών αριθμητικών μεταβλητών του dataset, με στόχο την αναγνώριση πιθανών σχέσεων μεταξύ τους.

corr_vars <- c("Weekly_Sales", "Temperature", "Fuel_Price",
               "MarkDown1", "MarkDown2", "MarkDown3",
               "MarkDown4", "MarkDown5", "Unemployment", "Size")

cor_matrix <- cor(walmart[corr_vars], use = "complete.obs", method = "pearson")
cor_matrix <- round(cor_matrix, 3)

kable(
  cor_matrix,
  format = "html",
  caption = "Πίνακας συσχετίσεων μεταξύ αριθμητικών μεταβλητών",
  align = "c"
) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE,
    position = "center"
  ) %>%
  scroll_box(width = "100%", height = "450px")
Πίνακας συσχετίσεων μεταξύ αριθμητικών μεταβλητών
Weekly_Sales Temperature Fuel_Price MarkDown1 MarkDown2 MarkDown3 MarkDown4 MarkDown5 Unemployment Size
Weekly_Sales 1.000 -0.002 0.000 0.047 0.021 0.039 0.037 0.050 -0.026 0.244
Temperature -0.002 1.000 0.144 -0.026 -0.180 -0.056 -0.050 -0.015 0.097 -0.058
Fuel_Price 0.000 0.144 1.000 0.297 0.029 0.019 0.167 0.215 -0.034 0.003
MarkDown1 0.047 -0.026 0.297 1.000 0.175 -0.014 0.839 0.415 -0.105 0.170
MarkDown2 0.021 -0.180 0.029 0.175 1.000 -0.006 0.113 0.132 -0.041 0.078
MarkDown3 0.039 -0.056 0.019 -0.014 -0.006 1.000 -0.012 0.042 -0.018 0.034
MarkDown4 0.037 -0.050 0.167 0.839 0.113 -0.012 1.000 0.303 -0.077 0.127
MarkDown5 0.050 -0.015 0.215 0.415 0.132 0.042 0.303 1.000 -0.120 0.153
Unemployment -0.026 0.097 -0.034 -0.105 -0.041 -0.018 -0.077 -0.120 1.000 -0.068
Size 0.244 -0.058 0.003 0.170 0.078 0.034 0.127 0.153 -0.068 1.000

Συσχέτιση Μεταβλητών με τις Εβδομαδιαίες Πωλήσεις

Για πιο στοχευμένη ανάλυση, παρουσιάζεται ξεχωριστά η συσχέτιση κάθε αριθμητικής μεταβλητής με τη μεταβλητή Weekly_Sales.

sales_corr <- sort(cor_matrix["Weekly_Sales", ], decreasing = TRUE)
sales_corr <- sales_corr[names(sales_corr) != "Weekly_Sales"]

sales_corr_df <- data.frame(
  "Μεταβλητή" = names(sales_corr),
  "Συντελεστής Συσχέτισης" = as.numeric(sales_corr),
  row.names = NULL
)

sales_corr_df[, 2] <- round(sales_corr_df[, 2], 3)

kable(
  sales_corr_df,
  format = "html",
  caption = "Συσχέτιση μεταβλητών με τις εβδομαδιαίες πωλήσεις",
  align = "c"
) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE,
    position = "center"
  )
Συσχέτιση μεταβλητών με τις εβδομαδιαίες πωλήσεις
Μεταβλητή Συντελεστής.Συσχέτισης
Size 0.244
MarkDown5 0.050
MarkDown1 0.047
MarkDown3 0.039
MarkDown4 0.037
MarkDown2 0.021
Fuel_Price 0.000
Temperature -0.002
Unemployment -0.026

Ερμηνεία Συσχετίσεων

Η ανάλυση συσχέτισης δείχνει ότι η ισχυρότερη σχέση της μεταβλητής Weekly_Sales παρατηρείται με το Size του καταστήματος, με συντελεστή 0.244, γεγονός που υποδηλώνει ασθενή θετική συσχέτιση. Αυτό σημαίνει ότι τα μεγαλύτερα καταστήματα τείνουν να εμφανίζουν υψηλότερες εβδομαδιαίες πωλήσεις, χωρίς όμως η σχέση αυτή να είναι ιδιαίτερα ισχυρή.

Οι μεταβλητές MarkDown1, MarkDown3, MarkDown4 και MarkDown5 εμφανίζουν επίσης θετική αλλά πολύ ασθενή συσχέτιση με τις πωλήσεις, γεγονός που υποδηλώνει ότι οι προωθητικές ενέργειες ενδέχεται να συνδέονται με αύξηση των πωλήσεων, αλλά η γραμμική τους σχέση με τη μεταβλητή Weekly_Sales είναι περιορισμένη. Η μεταβλητή Unemployment παρουσιάζει πολύ ασθενή αρνητική συσχέτιση με τις πωλήσεις, ενώ οι μεταβλητές Temperature και Fuel_Price εμφανίζουν σχεδόν μηδενική συσχέτιση.

Τέλος, μεταξύ των ανεξάρτητων μεταβλητών, η ισχυρότερη σχέση παρατηρείται ανάμεσα στις MarkDown1 και MarkDown4, με συντελεστή 0.839, κάτι που δείχνει πολύ ισχυρή θετική συσχέτιση. Αυτό πιθανόν σημαίνει ότι οι δύο αυτοί τύποι προωθητικών ενεργειών εφαρμόζονται συχνά ταυτόχρονα.

Δημιουργία Διαγραμμάτων

Στην ενότητα αυτή παρουσιάζονται τέσσερα βασικά διαγράμματα οπτικοποίησης δεδομένων: scatterplot, boxplot, histogram και bar chart. Για κάθε διάγραμμα παρατίθεται ο αντίστοιχος κώδικας, η οπτικοποίηση και ένας σύντομος σχολιασμός.

1. Scatterplot

library(ggplot2)
library(dplyr)
set.seed(123)

scatter_data <- walmart %>%
  slice_sample(n = min(10000, nrow(walmart)))

ggplot(scatter_data, aes(x = Size, y = Weekly_Sales)) +
  geom_point(alpha = 0.3, size = 1, color = "#0071ce") +
  geom_smooth(method = "lm", se = FALSE, color = "#ffc220", linewidth = 1.2) +
  labs(
    title = "Scatterplot: Μέγεθος Καταστήματος και Εβδομαδιαίες Πωλήσεις",
    x = "Μέγεθος Καταστήματος (Size)",
    y = "Εβδομαδιαίες Πωλήσεις (Weekly_Sales)"
  ) +
  theme_minimal()

Το scatterplot παρουσιάζει τη σχέση μεταξύ του μεγέθους του καταστήματος και των εβδομαδιαίων πωλήσεων. Παρατηρείται μια ασθενής θετική τάση, γεγονός που δείχνει ότι τα μεγαλύτερα καταστήματα τείνουν να εμφανίζουν υψηλότερες πωλήσεις. Ωστόσο, η μεγάλη διασπορά των σημείων δείχνει ότι το μέγεθος δεν αποτελεί τον μοναδικό παράγοντα που επηρεάζει τις πωλήσεις.

2. Boxplot

ggplot(
  walmart,
  aes(
    x = factor(IsHoliday, labels = c("Όχι Αργία", "Αργία")),
    y = Weekly_Sales,
    fill = factor(IsHoliday, labels = c("Όχι Αργία", "Αργία"))
  )
) +
  geom_boxplot(alpha = 0.8, outlier.alpha = 0.3) +
  labs(
    title = "Boxplot: Εβδομαδιαίες Πωλήσεις σε Εβδομάδες Αργιών και Μη Αργιών",
    x = "Κατηγορία Εβδομάδας",
    y = "Εβδομαδιαίες Πωλήσεις (Weekly_Sales)"
  ) +
  scale_fill_manual(values = c("#0071ce", "#ffc220")) +
  theme_minimal() +
  theme(legend.position = "none")

Το boxplot συγκρίνει την κατανομή των εβδομαδιαίων πωλήσεων μεταξύ εβδομάδων αργιών και μη αργιών. Μέσα από το διάγραμμα μπορεί να εξεταστεί αν οι περίοδοι αργιών συνδέονται με υψηλότερες πωλήσεις, καθώς και αν υπάρχουν ακραίες τιμές που επηρεάζουν σημαντικά την κατανομή των δεδομένων.

3. Histogram

hist_data <- walmart %>%
  group_by(Store, Date) %>%
  summarise(Total_Weekly_Sales = sum(Weekly_Sales, na.rm = TRUE), .groups = "drop")

mean_sales <- mean(hist_data$Total_Weekly_Sales, na.rm = TRUE)
median_sales <- median(hist_data$Total_Weekly_Sales, na.rm = TRUE)

ggplot(hist_data, aes(x = Total_Weekly_Sales)) +
  geom_histogram(bins = 30, fill = "#0071ce", color = "white", alpha = 0.9) +
  geom_vline(xintercept = mean_sales, color = "#ffc220", linewidth = 1.2) +
  geom_vline(xintercept = median_sales, color = "#d62828", linewidth = 1.2, linetype = "dashed") +
  labs(
    title = "Histogram: Κατανομή Συνολικών Εβδομαδιαίων Πωλήσεων ανά Κατάστημα",
    x = "Συνολικές Εβδομαδιαίες Πωλήσεις",
    y = "Συχνότητα"
  ) +
  theme_minimal()

Το histogram παρουσιάζει την κατανομή των συνολικών εβδομαδιαίων πωλήσεων ανά κατάστημα, αφού πρώτα αθροιστούν οι πωλήσεις όλων των τμημάτων για κάθε εβδομάδα. Με αυτόν τον τρόπο αποτυπώνεται πιο καθαρά το πραγματικό επίπεδο απόδοσης των καταστημάτων σε εβδομαδιαία βάση. Παρατηρείται ότι οι περισσότερες παρατηρήσεις συγκεντρώνονται σε μεσαία επίπεδα πωλήσεων, ενώ υπάρχουν και λιγότερες περιπτώσεις με πολύ υψηλές συνολικές πωλήσεις, γεγονός που δείχνει δεξιά ασυμμετρία. Η συνεχής κίτρινη γραμμή αντιστοιχεί στον μέσο όρο και η διακεκομμένη κόκκινη στη διάμεσο, διευκολύνοντας την ερμηνεία της κατανομής.

4. Bar Chart

bar_data <- walmart %>%
  group_by(Type) %>%
  summarise(Mean_Weekly_Sales = mean(Weekly_Sales, na.rm = TRUE))

ggplot(bar_data, aes(x = factor(Type), y = Mean_Weekly_Sales, fill = factor(Type))) +
  geom_col() +
  labs(
    title = "Bar Chart: Μέσος Όρος Εβδομαδιαίων Πωλήσεων ανά Τύπο Καταστήματος",
    x = "Τύπος Καταστήματος (Type)",
    y = "Μέσος Όρος Weekly_Sales"
  ) +
  scale_fill_manual(values = c("#0071ce", "#ffc220", "#004c91")) +
  theme_minimal() +
  theme(legend.position = "none")

Το bar chart παρουσιάζει τον μέσο όρο των εβδομαδιαίων πωλήσεων για κάθε τύπο καταστήματος. Με αυτόν τον τρόπο είναι δυνατή η σύγκριση της μέσης απόδοσης μεταξύ των διαφορετικών κατηγοριών καταστημάτων και ο εντοπισμός του τύπου που εμφανίζει υψηλότερες πωλήσεις.