============================================================

LAB 010 — Random Forests & Gradient Boosting

Dataset: Breast Cancer (Wisconsin)

Στόχος: Πρόβλεψη κακοήθειας από κυτταρολογικά χαρακτηριστικά

============================================================

ΜΕΡΟΣ Α — Baseline με Random Forest

Stratified Split

Χρησιμοποιούμε στρωματοποιημένη δειγματοληψία για να διατηρήσουμε την αναλογία των κλάσεων (περίπου 65/35) και στα δύο σύνολα.

train_idx <- createDataPartition(bc$Class, p = 0.7, list = FALSE)
train_set <- bc[train_idx, ]
test_set  <- bc[-train_idx, ]

Εκπαίδευση & Αξιολόγηση RF

Εκπαιδεύουμε ένα “δάσος” 500 δέντρων. Η τυχαιοποίηση των χαρακτηριστικών σε κάθε split βοηθά στην αποσυσχέτιση των δέντρων και τη μείωση του variance.

rf_model <- randomForest(Class ~ ., data = train_set, ntree = 500, importance = TRUE)

# --- TODO 3: Αξιολόγηση Μοντέλου ---

# 1. Παραγωγή Προβλέψεων (Classes & Probabilities)
rf_pred <- predict(rf_model, test_set) # Επιστρέφει "benign" ή "malignant"
rf_prob <- predict(rf_model, test_set, type = "prob")[, "malignant"] # Πιθανότητα για κακοήθεια

# 2. Confusion Matrix (Accuracy, Sensitivity)
# Ορίζουμε ως positive = "malignant" γιατί αυτό μας ενδιαφέρει να βρούμε
rf_cm <- confusionMatrix(rf_pred, test_set$Class, positive = "malignant")
print(rf_cm)
## Confusion Matrix and Statistics
## 
##            Reference
## Prediction  benign malignant
##   benign       131         2
##   malignant      2        69
##                                           
##                Accuracy : 0.9804          
##                  95% CI : (0.9506, 0.9946)
##     No Information Rate : 0.652           
##     P-Value [Acc > NIR] : <2e-16          
##                                           
##                   Kappa : 0.9568          
##                                           
##  Mcnemar's Test P-Value : 1               
##                                           
##             Sensitivity : 0.9718          
##             Specificity : 0.9850          
##          Pos Pred Value : 0.9718          
##          Neg Pred Value : 0.9850          
##              Prevalence : 0.3480          
##          Detection Rate : 0.3382          
##    Detection Prevalence : 0.3480          
##       Balanced Accuracy : 0.9784          
##                                           
##        'Positive' Class : malignant       
## 
# 3. Υπολογισμός AUC (Area Under the Curve)
rf_roc <- roc(test_set$Class, rf_prob, levels = c("benign", "malignant"))
## Setting direction: controls < cases
cat("AUC score:", rf_roc$auc, "\n")
## AUC score: 0.9981997
  • Accuracy (Ακρίβεια): Είναι το ποσοστό των σωστών προβλέψεων επί του συνόλου.

  • Sensitivity (Ευαισθησία): Είναι η ικανότητα του μοντέλου να βρίσκει τους πραγματικά ασθενείς (Malignant).

  • AUC (Area Under the Curve): Μετράει πόσο καλά το μοντέλο διαχωρίζει τις δύο κλάσεις σε όλα τα πιθανά επίπεδα πιθανότητας.

    1.0: Τέλειο μοντέλο.

    0.5: Το μοντέλο μαντεύει στην τύχη.

    0.99: Εξαιρετικός διαχωρισμός.

Variable Importance plot

# --- TODO 4: Variable Importance ---

# Εμφάνιση του γραφήματος σπουδαιότητας
varImpPlot(rf_model, 
           main = "Σπουδαιότητα Μεταβλητών - Διάγνωση Καρκίνου Μαστού",
           col = "darkblue", 
           pch = 19)

# Εναλλακτικά, εμφάνιση των τιμών σε πίνακα
importance_values <- as.data.frame(importance(rf_model))
print(importance_values[order(-importance_values$MeanDecreaseGini), ])
##                    benign malignant MeanDecreaseAccuracy MeanDecreaseGini
## Cell.size       11.976588 15.948203            19.900875        58.301150
## Cell.shape      10.011263 21.083813            22.370249        53.470968
## Bare.nuclei     19.069891 20.454103            24.973998        36.838280
## Normal.nucleoli 11.431501 11.709221            15.365021        22.570651
## Bl.cromatin      5.943408 14.599084            16.079432        13.093756
## Epith.c.size    10.025874  4.762791            11.224042        12.617603
## Cl.thickness    13.435500 21.454365            19.592274        12.492423
## Marg.adhesion    4.951799 13.487285            13.528026         6.915326
## Mitoses          4.732594  1.147448             4.710676         1.322268

Ερωτήσεις & Απαντήσεις

Ποιο Accuracy πήρατε;

Το Accuracy είναι 98.04%.

Ποια ήταν τα top-3 features σας;

Με βάση το Mean Decrease Gini, τα σημαντικότερα χαρακτηριστικά είναι συνήθως το Cell.size (Το πόσο ομοιόμορφα είναι τα μεγέθη των κυττάρων. Τα καρκινικά κύτταρα τείνουν να έχουν μεγάλες αποκλίσεις στο μέγεθος.), το Cell.shape (οι ανωμαλίες στο σχήμα είναι κλασικός δείκτης κακοήθειας) και το Bare.nuclei (Η παρουσία κυτταρικών πυρήνων που δεν περιβάλλονται από κυτταρόπλασμα).

Είναι το 97% accuracy «αρκετό» σε ιατρικό context;

Όχι απαραίτητα. Σε μια βιοψία, το κόστος ενός False Negative (να διαγνώσουμε έναν κακοήθη όγκο ως καλοήθη) είναι ασύμμετρα μεγαλύτερο από ένα False Positive. Επομένως, μας ενδιαφέρει περισσότερο η Sensitivity (Ευαισθησία). Ένα μοντέλο με 97% Accuracy αλλά χαμηλό Sensitivity είναι επικίνδυνο.

ΜΕΡΟΣ Β — Boosting & Tuning

# --- TODO 5: Προετοιμασία δεδομένων για XGBoost ---
# Το XGBoost απαιτεί αριθμητικό matrix για τα features και 0/1 για το target

# Μετατροπή των features σε matrix (αφαιρούμε τη στήλη Class)
train_x <- as.matrix(train_set[, -10])
test_x  <- as.matrix(test_set[, -10])

# Μετατροπή του target σε 0 (benign) και 1 (malignant)
train_y <- ifelse(train_set$Class == "malignant", 1, 0)
test_y  <- ifelse(test_set$Class == "malignant", 1, 0)

# Δημιουργία των ειδικών αντικειμένων DMatrix (βελτιστοποιημένα για XGBoost)
dtrain <- xgb.DMatrix(data = train_x, label = train_y)
dtest  <- xgb.DMatrix(data = test_x, label = test_y)


# --- TODO 6: Εκπαίδευση XGBoost με Early Stopping ---
params <- list(
  objective = "binary:logistic", 
  eval_metric = "auc", 
  max_depth = 4, 
  eta = 0.1
)

xgb_model <- xgb.train(
  params = params,
  data = dtrain,
  nrounds = 500,
  evals = list(val = dtest), # Παρακολούθηση της απόδοσης στο test set
  early_stopping_rounds = 20, # Σταμάτα αν δεν βελτιωθεί για 20 γύρους
  verbose = 0 # Μην γεμίσεις την οθόνη με logs
)


# --- TODO 7: Σύγκριση XGBoost vs Random Forest ---

# Προβλέψεις XGBoost (μετατροπή πιθανοτήτων σε factor)
xgb_prob <- predict(xgb_model, dtest)
xgb_pred <- factor(ifelse(xgb_prob > 0.5, "malignant", "benign"), 
                   levels = c("benign", "malignant"))

# Confusion Matrix και ROC για το XGBoost
xgb_cm  <- confusionMatrix(xgb_pred, test_set$Class, positive = "malignant")
xgb_roc <- roc(test_set$Class, xgb_prob, levels = c("benign", "malignant"))
## Setting direction: controls < cases
# Δημιουργία του Πίνακα Σύγκρισης
comparison_table <- data.frame(
  Metric = c("Accuracy", "Sensitivity", "Specificity", "AUC"),
  Random_Forest = c(rf_cm$overall["Accuracy"], 
                    rf_cm$byClass["Sensitivity"], 
                    rf_cm$byClass["Specificity"], 
                    rf_roc$auc),
  XGBoost = c(xgb_cm$overall["Accuracy"], 
              xgb_cm$byClass["Sensitivity"], 
              xgb_cm$byClass["Specificity"], 
              xgb_roc$auc)
)

# Εμφάνιση του πίνακα
knitr::kable(comparison_table, digits = 3, caption = "Σύγκριση Επιδόσεων Μοντέλων")
Σύγκριση Επιδόσεων Μοντέλων
Metric Random_Forest XGBoost
Accuracy Accuracy 0.980 0.975
Sensitivity Sensitivity 0.972 0.958
Specificity Specificity 0.985 0.985
AUC 0.998 0.997

Ερωτήσεις & Απαντήσεις

Ποιο μοντέλο νίκησε;

Στη συγκεκριμένη εκτέλεση, το Random Forest επικράτησε οριακά με Accuracy 98% έναντι 97.5% του XGBoost και AUC 0.998 έναντι 0.997. Παρόλο που το XGBoost θεωρείται συνήθως πιο ισχυρό, η καθαρότητα του dataset επέτρεψε στο Random Forest να φτάσει σε σχεδόν τέλεια αποτελέσματα.

Σας εξέπληξε κάτι;

Μας εξέπληξε το γεγονός ότι το Random Forest απέδωσε ελαφρώς καλύτερα από το XGBoost. Αυτό υποδηλώνει ότι οι σχέσεις μεταξύ των χαρακτηριστικών είναι αρκετά σαφείς και δεν χρειαζόταν η περίπλοκη σειριακή διόρθωση λαθών (boosting) για να επιτευχθεί η μέγιστη ακρίβεια. Επίσης, το AUC (0.998) είναι εντυπωσιακά κοντά στο τέλειο 1.0.

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

Με βάση τον πίνακα σύγκρισης, το Random Forest σημείωσε ελαφρώς καλύτερες επιδόσεις σε όλες τις μετρικές (Accuracy: 0.980, Sensitivity: 0.972, AUC: 0.998) σε σχέση με το XGBoost. Η ελαφρώς χαμηλότερη Sensitivity του XGBoost (95.8% έναντι 97.2% του RF) μας οδηγεί στο να προτείνουμε το Random Forest ως το κύριο εργαλείο μας, καθώς στην ογκολογία η ελαχιστοποίηση των False Negatives είναι η απόλυτη προτεραιότητα.