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 περιέχει 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
Η ιεραρχική συσταδοποίηση με χρήση της μεθόδου 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)
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 διαχώρισε τους πελάτες επίσης σε 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
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