1.Φόρτωση Βιβλιοθηκών

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(cluster)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(dplyr)
library(ggplot2)
library(NbClust)

1.1 Εισαγωγή αρχείου

nba <- read.csv("NBA_train.csv")

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

Το dataset περιλαμβάνει στατιστικά από ομάδες του NBA, με κάθε γραμμή να αντιπροσωπεύει την απόδοση μιας ομάδας σε μια αγωνιστική σεζόν. Στόχος είναι η ομαδοποίηση (clustering) των ομάδων με βάση αγωνιστικά χαρακτηριστικά, όπως πόντοι υπέρ και κατά, ποσοστά ευστοχίας, assists, rebounds κ.λπ.

Από το αρχικό σύνολο δεδομένων:

Αφαιρέθηκαν οι μεταβλητές Team και Playoffs, καθώς δεν συμβάλλουν ουσιαστικά στη διαδικασία clustering.

Ελέγχθηκε η ύπαρξη κενών τιμών (NA), χωρίς να εντοπιστεί πρόβλημα.

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

2.1 Φόρτωση Δεδομένων

nba <- read.csv("NBA_train.csv")

2.2 Δομή και Τύποι Μεταβλητών

2.3 Πρώτες γραμμές του dataset

head(nba)
##   SeasonEnd                Team Playoffs  W  PTS oppPTS   FG  FGA  X2P X2PA X3P
## 1      1980       Atlanta Hawks        1 50 8573   8334 3261 7027 3248 6952  13
## 2      1980      Boston Celtics        1 61 9303   8664 3617 7387 3455 6965 162
## 3      1980       Chicago Bulls        0 30 8813   9035 3362 6943 3292 6668  70
## 4      1980 Cleveland Cavaliers        0 37 9360   9332 3811 8041 3775 7854  36
## 5      1980      Denver Nuggets        0 30 8878   9240 3462 7470 3379 7215  83
## 6      1980     Detroit Pistons        0 16 8933   9609 3643 7596 3586 7377  57
##   X3PA   FT  FTA  ORB  DRB  AST STL BLK  TOV
## 1   75 2038 2645 1369 2406 1913 782 539 1495
## 2  422 1907 2449 1227 2457 2198 809 308 1539
## 3  275 2019 2592 1115 2465 2152 704 392 1684
## 4  187 1702 2205 1307 2381 2108 764 342 1370
## 5  255 1871 2539 1311 2524 2079 746 404 1533
## 6  219 1590 2149 1226 2415 1950 783 562 1742

2.4 Διάσταση του dataset

dim(nba)
## [1] 835  20

2.5 Δομή τύπων μεταβλητών

str(nba)
## 'data.frame':    835 obs. of  20 variables:
##  $ SeasonEnd: int  1980 1980 1980 1980 1980 1980 1980 1980 1980 1980 ...
##  $ Team     : chr  "Atlanta Hawks" "Boston Celtics" "Chicago Bulls" "Cleveland Cavaliers" ...
##  $ Playoffs : int  1 1 0 0 0 0 0 1 0 1 ...
##  $ W        : int  50 61 30 37 30 16 24 41 37 47 ...
##  $ PTS      : int  8573 9303 8813 9360 8878 8933 8493 9084 9119 8860 ...
##  $ oppPTS   : int  8334 8664 9035 9332 9240 9609 8853 9070 9176 8603 ...
##  $ FG       : int  3261 3617 3362 3811 3462 3643 3527 3599 3639 3582 ...
##  $ FGA      : int  7027 7387 6943 8041 7470 7596 7318 7496 7689 7489 ...
##  $ X2P      : int  3248 3455 3292 3775 3379 3586 3500 3495 3551 3557 ...
##  $ X2PA     : int  6952 6965 6668 7854 7215 7377 7197 7117 7375 7375 ...
##  $ X3P      : int  13 162 70 36 83 57 27 104 88 25 ...
##  $ X3PA     : int  75 422 275 187 255 219 121 379 314 114 ...
##  $ FT       : int  2038 1907 2019 1702 1871 1590 1412 1782 1753 1671 ...
##  $ FTA      : int  2645 2449 2592 2205 2539 2149 1914 2326 2333 2250 ...
##  $ ORB      : int  1369 1227 1115 1307 1311 1226 1155 1394 1398 1187 ...
##  $ DRB      : int  2406 2457 2465 2381 2524 2415 2437 2217 2326 2429 ...
##  $ AST      : int  1913 2198 2152 2108 2079 1950 2028 2149 2148 2123 ...
##  $ STL      : int  782 809 704 764 746 783 779 782 900 863 ...
##  $ BLK      : int  539 308 392 342 404 562 339 373 530 356 ...
##  $ TOV      : int  1495 1539 1684 1370 1533 1742 1492 1565 1517 1439 ...

2.6 Ονόματα μεταβλητών

names(nba)
##  [1] "SeasonEnd" "Team"      "Playoffs"  "W"         "PTS"       "oppPTS"   
##  [7] "FG"        "FGA"       "X2P"       "X2PA"      "X3P"       "X3PA"     
## [13] "FT"        "FTA"       "ORB"       "DRB"       "AST"       "STL"      
## [19] "BLK"       "TOV"

2.7 Έλεγχος για NA τιμές ανά στήλη

colSums(is.na(nba))
## SeasonEnd      Team  Playoffs         W       PTS    oppPTS        FG       FGA 
##         0         0         0         0         0         0         0         0 
##       X2P      X2PA       X3P      X3PA        FT       FTA       ORB       DRB 
##         0         0         0         0         0         0         0         0 
##       AST       STL       BLK       TOV 
##         0         0         0         0

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

summary(nba)
##    SeasonEnd        Team              Playoffs            W       
##  Min.   :1980   Length:835         Min.   :0.0000   Min.   :11.0  
##  1st Qu.:1989   Class :character   1st Qu.:0.0000   1st Qu.:31.0  
##  Median :1996   Mode  :character   Median :1.0000   Median :42.0  
##  Mean   :1996                      Mean   :0.5749   Mean   :41.0  
##  3rd Qu.:2005                      3rd Qu.:1.0000   3rd Qu.:50.5  
##  Max.   :2011                      Max.   :1.0000   Max.   :72.0  
##       PTS            oppPTS            FG            FGA            X2P      
##  Min.   : 6901   Min.   : 6909   Min.   :2565   Min.   :5972   Min.   :1981  
##  1st Qu.: 7934   1st Qu.: 7934   1st Qu.:2974   1st Qu.:6564   1st Qu.:2510  
##  Median : 8312   Median : 8365   Median :3150   Median :6831   Median :2718  
##  Mean   : 8370   Mean   : 8370   Mean   :3200   Mean   :6873   Mean   :2881  
##  3rd Qu.: 8784   3rd Qu.: 8768   3rd Qu.:3434   3rd Qu.:7157   3rd Qu.:3296  
##  Max.   :10371   Max.   :10723   Max.   :3980   Max.   :8868   Max.   :3954  
##       X2PA           X3P             X3PA              FT            FTA      
##  Min.   :4153   Min.   : 10.0   Min.   :  75.0   Min.   :1189   Min.   :1475  
##  1st Qu.:5269   1st Qu.:131.5   1st Qu.: 413.0   1st Qu.:1502   1st Qu.:2008  
##  Median :5706   Median :329.0   Median : 942.0   Median :1628   Median :2176  
##  Mean   :5956   Mean   :319.0   Mean   : 916.9   Mean   :1650   Mean   :2190  
##  3rd Qu.:6754   3rd Qu.:481.5   3rd Qu.:1347.5   3rd Qu.:1781   3rd Qu.:2352  
##  Max.   :7873   Max.   :841.0   Max.   :2284.0   Max.   :2388   Max.   :3051  
##       ORB              DRB            AST            STL        
##  Min.   : 639.0   Min.   :2044   Min.   :1423   Min.   : 455.0  
##  1st Qu.: 953.5   1st Qu.:2346   1st Qu.:1735   1st Qu.: 599.0  
##  Median :1055.0   Median :2433   Median :1899   Median : 658.0  
##  Mean   :1061.6   Mean   :2427   Mean   :1912   Mean   : 668.4  
##  3rd Qu.:1167.0   3rd Qu.:2516   3rd Qu.:2078   3rd Qu.: 729.0  
##  Max.   :1520.0   Max.   :2753   Max.   :2575   Max.   :1053.0  
##       BLK             TOV      
##  Min.   :204.0   Min.   : 931  
##  1st Qu.:359.0   1st Qu.:1192  
##  Median :410.0   Median :1289  
##  Mean   :419.8   Mean   :1303  
##  3rd Qu.:469.5   3rd Qu.:1396  
##  Max.   :716.0   Max.   :1873

2.9 Αφαίρεση Μη Προβλεπτικών Μεταβλητών

# Αφαίρεση Team και Playoffs, γιατί είναι ονομαστικές ή στόχος
nba_cluster <- nba %>%
  select(-Team, -Playoffs)

3.Κανονικοποίηση Δεδομένων

Πριν προχωρήσουμε σε συσταδοποίηση, κανονικοποιήσαμε τα δεδομένα ώστε όλες οι μεταβλητές να βρίσκονται στην ίδια κλίμακα. Αυτό είναι απαραίτητο γιατί οι μεταβλητές έχουν διαφορετικές μονάδες (π.χ. πόντοι, ποσοστά, αριθμός επιθέσεων), και χωρίς κανονικοποίηση κάποιες θα επηρέαζαν δυσανάλογα τα αποτελέσματα. Χρησιμοποιήσαμε τη συνάρτηση scale() για να δώσουμε σε κάθε στήλη μέσο όρο 0 και τυπική απόκλιση 1.

3.1 Κανονικοποίηση (standardization)

nba_scaled <- scale(nba_cluster)

3.2 Επιβεβαίωση Κανονικοποίησης

summary(nba_scaled)
##    SeasonEnd              W                 PTS              oppPTS         
##  Min.   :-1.76548   Min.   :-2.35464   Min.   :-2.5286   Min.   :-2.487030  
##  1st Qu.:-0.79186   1st Qu.:-0.78488   1st Qu.:-0.7508   1st Qu.:-0.742480  
##  Median :-0.03459   Median : 0.07849   Median :-0.1002   Median :-0.008918  
##  Mean   : 0.00000   Mean   : 0.00000   Mean   : 0.0000   Mean   : 0.000000  
##  3rd Qu.: 0.93903   3rd Qu.: 0.74563   3rd Qu.: 0.7130   3rd Qu.: 0.677839  
##  Max.   : 1.58812   Max.   : 2.43312   Max.   : 3.4434   Max.   : 4.004399  
##        FG               FGA               X2P               X2PA        
##  Min.   :-2.2124   Min.   :-2.2475   Min.   :-2.0182   Min.   :-2.1713  
##  1st Qu.:-0.7882   1st Qu.:-0.7726   1st Qu.:-0.8324   1st Qu.:-0.8277  
##  Median :-0.1754   Median :-0.1055   Median :-0.3661   Median :-0.3015  
##  Mean   : 0.0000   Mean   : 0.0000   Mean   : 0.0000   Mean   : 0.0000  
##  3rd Qu.: 0.8153   3rd Qu.: 0.7074   3rd Qu.: 0.9296   3rd Qu.: 0.9596  
##  Max.   : 2.7148   Max.   : 4.9739   Max.   : 2.4046   Max.   : 2.3074  
##       X3P                X3PA                FT               FTA          
##  Min.   :-1.54755   Min.   :-1.60668   Min.   :-2.3347   Min.   :-2.92425  
##  1st Qu.:-0.93913   1st Qu.:-0.96162   1st Qu.:-0.7486   1st Qu.:-0.74421  
##  Median : 0.04986   Median : 0.04795   Median :-0.1136   Median :-0.05707  
##  Mean   : 0.00000   Mean   : 0.00000   Mean   : 0.0000   Mean   : 0.00000  
##  3rd Qu.: 0.81351   3rd Qu.: 0.82183   3rd Qu.: 0.6604   3rd Qu.: 0.66279  
##  Max.   : 2.61372   Max.   : 2.60910   Max.   : 3.7315   Max.   : 3.52179  
##       ORB                DRB               AST                STL         
##  Min.   :-2.81302   Min.   :-2.9337   Min.   :-2.20708   Min.   :-2.2846  
##  1st Qu.:-0.71949   1st Qu.:-0.6188   1st Qu.:-0.79921   1st Qu.:-0.7427  
##  Median :-0.04383   Median : 0.0432   Median :-0.05917   Median :-0.1110  
##  Mean   : 0.00000   Mean   : 0.0000   Mean   : 0.00000   Mean   : 0.0000  
##  3rd Qu.: 0.70172   3rd Qu.: 0.6822   3rd Qu.: 0.74630   3rd Qu.: 0.6493  
##  Max.   : 3.05154   Max.   : 2.4921   Max.   : 2.99122   Max.   : 4.1185  
##       BLK               TOV          
##  Min.   :-2.6230   Min.   :-2.41494  
##  1st Qu.:-0.7391   1st Qu.:-0.71985  
##  Median :-0.1192   Median :-0.08987  
##  Mean   : 0.0000   Mean   : 0.00000  
##  3rd Qu.: 0.6040   3rd Qu.: 0.60181  
##  Max.   : 3.6001   Max.   : 3.70299

3.3 Οπτική Επισκόπηση με PCA

# Εκτέλεση PCA
pca_model <- prcomp(nba_scaled)

# Γραφική απεικόνιση των ομάδων με βάση τα δύο πρώτα κύρια συστατικά
fviz_pca_ind(pca_model,
             title = "PCA για Οπτική Επισκόπηση Ομάδων",
             repel = TRUE)

Οπτική Επισκόπηση των Ομάδων με PCA

Χρησιμοποιήσαμε Ανάλυση Κυρίων Συνιστωσών (PCA) για να απεικονίσουμε τις ομάδες σε δισδιάστατο χώρο, βασισμένο στις στατιστικές τους μεταβλητές. Στόχος ήταν να εντοπίσουμε αν υπάρχουν οπτικά διακριτές ομάδες/συστάδες. Αν και το διάγραμμα δείχνει μεγάλο όγκο παρατηρήσεων χωρίς ξεκάθαρα όρια, παρατηρούνται κάποια υποσυστήματα στο χώρο. Το PCA βοήθησε στην απλοποίηση της πληροφορίας και προετοίμασε τα δεδομένα για την επόμενη φάση συσταδοποίησης.

4. Υπολογισμός Ευκλείδειας Απόστασης

Υπολογίστηκε ο πίνακας Ευκλείδειων Αποστάσεων μεταξύ των ομάδων, βάσει των κανονικοποιημένων μεταβλητών.

dist_nba <- dist(nba_scaled, method = "euclidean")

4.1 Ιεραρχική Συσταδοποίηση με μέθοδο σύνδεσης ward.D2

Εφαρμόστηκε ιεραρχική συσταδοποίηση με μέθοδο σύνδεσης ward.D2, η οποία ελαχιστοποιεί τη διασπορά εντός των clusters.

hc_nba <- hclust(dist_nba, method = "ward.D2")

4.2 Οπτικοποίηση Δενδρογράμματος

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

plot(hc_nba, labels = FALSE, hang = -1, main = "Δενδροδιάγραμμα Ιεραρχικής Συσταδοποίησης")

4.3 Επιλογή Αριθμού Συστάδων

4.4 Υπολογισμός του βέλτιστου αριθμού συστάδων με βάση το Elbow Method

Χρησιμοποιήθηκε η Elbow Method για να εντοπιστεί το σημείο καμπής στο WSS (Within Sum of Squares). Η μέθοδος πρότεινε ως ιδανικό αριθμό clusters το k = 3, καθώς σε εκείνο το σημείο παρατηρείται επιβράδυνση στη μείωση του σφάλματος.

fviz_nbclust(nba_scaled, hcut, method = "wss") + 
  geom_vline(xintercept = 3, linetype = 2) +
  labs(title = "Elbow Method - Εύρεση Βέλτιστου K")

4.5 Υπολογισμός Silhouette Scores για διαφορετικά k

nba_scaled_clean <- nba_scaled[complete.cases(nba_scaled), ]

4.6 Silhouette method για εύρεση ιδανικού αριθμού clusters

Η μέθοδος Silhouette πρότεινε ως βέλτιστο αριθμό clusters το k = 2, καθώς παρατηρείται η μέγιστη μέση τιμή του δείκτη.

set.seed(123)
fviz_nbclust(nba_scaled_clean, hcut, method = "silhouette") +
  labs(subtitle = "Silhouette Method")

### 4.7 Επιλογή σημαντικών μεταβλητών και κανονικοποίηση

nba_subset <- nba %>%
  select(W, PTS, oppPTS, AST, TOV, STL, FG, DRB, X3P, FTA) %>%
  scale()

4.8 Αφαίρεση γραμμών με NA

nba_subset_clean <- nba_subset[complete.cases(nba_subset), ]

4.9 Ορισμός seed για αναπαραγωγιμότητα

set.seed(123)

4.10 Εκτέλεση NbClust με εύρος clusters από 2 έως 10

nb <- NbClust(
  data = nba_subset_clean,
  distance = "euclidean",
  min.nc = 2,
  max.nc = 10,
  method = "ward.D2"
)

## *** : The Hubert index is a graphical method of determining the number of clusters.
##                 In the plot of Hubert index, we seek a significant knee that corresponds to a 
##                 significant increase of the value of the measure i.e the significant peak in Hubert
##                 index second differences plot. 
## 

## *** : The D index is a graphical method of determining the number of clusters. 
##                 In the plot of D index, we seek a significant knee (the significant peak in Dindex
##                 second differences plot) that corresponds to a significant increase of the value of
##                 the measure. 
##  
## ******************************************************************* 
## * Among all indices:                                                
## * 11 proposed 2 as the best number of clusters 
## * 3 proposed 3 as the best number of clusters 
## * 4 proposed 4 as the best number of clusters 
## * 2 proposed 5 as the best number of clusters 
## * 1 proposed 6 as the best number of clusters 
## * 1 proposed 7 as the best number of clusters 
## * 1 proposed 9 as the best number of clusters 
## * 1 proposed 10 as the best number of clusters 
## 
##                    ***** Conclusion *****                            
##  
## * According to the majority rule, the best number of clusters is  2 
##  
##  
## *******************************************************************

Μέσω της συνάρτησης NbClust, αξιολογήθηκαν 30 διαφορετικοί δείκτες για τον καθορισμό του βέλτιστου αριθμού clusters. Η πλειοψηφία των δεικτών (11 στους 30) πρότεινε 2 συστάδες ως ιδανικές.

4.11 Εμφάνιση του πίνακα προτάσεων ανά δείκτη

table(nb$Best.nc[1, ])
## 
##  0  2  3  4  5  6  7  9 10 
##  2 11  3  4  2  1  1  1  1

5. Δημιουργία Συστάδων

5.1 Δημιουργία 3 clusters από το dendrogram

clusters <- cutree(hc_nba, k = 3)

5.2 Ενσωμάτωση των ετικετών στο αρχικό dataset

nba_clustered <- nba %>%
  mutate(Cluster = as.factor(clusters))

5.3 Οπτικοποίηση Συστάδων με fviz_cluster

# Γραφική απεικόνιση των clusters με βάση τα δύο πρώτα κύρια συστατικά
fviz_cluster(list(data = nba_scaled, cluster = clusters),
             ellipse.type = "convex",
             geom = "point",
             show.clust.cent = TRUE,
             palette = "jco",
             ggtheme = theme_minimal(),
             main = "Οπτική Απεικόνιση Συστάδων")

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

nba_clustered <- nba %>%
  mutate(cluster = clusters)
nba_clustered %>%
  group_by(cluster) %>%
  summarise(across(where(is.numeric), mean, na.rm = TRUE))
## Warning: There was 1 warning in `summarise()`.
## ℹ In argument: `across(where(is.numeric), mean, na.rm = TRUE)`.
## ℹ In group 1: `cluster = 1`.
## Caused by warning:
## ! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
## Supply arguments directly to `.fns` through an anonymous function instead.
## 
##   # Previously
##   across(a:b, mean, na.rm = TRUE)
## 
##   # Now
##   across(a:b, \(x) mean(x, na.rm = TRUE))
## # A tibble: 3 × 20
##   cluster SeasonEnd Playoffs     W   PTS oppPTS    FG   FGA   X2P  X2PA   X3P
##     <int>     <dbl>    <dbl> <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1       1     1985.    0.729  44.6 9110.  9000. 3575. 7325. 3483. 7012.  91.9
## 2       2     1989.    0.491  37.2 8607.  8720. 3379. 7129. 3215. 6619. 165. 
## 3       3     2003.    0.546  41.0 8014.  8016. 3000. 6618. 2543. 5337. 456. 
## # ℹ 9 more variables: X3PA <dbl>, FT <dbl>, FTA <dbl>, ORB <dbl>, DRB <dbl>,
## #   AST <dbl>, STL <dbl>, BLK <dbl>, TOV <dbl>

6. Boxplot βασικών

Επιλογή Μεταβλητών για Σχολιασμό Συστάδων

Για την ερμηνεία των συστάδων επιλέξαμε τις εξής 5 μεταβλητές:

PTS (Πόντοι): δείκτης επιθετικής δυναμικής κάθε ομάδας. Ο υψηλός μέσος όρος αντανακλά επιθετικά προσανατολισμένο παιχνίδι.

AST (Ασίστ): αποτυπώνει τον βαθμό ομαδικότητας – ομάδες με πολλές ασίστ βασίζονται σε συνεργασίες και σωστή κυκλοφορία της μπάλας.

TOV (Λάθη): δείκτης οργανωτικότητας. Χαμηλά λάθη συνεπάγονται σταθερότητα και προσοχή στην επίθεση.

X3P (Τρίποντα): δείχνει τον βαθμό εξάρτησης της ομάδας από το μακρινό σουτ – χρήσιμος για διάκριση «μοντέρνων» ομάδων με έμφαση στα τρίποντα.

DRB (Αμυντικά Ριμπάουντ): κλειδί για το αμυντικό προφίλ – ομάδες με πολλά DRB ελέγχουν καλύτερα τον ρυθμό του παιχνιδιού.

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

6.1 Boxplot των πόντων (PTS) ανά cluster

ggplot(nba_clustered, aes(x = factor(cluster), y = PTS, fill = factor(cluster))) +
  geom_boxplot() +
  labs(title = "Πόντοι ανά Cluster", x = "Cluster", y = "PTS") +
  theme_minimal()

Παρατηρείται ότι οι ομάδες στο Cluster 1 έχουν τη μεγαλύτερη διάμεση τιμή πόντων, ενώ οι ομάδες στο Cluster 3 σκοράρουν σημαντικά λιγότερο. Η διακύμανση στους πόντους είναι επίσης μεγαλύτερη στο πρώτο cluster, κάτι που δείχνει και διαφορετικά στυλ παιχνιδιού μέσα στο ίδιο group.

6.2 Boxplot για λάθη (TOV)

ggplot(nba_clustered, aes(x = factor(cluster), y = TOV, fill = factor(cluster))) +
  geom_boxplot() +
  labs(title = "Λάθη ανά Cluster", x = "Cluster", y = "TOV") +
  theme_minimal()

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

6.3 Boxplot για assists (AST)

ggplot(nba_clustered, aes(x = factor(cluster), y = AST, fill = factor(cluster))) +
  geom_boxplot() +
  labs(title = "Assists ανά Cluster", x = "Cluster", y = "AST") +
  theme_minimal()

Οι ομάδες του Cluster 1 είναι αυτές που κατά μέσο όρο δίνουν τις περισσότερες assists, ακολουθούμενες από το Cluster 2, με το Cluster 3 να βρίσκεται τελευταίο. Αυτό ίσως υποδηλώνει ότι στο πρώτο cluster βρίσκονται πιο ομαδικές ομάδες.

6.4 Boxplot για Τρίποντα (X3P)

ggplot(nba_clustered, aes(x = factor(cluster), y = X3P, fill = factor(cluster))) +
  geom_boxplot() +
  labs(title = "Κατανομή Τριπόντων ανά Cluster",
       x = "Cluster", y = "Τρίποντα (X3P)") +
  theme_minimal()

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

6.5 Boxplot για Αμυντικά Ριμπάουντ (DRB)

ggplot(nba_clustered, aes(x = factor(cluster), y = DRB, fill = factor(cluster))) +
  geom_boxplot() +
  labs(title = "Κατανομή Αμυντικών Ριμπάουντ ανά Cluster",
       x = "Cluster", y = "Αμυντικά Ριμπάουντ (DRB)") +
  theme_minimal()

Οι τιμές στα αμυντικά ριμπάουντ είναι σχετικά ισορροπημένες και στα τρία clusters, με το Cluster 3 να έχει ελαφρώς υψηλότερες τιμές, γεγονός που δείχνει πιθανή υπεροχή στο αμυντικό κομμάτι.

nba_with_clusters <- nba_cluster %>%
  mutate(cluster = as.factor(clusters))  # clusters = τα labels που έχουμε από hclust

7. Υπολογισμός μέσων όρων ανά cluster

Ο παρακάτω πίνακας βοηθά στην ερμηνεία των clusters, παρουσιάζοντας τον μέσο όρο κάθε μεταβλητής για κάθε ομάδα. Από την επισκόπηση των τιμών φαίνεται ότι:

Το Cluster 1 περιλαμβάνει ομάδες με τον υψηλότερο μέσο όρο σε πόντους (PTS), νίκες (W) και assists (AST), γεγονός που δείχνει υψηλή απόδοση και επιθετική δυναμική.

Το Cluster 2 μοιάζει να έχει πιο ισορροπημένο προφίλ, με ενδιάμεσες τιμές στις περισσότερες μεταβλητές.

Το Cluster 3 φαίνεται πιο σύγχρονο, με τον υψηλότερο μέσο όρο σε τρίποντα (X3P και X3PA), αλλά και λιγότερους συνολικούς πόντους, γεγονός που υποδηλώνει διαφορετικό στυλ παιχνιδιού.

Ο πίνακας αυτός ενισχύει την εικόνα που προέκυψε και από τα boxplots, προσφέροντας μια καθαρή σύγκριση των clusters βάσει των χαρακτηριστικών απόδοσης των ομάδων.

nba_with_clusters %>%
  group_by(cluster) %>%
  summarise(across(everything(), mean, .names = "mean_{.col}")) %>%
  t() %>% # για να το γυρίσεις και να φαίνεται πιο όμορφα (προαιρετικά)
  print()
##                [,1]        [,2]        [,3]       
## cluster        "1"         "2"         "3"        
## mean_SeasonEnd "1985.414"  "1988.790"  "2002.955" 
## mean_W         "44.60221"  "37.21557"  "40.95893" 
## mean_PTS       "9109.685"  "8607.389"  "8014.092" 
## mean_oppPTS    "9000.265"  "8720.234"  "8016.064" 
## mean_FG        "3574.912"  "3379.449"  "2999.754" 
## mean_FGA       "7324.608"  "7128.832"  "6617.971" 
## mean_X2P       "3483.039"  "3214.575"  "2543.413" 
## mean_X2PA      "7012.227"  "6618.719"  "5336.945" 
## mean_X3P       " 91.87293" "164.87425" "456.34086"
## mean_X3PA      " 312.3812" " 510.1138" "1281.0267"
## mean_FT        "1867.989"  "1683.617"  "1558.244" 
## mean_FTA       "2454.392"  "2237.976"  "2075.203" 
## mean_ORB       "1200.9890" "1145.1856" " 981.1047"
## mean_DRB       "2440.260"  "2359.323"  "2445.887" 
## mean_AST       "2152.061"  "2021.240"  "1785.511" 
## mean_STL       "734.6188"  "703.3473"  "631.7433" 
## mean_BLK       "466.3646"  "410.3772"  "405.7351" 
## mean_TOV       "1465.144"  "1353.934"  "1224.992"

8. Συμπεράσματα

Η ανάλυση οδήγησε στον διαχωρισμό των NBA ομάδων σε 3 διακριτές συστάδες, με βάση 30 στατιστικά απόδοσης.

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

Η οπτική απεικόνιση και η ανάλυση των μέσων όρων αποκάλυψαν ότι:

Το Cluster 1 συγκεντρώνει ομάδες με την υψηλότερη συνολική απόδοση (πόντοι, assists, νίκες).

Το Cluster 2 περιλαμβάνει ομάδες με ενδιάμεσες τιμές, πιο ισορροπημένες.

Το Cluster 3 χαρακτηρίζεται από αυξημένα τρίποντα αλλά χαμηλότερους συνολικούς πόντους.

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