Titanic, Python e XGBoost: anatomia di una previsione

Una galleria tra dati, curve e alberi decisionali per esplorare la sopravvivenza sul Titanic. Allenare un modello richiede poche righe; capire che cosa abbia imparato è un’altra storia.

Il Titanic è uno dei primi incontri di chi si avvicina al machine learning: una specie di “Hello, World!” con dati mancanti, variabili categoriche e un contesto storico tragico. La competizione Titanic di Kaggle propone un compito preciso: usare le informazioni sui passeggeri per prevederne la sopravvivenza.

Nel mio notebook in Python ho affrontato il problema con pandas, Seaborn e XGBoost. Prima osserviamo i dati, poi costruiamo le variabili e infine chiediamo al modello di rendere conto delle sue previsioni.

Il manifesto passeggeri diventa un dataset

Il training set contiene 891 passeggeri di cui conosciamo l’esito. Per altri 418, nel test set, dobbiamo generare le previsioni. Abbiamo sesso, età, classe del biglietto, tariffa, cabina, porto d’imbarco e numero di familiari a bordo. Nel training set mancano però 177 età e 687 informazioni sulla cabina. Prima della fantascienza, l’inventario.

Come leggere la galleria: Survived = 0 indica i non sopravvissuti; Survived = 1 i sopravvissuti. I colori vanno letti attraverso la legenda di ogni figura. Fai clic sui grafici per aprirli ingranditi.

1. Il biglietto era già una feature

Distribuzione della classe del biglietto nei due gruppi di esito.
Distribuzione della classe del biglietto nei due gruppi di esito.

La classe è un buon punto di partenza per esplorare il rapporto tra condizioni di viaggio e sopravvivenza. Queste curve mostrano distribuzioni, non tassi di sopravvivenza per classe: un picco più alto non equivale automaticamente a una maggiore probabilità di salvarsi. La KDE smussa una variabile con soli tre valori. Nessuno viaggiava in classe 1,7: è la rappresentazione a essere continua.

2. Prima del modello, l’identikit

Distribuzione dell’età per sesso: composizione anagrafica del campione.
Distribuzione dell’età per sesso: composizione anagrafica del campione.

Prima di interpretare le differenze di esito, conviene capire chi stiamo osservando. Qui il colore distingue il sesso, non la sopravvivenza. Le curve confrontano la forma delle distribuzioni; i conteggi vanno cercati nei dati. Nelle KDE sull’età, i valori mancanti sono sostituiti con −0,5: limitare l’asse visibile a zero non li esclude dal calcolo e può influenzare la curva vicino all’origine.

3. La trama si divide in sei pannelli

Età per sesso e classe, con colore associato alla sopravvivenza.
Età per sesso e classe, con colore associato alla sopravvivenza.

Incrociare le variabili rende le domande più interessanti. Il rapporto tra età e sopravvivenza cambia tra le classi? Il quadro è simile per uomini e donne? La griglia aiuta a esplorare queste combinazioni. L’altezza delle densità non rappresenta una probabilità individuale: normalizzazione e numerosità dei gruppi contano.

4. Una regex sul manifesto passeggeri

Età per sesso, titolo estratto dal nome ed esito.
Età per sesso, titolo estratto dal nome ed esito.

Il campo Name contiene più di un nome: una semplice estrazione restituisce titoli come Mr, Mrs, Miss e Master. Normalizzo alcune varianti e raggruppo i titoli meno frequenti in Rare. È feature engineering: rendere esplicita un’informazione già presente. La regex trova il titolo; interpretarlo richiede più lavoro. Una curva elegante non aumenta magicamente un campione piccolo.

5. Ogni punto, un passeggero

Swarmplot di sesso, età ed esito, limitato ai record con età maggiore di zero.
Swarmplot di sesso, età ed esito, limitato ai record con età maggiore di zero.

Dopo le curve, torniamo ai singoli casi. Lo swarmplot sposta lateralmente i punti per ridurne la sovrapposizione: la posizione all’interno di ciascun gruppo serve alla leggibilità, non rappresenta una nuova variabile. Una tendenza lascia spazio a molte eccezioni.

6. Stessi dati, un altro spartito

Violin plot di sesso, età e sopravvivenza; le linee interne indicano i quartili.
Violin plot di sesso, età e sopravvivenza; le linee interne indicano i quartili.

Curve, punti e violini: sembra un concerto sperimentale, invece è Seaborn. La sagoma riassume la densità stimata dell’età, sui record con età maggiore di zero. Le parti larghe indicano concentrazione nella distribuzione rappresentata; non sono automaticamente conteggi assoluti. I quartili aiutano a orientarsi.

7. Tre classi, più di tre storie

Violin plot dell’età per classe ed esito, sui record con età maggiore di zero.
Violin plot dell’età per classe ed esito, sui record con età maggiore di zero.

Cambiamo raggruppamento: dal sesso alla classe. Forme e quartili fanno emergere differenze che una sola media nasconderebbe. La classe è associata anche ad altre caratteristiche del viaggio: esploriamo associazioni, senza isolare un effetto causale.

8. La distribuzione torna una folla

Swarmplot dell’età per classe ed esito, sui record con età maggiore di zero.
Swarmplot dell’età per classe ed esito, sui record con età maggiore di zero.

Stesse variabili, rappresentazione diversa. Accanto ai violini, i punti mostrano che cosa c’è dietro la sagoma: dove si addensano i casi, dove sono pochi e quanto è eterogeneo ciascun gruppo. Passiamo dalla sintesi alla granularità.

9. Coordinate di bordo, con zone d’ombra

Numero di cabina estratto, ponte codificato ed esito, escludendo il ponte sconosciuto.

Dalla cabina ricavo il ponte e una componente numerica della stanza. Questa figura non è una planimetria: il numero estratto non è una coordinata spaziale continua e DeckLE è una codifica delle categorie. La cabina manca per 687 passeggeri del training set: il sottoinsieme visualizzato non va assunto come rappresentativo dell’intero campione.

10. Chi viaggiava in quale classe?

Distribuzione dell’età suddivisa per classe del biglietto.
Distribuzione dell’età suddivisa per classe del biglietto.

Torniamo alla composizione del campione. Gruppi con età differenti richiedono cautela anche nel confronto aggregato degli esiti. Qui il colore identifica la classe, non la sopravvivenza. Vale la nota sulle età mancanti codificate con −0,5 e sul loro effetto vicino all’origine.

11. Il radar delle feature

Matrice delle correlazioni lineari tra le variabili selezionate.
Matrice delle correlazioni lineari tra le variabili selezionate.

La heatmap raccoglie molte associazioni in una sola immagine. Correlazione non significa causalità, e una correlazione lineare debole può nascondere interazioni o relazioni non lineari. Le codifiche contano: Age include il segnaposto −0,5; DeckLE assegna numeri anche al ponte sconosciuto. FamilySize deriva da SibSp + Parch + 1: alcune celle raccontano anche come abbiamo costruito i dati.

Dall’esplorazione alle feature del modello

Nel notebook preparo fasce d’età, dimensione della famiglia, informazioni sulla cabina e titoli estratti dal nome. Per alcune categorie uso il one-hot encoding, creando colonne indicatrici. Esplorare una variabile non implica usarla nel modello finale: la selezione mostrata comprende sesso, classe, familiari, ponte codificato, alcune fasce d’età e porto d’imbarco. Anche le etichette meritano attenzione: Teenager copre l’intervallo oltre i 14 e fino ai 25 anni. Il nome è comodo; gli estremi definiscono il gruppo.

Il boss di fine tutorial: la baseline

Prima di convocare XGBoost, bisogna confrontarsi con una regola elementare: prevedere la sopravvivenza per tutte le donne e la non sopravvivenza per tutti gli uomini. Nell’articolo originale questa baseline raggiunge uno score Kaggle di 0,76555, circa il 76,6%. Arriva senza tuning e ci obbliga a dimostrare quanto serva la complessità aggiunta.

XGBoost entra in scena

XGBoost implementa il gradient boosting: una sequenza di alberi i cui contributi cercano progressivamente di ridurre l’errore del modello. Nel notebook riservo il 30% dei dati etichettati alla validazione e uso l’early stopping controllando la log loss.

InsiemeXGBoostBaseline sullo stesso insieme
Addestramento: 623 passeggeri87,159%78,491%
Validazione: 268 passeggeri79,478%79,104%

Sulla validazione il vantaggio è di circa 0,37 punti percentuali: una classificazione corretta in più su 268 passeggeri. È un miglioramento piccolo, da verificare con ulteriori suddivisioni o una validazione più ampia. Lo score Kaggle della baseline riguarda un insieme diverso dalla validazione locale: la loro differenza non misura direttamente il vantaggio del modello. Il Best Score di 0,77511 mostrato su Kaggle è associato alla versione 24; i risultati qui riportati provengono dalla versione 32. Le cifre hanno una provenienza: tenerla visibile fa parte dell’analisi.

Che cosa resta dopo la galleria

Questo esperimento riunisce gestione dei dati mancanti, costruzione delle feature, visualizzazione, addestramento e verifica. I punti mostrano le osservazioni, curve e violini ne riassumono la forma, le griglie mettono in relazione i gruppi e la heatmap suggerisce associazioni da approfondire.

Il notebook completo su Kaggle contiene codice, analisi e risultati. Far girare XGBoost richiede poche righe. Capire se quelle righe hanno imparato qualcosa richiede tutte le domande che vengono prima — e qualche controllo dopo.