Το Mall Customers Segmentation κοινοποιήθηκε στο Kaggle, ένα αποθετήριο βάσεων, συνόλων δεδομένων και θεωριών πεδίων. Εντάσσεται στον χώρο της μηχανικής μάθησης και χρησιμοποιείται για σκοπούς ταξινόμησης και επίδειξης αλγορίθμων συσταδοποίησης. Παρέχει δεδομένα για 200 άτομα που επισκέπτονται ένα εμπορικό κέντρο και πιο συγκεκριμένα δημογραφικές τους πληροφορίες, ετήσιο εισόδημα και καταναλωτικές τους συνήθειες.
Η ανάλυση των δεδομένων του dataset επιτρέπει στη διοίκηση του εμπορικού κέντρου και των εσωτερικών του καταστημάτων, να κατανοήσει καλύτερα το προφίλ των πελατών τους και να πάρει στοχευμένες αποφάσεις. Μέσω της συσταδοποίησης, μπορούμε να εντοπίσουμε ομάδες πελατών με παρόμοια συμπεριφορά, γεγονός που συμβάλλει στη στοχευμένη εμπορική στρατηγική, τη βελτιστοποίηση αποθεμάτων, τη διαμόρφωση προγραμμάτων εκπτώσεων και την ενίσχυση της σχέσης με τους πιο κερδοφόρους πελάτες.
Υπάρχουν σαφή clusters πελατών;
Ποιες δημογραφικές ομάδες έχουν υψηλότερο spending score;
Υπάρχει σχέση μεταξύ εισοδήματος και δαπάνης;
Ποιες στρατηγικές μπορούν να αυξήσουν τις δαπάνες κάποιων ομάδων;
Το dataset αποτελείται από 200 εγγραφές και 5 μεταβλητές.
| Μεταβλητή | Περιγραφή | Τύπος | Εύρος | Μονάδα Μέτρησης |
|---|---|---|---|---|
| CustomerID | Μοναδικό αναγνωριστικό πελάτη | Αριθμητική | 1 - 200 |
|
| Genre | Φύλο | Κατηγορική | Female, Male |
|
| Age | Ηλικία | Αριθμητική | 18 - 70 |
|
| Annual Income | Ετήσια εισόδημα | Αριθμητική | 15 - 137 | Χιλιάδες Δολλάρια ($) |
| Spending Score | Ατομική βαθμολογία που αποδίδεται από το εμπορικό κέντρο, με βάση την καταναλωτική συμπεριφορά και τις δαπάνες | Αριθμητική | 1 - 99 |
|
Παρατηρούμε πως το dataset δεν έχει missing values, αλλά ούτε και διπλότυπες εγγραφές.
Ελλιπείς Τιμές
cat(sum(is.na(customers)))
## 0
Διπλότυπες Εγγραφές
cat(sum(duplicated(customers)))
## 0
Αφαιρούμε την κατηγορική μεταβλητή Genre και το μοναδικό αναγνωριστικό του κάθε πελάτη CustomerID.
customers_numeric <- subset(customers, select = -c(CustomerID, Genre))
| Metrics | Age | Annual Income | Spending Score |
|---|---|---|---|
| 1st Qu. | 28.75 | 41.50 | 34.75 |
| Median | 36.00 | 61.50 | 50.00 |
| Mean | 38.85 | 60.56 | 50.20 |
| 3rd Qu. | 49.00 | 78.00 | 73.00 |
| Metrics | Age | Annual Income | Spending Score |
|---|---|---|---|
| Standard Deviation | 13.96901 | 26.26472 | 25.82352 |
| Sample Variance | 195.13317 | 689.83558 | 666.85427 |
ggplot(customers, aes(Age)) +
geom_histogram(binwidth = 5, fill = "skyblue", color = "black") +
labs(title = "Κατανομή Ηλικίας Πελατών",
x = "Ηλικία",
y = "Αριθμός Πελατών")
Σχόλιο
Το παραπάνω διάγραμμα δείχνει πώς
κατανέμονται οι ηλικίες των πελατών στο dataset. Παρατηρούμε πως τα
περισσότερα datapoints βρίσκονται ηλικιακά μεταξύ των 20 και 40 ετών. Η
πληροφορία αυτή είναι χρήσιμη για την αναγνώριση του βασικού ηλικιακού
target group.
ggplot(customers, aes(x = Genre, y = AnnualIncome, fill = Genre)) +
geom_boxplot() +
labs(title = "Ετήσιο Εισόδημα ανά Φύλο",
x = "Φύλο",
y = "Ετήσιο Εισόδημα (k$)") +
theme(legend.position = "none")
Σχόλιο
Παρατηρούμε πως οι γυναίκες του dataset
έχουν ελαφρώς μεγαλύτερο μέσο ετήσιο εισόδημα από τους άνδρες, κάτι που
ωστόσο μπορεί να επηρεάζεται από την ύπαρξη outlier (μαύρη κουκίδα πάνω
από το box). Αυτή η πληροφορία είναι χρήσιμη για την στοχευμένη
δημιουργία προσφορών προσφορών.
ggplot(customers, aes(x = AnnualIncome, y = SpendingScore, color = Genre)) +
geom_point(size = 3, alpha = 0.7) +
labs(title = "Ετήσιο Εισόδημα vs Spending Score",
x = "Ετήσιο Εισόδημα (k$)",
y = "Spending Score") +
theme_minimal()
Σχόλιο
Το παραπάνω διάγραμμα δείχνει πώς
κατανέμονται οι πελάτες με βάση το ετήσιο εισόδημα και το spending score
τους, διαχωρίζοντας τα φύλα. Παρατηρείται ότι δεν υπάρχει ξεκάθαρη
γραμμική συσχέτιση, αλλά διακρίνονται ομάδες πελατών με χαμηλό ή υψηλό
spending score ανεξάρτητα από το εισόδημα.
Προκειμένου να εφαρμόσουμε clustering στο dataset μας, πρέπει να κανονικοποιήσουμε τα δεδομένα ώστε να έχουν μέσο όρο 0 και τυπική απόκλιση 1. Με τον τρόπο αυτό, και έχοντας αφαιρέσει την κατηγορική μεταβλητή Genre και το μοναδικό αναγνωριστικό CustomerID, όλες οι αριθμητικές μεταβλητές παίρνουν την ίδια κλίμακα και αυτές με μεγάλο εύρος δεν μπορούν πλέον να επηρεάσουν υπερβολικά τα αποτελέσματα.
customers_scaled <- scale(customers_numeric)
distances <- dist(customers_scaled, method = "euclidean")
clusterCustomers <- hclust(distances, method = "ward.D2")
Σχόλια
Υπολογίζουμε τις αποστάσεις μεταξύ όλων
των παρατηρήσεων στο dataset, αξιοποιώντας την ευκλείδεια απόσταση. Η
μέθοδος ward χρησιμοποιείται για να υπολογίσουμε απόσταση μεταξύ των
κέντρων των συστάδων.
plot(clusterCustomers, labels = FALSE, main = "Hierarchical Clustering Dendrogram")
Σχόλιο
Το δενδροδιάγραμμα δείχνει τη διαδικασία
συγχώνευσης των datapoints σε ομάδες. Κάθε κατακόρυφη γραμμή αντιστοιχεί
στην απόσταση συγχώνευσης δύο clusters και όσο μεγαλύτερο είναι το ύψος,
τόσο μεγαλύτερη η διαφορά μεταξύ των ομάδων που συγχωνεύονται. Θα πρέπει
να κόψουμε το δέντρο σε ένα σημείο όπου οι συνδέσεις μεταξύ ομάδων είναι
μεγάλες, ώστε να βρούμε διακριτά clusters.
Δοκιμάζοντας διάφορες τιμές του k, καταλήγουμε στο συμπέρασμα ότι η βέλτιστη τιμή είναι 5, καθώς για k > 5 πιθανόν να έχουμε overclustering, ενώ για k < 5 έχουμε άνιση κατανομή των datapoints.
clusterGroups = cutree(clusterCustomers, k=5)
plot(clusterCustomers, labels = FALSE, main = "Hierarchical Clustering Cutted Dendrogram")
rect.hclust(clusterCustomers, k = 5, border = "red")
Σχόλιο
Στο κόκκινο πλαίσιο διακρίνεται ο
διαχώρισμος των 5 clusters.
Προσθέτουμε τα cluster που δημιουργήσαμε στο αρχικό dataset, σαν κατηγορική μεταβλητή και υπολογίζουμε τον μέσο όρο κάθε μεταβλητής ανά cluster.
customers$HC_Cluster <- factor(clusterGroups)
agg_means <- aggregate(customers_numeric, by = list(Cluster = customers$HC_Cluster), mean)
| Cluster | Age | Annual Income | Spending Score |
|---|---|---|---|
| 1 | 44.31818 | 25.77273 | 20.27273 |
| 2 | 26.56061 | 47.36364 | 56.78788 |
| 3 | 56.40000 | 55.28889 | 48.35556 |
| 4 | 32.69231 | 86.53846 | 82.12821 |
| 5 | 43.89286 | 91.28571 | 16.67857 |
Σχόλια
Cluster 1: Οι πελάτες είναι σχετικά μεγαλύτερης ηλικίας (~44 ετών), με χαμηλό ετήσιο εισόδημα (~25) και χαμηλό spending score (~20). Πιθανό προφίλ: συντηρητικοί καταναλωτές με περιορισμένη αγοραστική δύναμη.
Cluster 2: Νεότεροι πελάτες (~27 ετών) με μέτριο εισόδημα (~47) και μέτριο προς υψηλό spending score (~57). Ίσως πρόκειται για νεαρούς ενήλικες που ξοδεύουν περισσότερο σε σχέση με το εισόδημά τους.
Cluster 3: Ηλικιωμένοι πελάτες (~56 ετών) με σχετικά καλό εισόδημα (~55) και μέτριο spending score (~48). Πιθανό προφίλ: οικονομικά άνετοι αλλά συγκρατημένοι στις δαπάνες.
Cluster 4: Νεότεροι πελάτες (~33 ετών) με υψηλό εισόδημα (~87) και πολύ υψηλό spending score (~82). Πρόκειται πιθανότατα για πελάτες-στόχους με υψηλή αγοραστική διάθεση.
Cluster 5: Πελάτες μέσης ηλικίας (~44 ετών) με
υψηλό εισόδημα (~91) αλλά πολύ χαμηλό spending score (~17). Πιθανό
προφίλ: άτομα με μεγάλη αγοραστική δύναμη που όμως ξοδεύουν πολύ
συγκρατημένα.
Σχόλια
Το παραπάνω διάγραμμα μας δίνει την
κατανομή των datapoints στα 5 διαφορετικά clusters που δημιουργήθηκαν.
Παρατηρούμε πως τα περισσότερα clusters διαχωρίζονται αρκετά καθαρά,
ειδικά τα Clusters 1 (κόκκινο) και 4 (μωβ) που εμφανίζουν σαφείς
περιοχές συγκέντρωσης. Τα Clusters 2 (μπλε) και 3 (πράσινο) έχουν μια
μικρή επικάλυψη, που δείχνει ότι ορισμένα σημεία έχουν παρόμοια
χαρακτηριστικά. Το Cluster 5 (πορτοκαλί) φαίνεται να καταλαμβάνει
ξεχωριστό χώρο, υποδεικνύοντας καλά διακριτό προφίλ πελατών. Η
απεικόνιση επιβεβαιώνει ότι η ανάλυση με Ward.D2 παρήγαγε σαφώς
διαχωρίσιμες ομάδες, υποστηρίζοντας την ορθότητα της επιλογής k = 5.
set.seed(123)
kmeans_model <- kmeans(customers_scaled, centers = 5, nstart = 25)
Σχόλια
Η μέθοδος k-means τοποθετεί τυχαία 5
αρχικά κέντρα και επαναλαμβάνει μετακινήσεις σημείων μεταξύ clusters
μέχρι να ελαχιστοποιηθεί η ενδοομαδική διακύμανση. Με το nstart = 25
εκτελούμε την αλγοριθμική διαδικασία από 25 διαφορετικά σημεία εκκίνησης
ώστε να βρούμε το βέλτιστο αποτέλεσμα.
Προσθέτουμε τα cluster που δημιουργήσαμε στο αρχικό dataset, σαν κατηγορική μεταβλητή και υπολογίζουμε τον μέσο όρο κάθε μεταβλητής ανά cluster.
customers$KM_Cluster <- factor(kmeans_model$cluster)
agg_means_km <- aggregate(customers_numeric, by = list(Cluster = customers$KM_Cluster), mean)
| Cluster | Age | Annual Income | Spending Score |
|---|---|---|---|
| 1 | 32.87500 | 86.10000 | 81.52500 |
| 2 | 25.18519 | 41.09259 | 62.24074 |
| 3 | 39.87179 | 86.10256 | 19.35897 |
| 4 | 55.63830 | 54.38298 | 48.85106 |
| 5 | 46.25000 | 26.75000 | 18.35000 |
Σχόλια
Cluster 1: Νέοι πελάτες (~33 ετών) με υψηλό εισόδημα (~86) και υψηλή καταναλωτική συμπεριφορά (~82). Πρόκειται πιθανότατα για πελάτες-στόχους με υψηλή αγοραστική διάθεση.
Cluster 2: Έφηβοι πελάτες (~25 ετών), με μέτριο εισόδημα (~41) και σχετικά υψηλό spending score (~62). Φαίνεται να έχουν μία τάση για κατανάλωση.
Cluster 3: Μεσήλικες πελάτες (~40 ετών), με υψηλό εισόδημα (~86), αλλά πολύ χαμηλή καταναλωτική συμπεριφορά (~19). Πρόκειται για πιο συντηρητικούς καταναλωτές.
Cluster 4: Η μεγαλύτερη ηλικιακά ομάδα (~56 ετών), με μέσο εισόδημα (~54) και μέτριο spending score (~49). Θα μπορούσαμε να τους χαρακτηρίσουμε ισορροπημένους καταναλωτές.
Cluster 5: Πελάτες μεσαίας ηλικίας (~46 ετών),
με χαμηλό εισόδημα (~27) και χαμηλό spending score (~18). Πρόκειτα για
πελάτες χαμηλής αξίας.
Σχόλια
Το παραπάνω διάγραμμα μας δίνει την
κατανομή των datapoints στα 5 διαφορετικά clusters που δημιουργήθηκαν.
Παρατηρούμε πως τα περισσότερα clusters διαχωρίζονται αρκετά καθαρά,
ειδικά τα Clusters 2 (μπλε) και 5 (πορτοκαλί) που εμφανίζουν σαφείς
περιοχές συγκέντρωσης. Τα Clusters 3 (πράσινο), 4 (μωβ) και 1(κόκκινο)
έχουν μεταξύ μια μικρή επικάλυψη, που δείχνει ότι ορισμένα σημεία έχουν
παρόμοια χαρακτηριστικά. Η απεικόνιση μας παρουσιάζει ότι η ανάλυση με
kmeans παρήγαγε καλά διαχωρίσιμες ομάδες, υποστηρίζοντας την ορθότητα
της επιλογής k = 5.
Και τα δύο μοντέλα κατηγοριοποιούν τα Clusters τους με παρόμοιο τρόπο και αυτό φαίνεται από την διάταξη των datapoints στο χώρο. Αναλυτικότερα κάθε cluster αποτελεί μια ομάδα πελατών με βάση την ηλικία τους, το ετήσιο εισόδημα τους και το spending score. Για το συγκεκριμένο dataset φαίνεται πως η μέθοδος kmeans έχει περισσότερες επικαλύψεις στα datapoints, από την ιεραρχική συσταδοποίηση.
Γενικότερα, η μέθοδος της ιεραρχικής συσταδοποίησης είναι χρήσιμη για την αρχική διερεύνηση ενός dataset, καθώς με το δενδρόγραμμα παρουσίαζει την φυσική δομή και τον διαχωρισμό των datapoints. Αντιθέτως, η μέθοδος K-means συνήθως προτιμάται στην ομαδοποίηση μεγάλου όγκου δεδομένων και στην λήψη πολύπλοκων επιχειρηματικών αποφάσεων, λόγω της ευκολίας χρήσης και της επαναληψιμότητας που προσφέρει.
Συνολικά, ο συνδυασμός των δύο τεχνικών θεωρείται καλή πρακτική, δηλαδή πρώτα συστήνεται η ιεραρχική ανάλυση για την κατανόηση του dataset και την εκτίμηση του κατάλληλου k και στη συνέχεια η εφαρμογή του K-means για πιο σταθερή και παραγωγική ομαδοποίηση.