Head του dataset

suppressPackageStartupMessages({
  library(readr)
  library(ggplot2)
  library(cluster)
  library(dendextend)
})

dataset <- read_csv("C:/Users/vaggo/Downloads/Mall_Customers.csv")
head(dataset)
## # A tibble: 6 × 5
##   CustomerID Genre    Age `Annual Income (k$)` `Spending Score (1-100)`
##   <chr>      <chr>  <dbl>                <dbl>                    <dbl>
## 1 0001       Male      19                   15                       39
## 2 0002       Male      21                   15                       81
## 3 0003       Female    20                   16                        6
## 4 0004       Female    23                   16                       77
## 5 0005       Female    31                   17                       40
## 6 0006       Female    22                   17                       76

📝 Περιγραφή του Dataset

Το dataset περιέχει 200 πελάτες ενός εμπορικού κέντρου, με τις εξής μεταβλητές:


📊 Εξερεύνηση & Στατιστικά Δεδομένων

str(dataset)
## spc_tbl_ [200 × 5] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ CustomerID            : chr [1:200] "0001" "0002" "0003" "0004" ...
##  $ Genre                 : chr [1:200] "Male" "Male" "Female" "Female" ...
##  $ Age                   : num [1:200] 19 21 20 23 31 22 35 23 64 30 ...
##  $ Annual Income (k$)    : num [1:200] 15 15 16 16 17 17 18 18 19 19 ...
##  $ Spending Score (1-100): num [1:200] 39 81 6 77 40 76 6 94 3 72 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   CustomerID = col_character(),
##   ..   Genre = col_character(),
##   ..   Age = col_double(),
##   ..   `Annual Income (k$)` = col_double(),
##   ..   `Spending Score (1-100)` = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>
summary(dataset)
##   CustomerID           Genre                Age        Annual Income (k$)
##  Length:200         Length:200         Min.   :18.00   Min.   : 15.00    
##  Class :character   Class :character   1st Qu.:28.75   1st Qu.: 41.50    
##  Mode  :character   Mode  :character   Median :36.00   Median : 61.50    
##                                        Mean   :38.85   Mean   : 60.56    
##                                        3rd Qu.:49.00   3rd Qu.: 78.00    
##                                        Max.   :70.00   Max.   :137.00    
##  Spending Score (1-100)
##  Min.   : 1.00         
##  1st Qu.:34.75         
##  Median :50.00         
##  Mean   :50.20         
##  3rd Qu.:73.00         
##  Max.   :99.00

🔍 Παρατηρήσεις:

  • Ηλικία:
    • Εύρος: 18–70 ετών
    • Μέσος όρος: 38.85, Διάμεσος: 36 → σχεδόν συμμετρική κατανομή.
  • Εισόδημα:
    • Εύρος: 15k\(–137k\)
    • Μέσος όρος: 60.56k\(, με 1ο τεταρτημόριο **41.5k\) και 3ο 78k$
    • Ελαφρώς ασύμμετρο προς τα δεξιά (υπάρχουν “υψηλόμισθοι”).
  • Spending Score:
    • Εύρος: 1–99
    • Μέσος όρος: 50.2, Διάμεσος 50 → σχεδόν ομοιόμορφη κατανομή.

🌳 Ιεραρχική Συσταδοποίηση (Hierarchical Clustering)

Η ιεραρχική συσταδοποίηση με χρήση της μεθόδου Ward.D2 δημιούργησε ένα δενδρόγραμμα το οποίο καταλήγει σε 4 διακριτές ομάδες πελατών. Από τις μέσες τιμές που υπολογίστηκαν:

📌 Cluster 1:

Πελάτες μεγαλύτερης ηλικίας (~43)

Μέσο εισόδημα περίπου 48.6k$

Μέτριο spending score (~43.5) → Πιθανόν σταθεροί, συγκρατημένοι καταναλωτές με σταθερά εισοδήματα.

📌 Cluster 2:

Πολύ νεαροί πελάτες (~24.9 ετών)

Χαμηλό εισόδημα (~25k$)

Υψηλό spending score (~81) → Νεανικό κοινό που ξοδεύει δυσανάλογα σε σχέση με το εισόδημά του (ίσως άγαμοι ή φοιτητές).

📌 Cluster 3:

Πελάτες μεσαίας ηλικίας (~32.7)

Πολύ υψηλό εισόδημα (~86.5k$)

Πολύ υψηλό spending score (~82.1) → Το πιο ελκυστικό target group για επιχειρήσεις – καταναλωτικά ενεργοί και με οικονομική δυνατότητα.

📌 Cluster 4:

Πελάτες άνω των 41 ετών

Υψηλό εισόδημα (~88.2k$)

Πολύ χαμηλός spending score (~17.3) → Πλούσιοι αλλά συντηρητικοί καταναλωτές, ενδεχομένως χρειάζονται στοχευμένη στρατηγική προσφορών.

names(dataset) <- c("CustomerID", "Gender", "Age", "Annual_Income", "Spending_Score")
data_num <- unique(dataset[, c("Age", "Annual_Income", "Spending_Score")])
distances <- dist(data_num, method = "euclidean")
clusterCustomers <- hclust(distances, method = "ward.D2")

plot(clusterCustomers, main = "Δενδρόγραμμα Ιεραρχικής Συσταδοποίησης", labels = FALSE, hang = -1)
rect.hclust(clusterCustomers, k = 4, border = 2:5)

clusterGroups <- cutree(clusterCustomers, k = 4)

📌 Σχολιασμός:

  • Η μέθοδος Ward.D2 προσπαθεί να ελαχιστοποιήσει τη διακύμανση εντός ομάδων.
  • Η επιλογή 4 ομάδων (clusters) φαίνεται κατάλληλη, καθώς ξεχωρίζουν καθαρά στο δενδρόγραμμα.

📈 Μέσοι όροι ανά ομάδα:

cat("Μέση ηλικία ανά cluster:\n")
## Μέση ηλικία ανά cluster:
print(tapply(data_num$Age, clusterGroups, mean))
##        1        2        3        4 
## 42.82075 24.85000 32.69231 41.68571
cat("Μέσο εισόδημα ανά cluster:\n")
## Μέσο εισόδημα ανά cluster:
print(tapply(data_num$Annual_Income, clusterGroups, mean))
##        1        2        3        4 
## 48.58491 24.95000 86.53846 88.22857
cat("Μέση βαθμολογία δαπανών:\n")
## Μέση βαθμολογία δαπανών:
print(tapply(data_num$Spending_Score, clusterGroups, mean))
##        1        2        3        4 
## 43.50943 81.00000 82.12821 17.28571

🎯 K-means Clustering

🔹 K-Means Clustering – Ανάλυση Συμπεριφοράς Η μέθοδος k-means διαχώρισε τους πελάτες επίσης σε 4 ομάδες, επιβεβαιώνοντας παρόμοια δομή με την ιεραρχική συσταδοποίηση, αλλά με σαφέστερη γεωμετρική διάκριση:

Cluster 1:

Ηλικία ~25 ετών

Χαμηλό εισόδημα (~28.7k$)

Πολύ υψηλό spending score (~74.2) → Νεανική ομάδα που ξοδεύει πολύ. Ίσως ανταποκρίνονται έντονα σε διαφημίσεις ή trends.

Cluster 2:

Ηλικία ~32.7 ετών

Πολύ υψηλό εισόδημα (~86.5k$)

Πολύ υψηλό spending score (~82.1) → Premium πελάτες. Ιδανικό target group για πολυτελή προϊόντα ή υπηρεσίες.

Cluster 3:

Ηλικία ~40.4 ετών

Πολύ υψηλό εισόδημα (~87k$)

Πολύ χαμηλό spending score (~18.6) → Πελάτες με οικονομική δυνατότητα αλλά περιορισμένη αγοραστική διάθεση – ίσως συντηρητικοί ή πιο “ορθολογικοί”.

Cluster 4:

Ηλικία ~44.9 ετών

Μέσο εισόδημα (~48.7k$)

Μέση αγοραστική συμπεριφορά (~42.6)

set.seed(123)
kmeans_result <- kmeans(data_num, centers = 4, nstart = 25)

🧮 Αποτελέσματα:

cat("Πλήθος πελατών ανά cluster:\n")
## Πλήθος πελατών ανά cluster:
print(table(kmeans_result$cluster))
## 
##  1  2  3  4 
## 28 39 38 95
cat("Μέσες τιμές ανά cluster:\n")
## Μέσες τιμές ανά cluster:
print(aggregate(data_num, by = list(cluster = kmeans_result$cluster), FUN = mean))
##   cluster      Age Annual_Income Spending_Score
## 1       1 24.82143      28.71429       74.25000
## 2       2 32.69231      86.53846       82.12821
## 3       3 40.39474      87.00000       18.63158
## 4       4 44.89474      48.70526       42.63158

📌 Οπτικοποίηση: Εισόδημα vs Ηλικία

plot(data_num$Age, data_num$Annual_Income,
     col = kmeans_result$cluster, pch = 19,
     xlab = "Age", ylab = "Annual Income",
     main = "K-means Clustering (Age vs Annual Income)")

points(kmeans_result$centers[, c("Age", "Annual_Income")],
       col = 1:4, pch = 8, cex = 2, lwd = 2)


dataset$Cluster <- kmeans_result$cluster
head(dataset)
## # A tibble: 6 × 6
##   CustomerID Gender   Age Annual_Income Spending_Score Cluster
##   <chr>      <chr>  <dbl>         <dbl>          <dbl>   <int>
## 1 0001       Male      19            15             39       1
## 2 0002       Male      21            15             81       1
## 3 0003       Female    20            16              6       4
## 4 0004       Female    23            16             77       1
## 5 0005       Female    31            17             40       4
## 6 0006       Female    22            17             76       1

✅ Συμπεράσματα