1 Παρουσίαση του Dataset

Το παρόν σύνολο δεδομένων αφορά την κερδοφορία 30 αεροπορικών δρομολογίων από το Ντουμπάι (DXB). Περιλαμβάνει περίπου 7500 πτήσεις με 33 μεταβλητές που καλύπτουν επιχειρησιακά στοιχεία (ώρες πτήσης, πληρότητα) και οικονομικά δεδομένα (κόστος καυσίμων, συνολικά έσοδα, περιθώριο κέρδους).

Στόχος μας είναι να ομαδοποιήσουμε τις πτήσεις σε “τύπους δρομολογίων” με βάση την οικονομική τους συμπεριφορά και τα λειτουργικά τους χαρακτηριστικά.

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

Ενδεικτικά, μερικές από τις σημαντικότερες μεταβλητές του Dataset είναι:

Load_Factor: Αριθμητική μεταβλητή. Εκφράζει το ποσοστό πληρότητας, με εύρος από 0.50 έως 0.95.

Flight_Hours: Αριθμητική μεταβλητή. Διάρκεια της πτήσης σε ώρες.

Total_Revenue: Αριθμητική μεταβλητή. Το συνολικό έσοδο σε νομισματική μονάδα (π.χ. USD).

Total_Cost: Αριθμητική μεταβλητή. Το συνολικό λειτουργικό κόστος σε νομισματική μονάδα.

Profit_Margin: Αριθμητική μεταβλητή. Το κέρδος ως ποσοστό (%) των συνολικών εσόδων (αρνητικές τιμές υποδηλώνουν ζημία).

Route_Category: Κατηγορική μεταβλητή (Short Haul, Medium Haul, Long Haul).

Aircraft_Type: Κατηγορική μεταβλητή (μοντέλο αεροσκάφους).

2.1 Φόρτωση και Επιλογή Μεταβλητών

Θα χρησιμοποιήσουμε τις μεταβλητές: Load_Factor, Flight_Hours, Total_Revenue, Total_Cost, Profit_Margin και Passengers.

# Φόρτωση δεδομένων (airline_route_profitability.csv)
 train <- read.csv("airline_route_profitability.csv")

# Επιλογή αριθμητικών μεταβλητών για συσταδοποίηση
airline_numeric <- train %>% 
  select(Load_Factor, Flight_Hours, Total_Revenue, Total_Cost, Profit_Margin, Passengers)

# Κανονικοποίηση δεδομένων (Scaling)
# Απαραίτητο βήμα γιατί οι τιμές έχουν τεράστιες διαφορές στις κλίμακες (Μετατρέπουμε τις τιμές σε Z-scores, τιμές που δεν εκφράζουν πλέον δολάρια, ώρες ή ποσοστά, αλλά αποστάσεις από τον μέσο όρ)
airline_scaled <- scale(airline_numeric)

# Δείγμα των δεδομένων
head(airline_scaled)
##      Load_Factor Flight_Hours Total_Revenue Total_Cost Profit_Margin
## [1,]  -0.2560497    1.7939601     0.6250400  1.6109616    -0.3913932
## [2,]  -0.1204453   -0.4669598    -0.5016277 -0.5841106     0.4718110
## [3,]   0.5541585    0.2574126     1.4395864  0.3265956     1.3421872
## [4,]  -0.3050497   -0.6206146    -0.5749208 -0.6379980     0.3770378
## [5,]  -0.1307011   -0.9059734    -0.9778157 -1.0238324    -0.8639783
## [6,]   1.6914127   -0.9498747    -0.8797383 -0.9881074     0.2448677
##       Passengers
## [1,]  0.60335433
## [2,] -0.23620033
## [3,] -0.04332967
## [4,] -0.29292700
## [5,] -1.27997099
## [6,] -0.95095633
# Εκτελούμε το K-means νωρίς για να είναι διαθέσιμο σε όλο το έγγραφο
set.seed(160)
km_res <- kmeans(airline_scaled, centers = 4, nstart = 25)

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

Υπολογίζουμε τις αποστάσεις (Euclidean) και εφαρμόζουμε τη μέθοδο Ward.D2 για να δημιουργήσουμε συμπαγείς ομάδες.

# Υπολογισμός αποστάσεων
distances <- dist(airline_scaled, method = "euclidean")

# Εκτέλεση Ιεραρχικής Συσταδοποίησης
hc_model <- hclust(distances, method = "ward.D2")

# Σχεδίαση Δενδρογράμματος
plot(hc_model, labels = FALSE, main = "Δενδρόγραμμα Πτήσεων (Hierarchical Clustering)", xlab = "Πτήσεις", sub = "")
rect.hclust(hc_model, k = 4, border = "red") # Επιλέγουμε ενδεικτικά 4 clusters

4 Λεπτομερείς Ανάλυση σε Clusters

Σύμφωνα με τη θεωρία, μπορούμε να διαιρέσουμε το δείγμα σε περισσότερα clusters (π.χ. 10) και να χρησιμοποιήσουμε εντολές όπως tapply και colMeans για βαθύτερη ανάλυση.

# Επιλέγουμε 10 clusters όπως προτείνει η θεωρία
clusterGroups = cutree(hc_model, k = 10)

# Χρήση tapply για να βρούμε το μέσο όρο κερδοφορίας και πληρότητας ανά cluster
# Το tapply είναι πολύ χρήσιμο για να δούμε το "προφίλ" κάθε ομάδας
tapply(train$Profit_Margin, clusterGroups, mean)
##           1           2           3           4           5           6 
##  -13.323488   10.817418   41.367002   -2.191982   17.062135  -11.951579 
##           7           8           9          10 
##   38.918696   33.486387   15.028569 -116.471584
tapply(train$Load_Factor, clusterGroups, mean)
##         1         2         3         4         5         6         7         8 
## 0.7235679 0.7677613 0.8510391 0.8712408 0.8788332 0.7122157 0.8967177 0.7365832 
##         9        10 
## 0.8371241 0.7210416
# Χρήση colMeans για το Cluster 1
# Παίρνουμε τη μέση τιμή κάθε μεταβλητής για τις πτήσεις της πρώτης ομάδας
cat("Μέσοι όροι μεταβλητών για το Cluster 1:\n")
## Μέσοι όροι μεταβλητών για το Cluster 1:
colMeans(subset(airline_numeric, clusterGroups == 1))
##   Load_Factor  Flight_Hours Total_Revenue    Total_Cost Profit_Margin 
##  7.235679e-01  1.503694e+01  3.836257e+05  4.194557e+05 -1.332349e+01 
##    Passengers 
##  2.524501e+02

4.1 Ανάλυση Συγκεκριμένης Πτήσης

Μπορούμε να δούμε σε ποιο cluster ανήκει μια συγκεκριμένη πτήση. Έστω ότι εξετάζουμε την πτήση στη γραμμή 259:

# Δες σε ποιο cluster ανήκει η πτήση 259
cat("Η πτήση στη γραμμή 259 ανήκει στο Cluster:", clusterGroups[259], "\n")
## Η πτήση στη γραμμή 259 ανήκει στο Cluster: 9
# Δημιουργία υποσυνόλου δεδομένων μόνο για το Cluster (9) της πτήσης 257
cluster_subset = subset(train, clusterGroups == clusterGroups[259])
cat("Πρώτα 5 δρομολόγια στο ίδιο Cluster:\n")
## Πρώτα 5 δρομολόγια στο ίδιο Cluster:
head(cluster_subset$Route, 5)
## [1] "DXB-SYD" "DXB-MEL" "DXB-SYD" "DXB-SYD" "DXB-LAX"

5 Ανάλυση και Συμπεράσματα

Προσθέτουμε την πληροφορία των clusters στο αρχικό μας dataset για να καταλάβουμε τι αντιπροσωπεύει κάθε ομάδα.

# Προσθήκη του cluster group
train$Cluster <- as.factor(km_res$cluster)

# Σύνοψη των χαρακτηριστικών ανά Cluster
cluster_profile <- train %>%
  group_by(Cluster) %>%
  summarise(
    Count = n(),
    Avg_Revenue = mean(Total_Revenue),
    Avg_Profit_Margin = mean(Profit_Margin),
    Avg_Hours = mean(Flight_Hours),
    Avg_Load = mean(Load_Factor)
  )

print(cluster_profile)
## # A tibble: 4 × 6
##   Cluster Count Avg_Revenue Avg_Profit_Margin Avg_Hours Avg_Load
##   <fct>   <int>       <dbl>             <dbl>     <dbl>    <dbl>
## 1 1        3083     173650.             19.6       3.75    0.844
## 2 2        1932      68263.            -35.3       3.11    0.724
## 3 3        1545     708548.             35.2       9.33    0.869
## 4 4        1414     431262.              1.85     13.1     0.741

6 Συσταδοποίηση K-means

Η μέθοδος K-means είναι πιο αποδοτική για μεγάλα σύνολα δεδομένων όπως το δικό μας (6.000+ εγγραφές).

set.seed(160)
# Επιλογή 4 clusters
km_res <- kmeans(airline_scaled, centers = 4, nstart = 25)

# Οπτικοποίηση των clusters
fviz_cluster(km_res, data = airline_scaled, 
             geom = "point",
             ellipse.type = "convex", 
             ggtheme = theme_minimal(),
             main = "Οπτικοποίηση Clusters (K-means)")

6.1 Σχολιασμός των 4 Clusters

Dim1 (58.7%): Αυτός ο άξονας μεταφέρει το 58.7% της πληροφορίας. Aντιπροσωπεύει το μέγεθος της πτήσης (Έσοδα, Ώρες, Επιβάτες). Όσο πιο δεξιά είναι μια τελεία, τόσο μεγαλύτερη/μακρύτερη είναι η πτήση.

Dim2 (23%): Μεταφέρει το 23% της πληροφορίας και σχετίζεται με την αποδοτικότητα (Load Factor, Profit Margin).

Cluster 2 (Πράσινο - Αριστερά): Βρίσκεται πολύ αριστερά στον Dim1. Αυτές είναι οι μικρές πτήσεις (Short-haul) με χαμηλά έσοδα. Επειδή είναι στενό και μακρόστενο, δείχνει μεγάλη ομοιομορφία.

Cluster 1 (Κόκκινο - Πάνω αριστερά): Είναι οι μεσαίες πτήσεις. Παρατήρησε ότι συνορεύει με το πράσινο, άρα κάποια δρομολόγια είναι οριακά μεταξύ μικρών και μεσαίων.

Cluster 3 (Γαλάζιο - Δεξιά): Αυτές είναι οι “ναυαρχίδες” σου (Long-haul). Είναι πολύ δεξιά στον Dim1, που σημαίνει μέγιστα έσοδα και πολλές ώρες πτήσης. Το γεγονός ότι η ομάδα είναι “πλατιά” δείχνει ότι οι μεγάλες πτήσεις έχουν μεγαλύτερη ποικιλία μεταξύ τους.

Cluster 4 (Μοβ - Κάτω): Αυτές είναι οι πτήσεις με ιδιαίτερα χαρακτηριστικά, πιθανώς αυτές που έχουν καλή απόδοση αλλά σε μεσαίες αποστάσεις.

7 Σχολιασμός Τελικών Ευρημάτων

Με βάση την ανάλυση των μέσων όρων ανά cluster, μπορούμε να ταυτοποιήσουμε τις εξής ομάδες (ενδεικτικά):

Cluster 1 (Standard Δρομολόγια): Η “ραχοκοκαλιά” της εταιρείας. Μεσαία δρομολόγια με σταθερή κερδοφορία (19.6%).

Cluster 2 (Προβληματικά Δρομολόγια): SOS. Χαμηλή πληρότητα και σημαντική ζημία (-35.3%). Χρήζουν άμεσης επαναξιολόγησης.

Cluster 3 (Ναυαρχίδες - Long Haul): Οι πιο αποδοτικές πτήσεις. Υψηλά έσοδα και μέγιστο κέρδος (35.2%).

Cluster 4 (Μακρινές Διαδρομές Χαμηλής Απόδοσης): Πολύ μεγάλες πτήσεις (13 ώρες) που “παλεύουν” με οριακό κέρδος λόγω υψηλού κόστους καυσίμων.

8 Τελικό Συμπέρασμα

Η συσταδοποίηση μας επέτρεψε να ομαδοποιήσουμε 7.500 πτήσεις σε διακριτές κατηγορίες. Η χρήση των tapply και colMeans επιβεβαίωσε ότι η πραγματική κερδοφορία εξαρτάται περισσότερο από το Load_Factor παρά από τα συνολικά έσοδα.