Passa al contenuto principale

EDA clinica

Indice


1. Le tre cose da sapere prima di guardare un grafico

Prima di lanciare un singolo plot, fissa tre numeri di riferimento sul dataset Diabetes 130-US Hospitals:

Quantita'ValoreImplicazione
Numero di righe101.766Sufficienti per LogReg/RF; XGBoost non strettamente necessario
Numero di pazienti unici (patient_nbr)~71.500~30% dei pazienti ha >=2 ricoveri
Tasso di readmitted = '<30'~11.16%Classe positiva minoritaria; AUC-PR > AUC-ROC come metrica

Senza questi tre numeri, ogni grafico e' privo di scala interpretativa.

2. Distribuzione del target (3 classi vs binaria)

df['readmitted'].value_counts(normalize=True).round(4) * 100
# NO 53.91 %
# >30 34.93 %
# <30 11.16 %

Cosa leggere:

  • La classe <30 (positiva binaria) e' al ~11%. Su 100 pazienti, ne riammettiamo 11 entro 30 giorni.
  • La classe >30 (~35%) e' la piu' insidiosa: questi pazienti sono stati riammessi, ma fuori dalla finestra HRRP. La binarizzazione li tratta come "negativi" ma clinicamente non lo sono.
  • Un classificatore costante "predici sempre 0" raggiunge 89% accuracy senza imparare nulla. Per questo l'accuracy e' inutile come metrica primaria.

3. Distribuzione demografica e disparita' nel target

E' lo step diagnostico chiave per l'audit di fairness in fase di valutazione. Calcola il tasso di readmission per sottogruppo:

df.groupby('race')['readmitted_30d'].agg(['mean', 'count'])

Pattern tipici osservati su questo dataset (Strack 2014, Tabella 4):

RaceTasso readmit 30dn
Caucasian~10.9%~76.000
AfricanAmerican~11.7%~19.000
Hispanic~9.8%~2.000
Asian~8.6%~640
Other~9.1%~1.500
Missing (NaN)~10.2%~2.300

La differenza fra Caucasian e AfricanAmerican (10.9% vs 11.7%) e' statisticamente significativa dato nn elevato, ma operativamente piccola (~0.8 percentage point). E' il base rate che dovremo confrontare con il predicted rate del modello in fase di fairness audit.

Sull'asse age la differenza e' molto piu' marcata: pazienti \geq70 anni hanno tassi quasi doppi rispetto agli under-50. Conseguenza: un modello che usa age come feature predittiva di per se' separera' bene, ma generera' alert sproporzionati sugli anziani.

4. Pattern di utilizzo sanitario pregresso

Le tre feature number_outpatient, number_emergency, number_inpatient (visite ambulatoriali, accessi in PS, ricoveri nell'anno precedente) sono fra i predittori piu' forti in letteratura (Kansagara et al. 2011).

Distribuzione tipica:

  • number_inpatient: zero per il ~70% dei pazienti, ma con coda lunga fino a 21+.
  • number_emergency: zero per il ~80%.
  • Pazienti con number_inpatient >= 3 hanno tasso di readmission >25% (vs ~9% per chi ha 0).

Implicazione per il feature engineering:

prior_healthcare_use = (
number_outpatient + 2 * number_emergency + 3 * number_inpatient
)

Pesi crescenti perche' un ricovero pregresso e' clinicamente piu' grave di un accesso al PS, che e' a sua volta piu' grave di una visita ambulatoriale.

5. Diagnosi primarie: la cardinalita' di ICD-9

Le tre colonne diag_1, diag_2, diag_3 contengono codici ICD-9 (formato XXX.YY). Caratteristiche:

  • ~700 valori unici per diag_1.
  • Code "V" e "E" (status / external causes) presenti ma rari.
  • I codici della famiglia 250.xx sono il diabete con varianti (250.83, 250.6, ecc.).

Mai usare un OneHotEncoder grezzo su diag_*: produrrebbe ~700 colonne con la maggior parte sparse, esplodendo dimensionalita' e rumore.

Soluzione: macro-grouping in 9 categorie (Strack 2014, Tabella 2):

Range ICD-9Categoria
390-459, 785Circulatory
460-519, 786Respiratory
520-579, 787Digestive
250.xxDiabetes
800-999Injury / Poisoning
710-739Musculoskeletal
580-629, 788Genitourinary
140-239Neoplasms
altroOther

Implementato in src/readmit_pipeline/icd9.py.

6. HbA1c: l'ipotesi centrale di Strack 2014

Il paper originale ha mostrato che la misurazione dell'HbA1c durante il ricovero (a prescindere dal valore) e' associata a un tasso di readmission ridotto. Razionale clinico: misurare l'HbA1c indica un'attenzione strutturata al controllo glicemico, che si traduce in piano di dimissione piu' robusto.

Distribuzione di A1Cresult:

Valore%Interpretazione
None~83%Test non eseguito
>8~8%HbA1c elevata
Norm~5%HbA1c normale
>7~4%HbA1c moderatamente elevata

Feature derivata utile: A1C_measured = (A1Cresult != 'None') come flag binario, che cattura l'effetto Strack indipendentemente dal valore esatto.

7. Pazienti con encounter multipli

n_per_patient = df.groupby('patient_nbr').size()
print((n_per_patient > 1).sum()) # ~22.000 pazienti
print(n_per_patient.max()) # ~40 ricoveri di un singolo paziente!

Implicazione metodologica fondamentale: lo split casuale e' sbagliato. Senza un group-aware split, ricoveri dello stesso paziente finirebbero sia in train sia in test. Il modello "riconosce" il paziente attraverso pattern individuali (eta', razza, prior_inpatient) e ottiene metriche over-ottimistiche che non si replicano in produzione.

Soluzione: GroupShuffleSplit per l'holdout iniziale + StratifiedGroupKFold per la cross-validation, entrambi con groups=patient_nbr. Vedi src/readmit_pipeline/splits.py.

8. Distribuzione time_in_hospital e numero di farmaci

Due feature continue informative:

  • time_in_hospital \in [1, 14]: distribuzione approssimativamente esponenziale, mediana ~3 giorni. Pazienti con permanenza >7 giorni hanno tassi di readmission ~2x rispetto a permanenze brevi (gravita' clinica maggiore al baseline).
  • num_medications \in [1, 81]: distribuzione skewed-right. Pazienti con >20 farmaci sono i multimorbidi: alta complessita' clinica, alto rischio.

Feature derivata n_med_changed (numero di farmaci antidiabetici con dosaggio modificato) e' un proxy della fragilita' farmacologica: un dosaggio modificato significa che il clinico sta cercando un equilibrio non ancora raggiunto, segnale di paziente complesso.

9. Cosa NON vedere nei dati

Il dataset Diabetes-130 manca di:

  • Condizioni socio-economiche (income, education, housing).
  • Supporto familiare (vivi solo? caregiver disponibile?).
  • Aderenza terapeutica (il paziente ha effettivamente preso i farmaci?).
  • Eventi acuti post-dimissione (caduta, infezione, complicanza).
  • Eventi ambulatoriali post-dimissione (visite di follow-up effettuate o no).

Questi sono predittori potenzialmente molto forti della readmission. La loro assenza e' la ragione principale per cui le AUC-ROC tipiche su questo dataset sono moderate (0.60-0.67): non e' un fallimento del modello, e' un limite del dataset.

10. Riferimenti