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(rpart)
library(rpart.plot)
library(pROC)
## Type 'citation("pROC")' for a citation.
## 
## Attaching package: 'pROC'
## 
## The following objects are masked from 'package:stats':
## 
##     cov, smooth, var
library(caTools)

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

Το παρόν dataset περιλαμβάνει στατιστικά απόδοσης ομάδων του NBA, με στόχο την πρόβλεψη της συμμετοχής τους στα Playoffs μιας σεζόν. Κάθε γραμμή του dataset αντιπροσωπεύει μία ομάδα για μία συγκεκριμένη αγωνιστική περίοδο και περιέχει πληθώρα αγωνιστικών χαρακτηριστικών, όπως πόντους υπέρ και κατά, ποσοστά ευστοχίας, ριμπάουντ, ασίστ, κλεψίματα, λάθη και φάουλ.

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

Team: Όνομα ομάδας (δεν χρησιμοποιείται ως προβλεπτική μεταβλητή)

W / L: Νίκες και ήττες

PW / PL: Προβλεπόμενες νίκες/ήττες βάσει στατιστικής

MOV: Μέση διαφορά πόντων ανά παιχνίδι (Margin of Victory)

SOS: Δείκτης δυσκολίας προγράμματος (Strength of Schedule)

SRS: Ενιαίος δείκτης απόδοσης (MOV + SOS)

ORTG / DRTG / NRtg: Επιθετική, αμυντική και καθαρή αποτελεσματικότητα

PACE: Ρυθμός παιχνιδιού (κατοχές ανά 48')

FTr / X3PAr / TS.: Δείκτες σκοραρίσματος (βολές, τρίποντα, συνολική αποδοτικότητα)

TRB, AST, STL, BLK, TOV, PF: Ριμπάουντ, ασίστ, κλεψίματα, τάπες, λάθη, φάουλ

Playoffs: Εξαρτημένη μεταβλητή (1 = πρόκριση, 0 = αποκλεισμός)
# Ανάγνωση του αρχείου
nba_train <- read.csv("NBA_train.csv")

# Δημιουργία train/test set (70/30 split)
set.seed(123)  # για επαναληψιμότητα
split <- sample.split(nba_train$Playoffs, SplitRatio = 0.7)
train_set <- subset(nba_train, split == TRUE)
test_set  <- subset(nba_train, split == FALSE)

# Αφαίρεση μη προβλεπτικής μεταβλητής (Team)
train_set <- train_set %>% select(-Team)
test_set  <- test_set %>% select(-Team)

# Μετατροπή της εξαρτημένης μεταβλητής σε factor
train_set$Playoffs <- as.factor(train_set$Playoffs)
test_set$Playoffs  <- as.factor(test_set$Playoffs)

# Εξερεύνηση βασικών χαρακτηριστικών
str(train_set)
## 'data.frame':    584 obs. of  19 variables:
##  $ SeasonEnd: int  1980 1980 1980 1980 1980 1980 1980 1980 1980 1980 ...
##  $ Playoffs : Factor w/ 2 levels "0","1": 2 1 1 1 2 1 2 1 1 2 ...
##  $ W        : int  50 30 30 16 41 37 49 34 39 59 ...
##  $ PTS      : int  8573 8813 8878 8933 9084 9119 9025 8879 9344 8949 ...
##  $ oppPTS   : int  8334 9035 9240 9609 9070 9176 8702 8975 9438 8603 ...
##  $ FG       : int  3261 3362 3462 3643 3599 3639 3685 3456 3802 3523 ...
##  $ FGA      : int  7027 6943 7470 7596 7496 7689 7553 7504 7672 7156 ...
##  $ X2P      : int  3248 3292 3379 3586 3495 3551 3635 3371 3760 3496 ...
##  $ X2PA     : int  6952 6668 7215 7377 7117 7375 7398 7206 7481 7031 ...
##  $ X3P      : int  13 70 83 57 104 88 50 85 42 27 ...
##  $ X3PA     : int  75 275 255 219 379 314 155 298 191 125 ...
##  $ FT       : int  2038 2019 1871 1590 1782 1753 1605 1882 1698 1876 ...
##  $ FTA      : int  2645 2592 2539 2149 2326 2333 2102 2406 2274 2431 ...
##  $ ORB      : int  1369 1115 1311 1226 1394 1398 1245 1229 1236 1187 ...
##  $ DRB      : int  2406 2465 2524 2415 2217 2326 2396 2535 2303 2635 ...
##  $ AST      : int  1913 2152 2079 1950 2149 2148 2277 2094 2265 2226 ...
##  $ STL      : int  782 704 746 783 782 900 778 869 881 792 ...
##  $ BLK      : int  539 392 404 562 373 530 510 581 457 652 ...
##  $ TOV      : int  1495 1684 1533 1742 1565 1517 1496 1702 1613 1708 ...
dim(train_set)
## [1] 584  19
head(train_set)
##   SeasonEnd Playoffs  W  PTS oppPTS   FG  FGA  X2P X2PA X3P X3PA   FT  FTA  ORB
## 1      1980        1 50 8573   8334 3261 7027 3248 6952  13   75 2038 2645 1369
## 3      1980        0 30 8813   9035 3362 6943 3292 6668  70  275 2019 2592 1115
## 5      1980        0 30 8878   9240 3462 7470 3379 7215  83  255 1871 2539 1311
## 6      1980        0 16 8933   9609 3643 7596 3586 7377  57  219 1590 2149 1226
## 8      1980        1 41 9084   9070 3599 7496 3495 7117 104  379 1782 2326 1394
## 9      1980        0 37 9119   9176 3639 7689 3551 7375  88  314 1753 2333 1398
##    DRB  AST STL BLK  TOV
## 1 2406 1913 782 539 1495
## 3 2465 2152 704 392 1684
## 5 2524 2079 746 404 1533
## 6 2415 1950 783 562 1742
## 8 2217 2149 782 373 1565
## 9 2326 2148 900 530 1517
colSums(is.na(train_set))
## SeasonEnd  Playoffs         W       PTS    oppPTS        FG       FGA       X2P 
##         0         0         0         0         0         0         0         0 
##      X2PA       X3P      X3PA        FT       FTA       ORB       DRB       AST 
##         0         0         0         0         0         0         0         0 
##       STL       BLK       TOV 
##         0         0         0

3 Δημιουργία Μοντέλων – Λογιστική Παλινδρόμηση και CART

3.1 Επιλογή Μεταβλητών και Κατασκευή Μοντέλων

Για την κατασκευή των μοντέλων λογιστικής παλινδρόμησης και CART, επιλέχθηκε ένα σύνολο μεταβλητών που θεωρούνται σχετικές με την πρόβλεψη της πρόκρισης στα Playoffs. Η μεταβλητή W (Νίκες), παρότι παρουσιάζει ισχυρή συσχέτιση με την εξαρτημένη μεταβλητή, δεν περιλήφθηκε στη μοντελοποίηση. Ο λόγος είναι ότι η W ουσιαστικά αντανακλά άμεσα την τελική έκβαση της πρόκρισης και η χρήση της θα περιόριζε τη δυνατότητα ανάδειξης των υποκείμενων παραγόντων απόδοσης που συμβάλλουν στην επιτυχία.

Το τελικό σύνολο μεταβλητών περιλαμβάνει: - PTS (πόντοι υπέρ), - AST (ασίστ), - TOV (λάθη), - FG (εύστοχα σουτ), - oppPTS (πόντοι κατά).

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

3.2 Προετοιμασία μεταβλητών και μετονομασίες

# Προαιρετικό: αρχική λίστα για άλλες δοκιμές (δεν χρησιμοποιείται στο τελικό μοντέλο)
vars <- c("W", "PTS", "oppPTS", "FG", "FGA", "X3P", "X3PA", "FT", "FTA", 
          "ORB", "DRB", "AST", "STL", "BLK", "TOV")

# Μετονομασία των 3P / 3PA ώστε να είναι συμβατές με R
colnames(nba_train)[which(names(nba_train) == "3P")] <- "X3P"
colnames(nba_train)[which(names(nba_train) == "3PA")] <- "X3PA"
colnames(test_set)[which(names(test_set) == "3P")] <- "X3P"
colnames(test_set)[which(names(test_set) == "3PA")] <- "X3PA"

3.3 Μοντέλο Λογιστικής Παλινδρόμησης

log_model <- glm(Playoffs ~ PTS + AST + TOV + FG + oppPTS, 
                        data = nba_train, family = "binomial")
summary(log_model)
## 
## Call:
## glm(formula = Playoffs ~ PTS + AST + TOV + FG + oppPTS, family = "binomial", 
##     data = nba_train)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept) -3.6093296  2.3410071  -1.542 0.123126    
## PTS          0.0130927  0.0012244  10.693  < 2e-16 ***
## AST          0.0041483  0.0012379   3.351 0.000805 ***
## TOV         -0.0004847  0.0011697  -0.414 0.678597    
## FG          -0.0028836  0.0017426  -1.655 0.097964 .  
## oppPTS      -0.0123285  0.0010028 -12.295  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 1138.77  on 834  degrees of freedom
## Residual deviance:  365.89  on 829  degrees of freedom
## AIC: 377.89
## 
## Number of Fisher Scoring iterations: 7

3.4 Μοντέλο CART (Decision Tree)

cart_model <- rpart(Playoffs ~ PTS + AST + STL + TOV + oppPTS,
                  data = nba_train, method = "class", minbucket = 10)
prp(cart_model)

4 Αξιολόγηση Μοντέλων

Η αξιολόγηση των δύο μοντέλων πραγματοποιείται στο σύνολο ελέγχου (test_set) που δημιουργήθηκε με τυχαίο διαχωρισμό των αρχικών δεδομένων. Για κάθε μοντέλο υπολογίζονται:

  • Πίνακας σύγχυσης (confusion matrix)
  • Ακρίβεια πρόβλεψης (accuracy)
  • Καμπύλη ROC και AUC

4.1 Αξιολόγηση Μοντέλου Λογιστικής Παλινδρόμησης

# Προβλέψεις πιθανοτήτων
log_pred_probs <- predict(log_model, newdata = test_set[, vars], type = "response")

4.1.1 Μετατροπή πιθανοτήτων σε κλάσεις με κατώφλι 0.5

log_pred_class <- ifelse(log_pred_probs >= 0.5, 1, 0)

4.1.2 Πίνακας σύγχυσης

table(Πραγματικό = test_set$Playoffs, Προβλεπόμενο = log_pred_class)
##           Προβλεπόμενο
## Πραγματικό   0   1
##          0  96  11
##          1   8 136
# Confusion Matrix
conf_log <- table(Πραγματικό = test_set$Playoffs, Προβλεπόμενο = log_pred_class)

# Εξαγωγή τιμών
TP <- conf_log["1", "1"]
FP <- conf_log["0", "1"]
FN <- conf_log["1", "0"]
TN <- conf_log["0", "0"]

# Precision, Recall, F1, Specificity
precision_log <- TP / (TP + FP)
recall_log <- TP / (TP + FN)

# Εμφάνιση
precision_log; recall_log; 
## [1] 0.9251701
## [1] 0.9444444

4.1.3 Υπολογισμός ακρίβειας

mean(test_set$Playoffs == log_pred_class)
## [1] 0.9243028

4.2 Καμπύλη ROC και AUC – Λογιστική Παλινδρόμηση

library(ROCR)

4.2.1 Δημιουργία αντικειμένου για ROC

log_pred_obj <- prediction(log_pred_probs, test_set$Playoffs)
log_perf <- performance(log_pred_obj, "tpr", "fpr")

4.2.2 Σχεδίαση ROC καμπύλης

plot(log_perf, col = "blue", main = "ROC Curve – Λογιστική Παλινδρόμηση")

### Υπολογισμός AUC

as.numeric(performance(log_pred_obj, "auc")@y.values)
## [1] 0.9797508

4.3 Αξιολόγηση Μοντέλου CART

4.3.1 Προβλέψεις κλάσης

cart_pred <- predict(cart_model, newdata = test_set[, vars], type = "class")

4.3.2 Πίνακας σύγχυσης

table(Πραγματικό = test_set$Playoffs, Προβλεπόμενο = cart_pred)
##           Προβλεπόμενο
## Πραγματικό   0   1
##          0  94  13
##          1   9 135
conf_cart <- table(Πραγματικό = test_set$Playoffs, Προβλεπόμενο = cart_pred)

TP <- conf_cart["1", "1"]
FP <- conf_cart["0", "1"]
FN <- conf_cart["1", "0"]
TN <- conf_cart["0", "0"]

precision_cart <- TP / (TP + FP)
recall_cart <- TP / (TP + FN)

precision_cart; recall_cart; 
## [1] 0.9121622
## [1] 0.9375

4.3.3 Υπολογισμός ακρίβειας

mean(test_set$Playoffs == cart_pred)
## [1] 0.9123506

4.4 Καμπύλη ROC και AUC – CART

4.4.1 Προβλέψεις πιθανοτήτων για class 1

cart_probs <- predict(cart_model, newdata = test_set[, vars], type = "prob")[, 2]

4.4.2 ROC αντικείμενο και καμπύλη

cart_pred_obj <- prediction(cart_probs, test_set$Playoffs)
cart_perf <- performance(cart_pred_obj, "tpr", "fpr")

4.4.3 Σχεδίαση καμπύλης

plot(cart_perf, col = "darkgreen", main = "ROC Curve – CART")

### Υπολογισμός AUC

as.numeric(performance(cart_pred_obj, "auc")@y.values)
## [1] 0.9353583

5 Σύγκριση Μοντέλων & Συμπεράσματα

Η σύγκριση των μοντέλων πραγματοποιήθηκε στο σύνολο ελέγχου που προέκυψε από τυχαίο διαχωρισμό του αρχικού dataset. Χρησιμοποιήθηκαν τα ίδια σύνολα μεταβλητών για τη λογιστική παλινδρόμηση και το CART, προκειμένου να διασφαλιστεί η συγκρισιμότητα.

5.1 Απόδοση Μοντέλου Λογιστικής Παλινδρόμησης:

  • Ακρίβεια (Accuracy): 0.9243
  • Precision: 0.9252
  • Recall (Sensitivity): 0.9444
  • AUC (Area Under Curve): 0.9798
  • Συμπέρασμα: Το μοντέλο λογιστικής παλινδρόμησης παρουσιάζει υψηλό βαθμό ευαισθησίας και ακρίβειας, εντοπίζοντας αποτελεσματικά τις ομάδες που προκρίνονται στα Playoffs, ενώ ταυτόχρονα διατηρεί χαμηλό αριθμό ψευδώς θετικών.

5.2 Απόδοση Μοντέλου CART:

  • Ακρίβεια (Accuracy): 0.9124
  • Precision: 0.9122
  • Recall (Sensitivity): 0.9375
  • AUC: 0.9354
  • Συμπέρασμα: Το CART μοντέλο επιτυγχάνει επίσης υψηλή απόδοση, με ελαφρώς χαμηλότερους δείκτες σε σχέση με τη λογιστική παλινδρόμηση. Ωστόσο, προσφέρει το πλεονέκτημα της ερμηνευσιμότητας, μέσω της οπτικής απεικόνισης του δέντρου και της δυνατότητας εξαγωγής ξεκάθαρων ταξινομητικών κανόνων.

5.3 Συνολική Σύγκριση:

  • Το μοντέλο λογιστικής παλινδρόμησης υπερέχει ελαφρώς στους περισσότερους ποσοτικούς δείκτες (Accuracy, AUC, Recall).
  • Το CART παραμένει ανταγωνιστικό και πιο ερμηνεύσιμο, γεγονός που το καθιστά χρήσιμο σε περιβάλλοντα όπου η διαφάνεια των αποφάσεων είναι σημαντική.
  • Η επιλογή μεταξύ των δύο εξαρτάται από τις ανάγκες της εκάστοτε εφαρμογής: αν ζητείται προβλεπτική ισχύς, προτείνεται η λογιστική παλινδρόμηση· αν ζητείται απλότητα και εξήγηση των αποφάσεων, το CART αποτελεί κατάλληλη επιλογή.