Raccolta dei dati e Struttura del dataset

Il peso alla nascita è un indicatore cruciale della salute neonatale e dello sviluppo futuro del bambino. Comprendere i fattori che influenzano il peso alla nascita può aiutare i professionisti sanitari ad identificare gravidanze a rischio e implementare interventi preventivi appropriati.

Gli obiettivi principali di questa analisi sono:

  1. Identificare le variabili più predittive del peso alla nascita
  2. Quantificare l’impatto del fumo materno sul peso del neonato
  3. Valutare l’effetto delle settimane di gestazione (nascite premature)
  4. Verificare eventuali differenze tra ospedali e tra sessi
  5. Sviluppare un modello predittivo affidabile per il peso alla nascita

Il dataset include informazioni su 2500 neonati provenienti da tre ospedali. Le variabili raccolte si possono distinguere in variabili qualitative nominali (fumo materno, tipo di parto, ospedale di nascita e sesso del neonato), quantitative discrete (numero di gravidanze) e continue (età della madre, durata della gravidanza, peso del neonato, lunghezza e diametro del cranio)

Analisi e Modellizzazione

Analisi preliminare

#install packages
library(ggplot2)      
library(corrplot)     
library(car)          
library(MASS)         

dati <- read.csv("neonati.csv", sep = ",")
N <- dim(dati)[1] 

# Indici di posizione
summary(dati[, c("Anni.madre", "N.gravidanze", "Gestazione", "Peso", 
                 "Lunghezza", "Cranio")])
##    Anni.madre     N.gravidanze       Gestazione         Peso     
##  Min.   : 0.00   Min.   : 0.0000   Min.   :25.00   Min.   : 830  
##  1st Qu.:25.00   1st Qu.: 0.0000   1st Qu.:38.00   1st Qu.:2990  
##  Median :28.00   Median : 1.0000   Median :39.00   Median :3300  
##  Mean   :28.16   Mean   : 0.9812   Mean   :38.98   Mean   :3284  
##  3rd Qu.:32.00   3rd Qu.: 1.0000   3rd Qu.:40.00   3rd Qu.:3620  
##  Max.   :46.00   Max.   :12.0000   Max.   :43.00   Max.   :4930  
##    Lunghezza         Cranio   
##  Min.   :310.0   Min.   :235  
##  1st Qu.:480.0   1st Qu.:330  
##  Median :500.0   Median :340  
##  Mean   :494.7   Mean   :340  
##  3rd Qu.:510.0   3rd Qu.:350  
##  Max.   :565.0   Max.   :390
# Deviazioni standard
sapply(dati[, c("Anni.madre", "N.gravidanze", "Gestazione", "Peso", 
                "Lunghezza", "Cranio")], sd)
##   Anni.madre N.gravidanze   Gestazione         Peso    Lunghezza       Cranio 
##     5.273578     1.280587     1.868639   525.038744    26.318644    16.425330
# Distribuzioni di frequenze per le variabili statistiche qualitative nominali
table(dati$Fumatrici)
## 
##    0    1 
## 2396  104
table(dati$Tipo.parto)
## 
##  Ces  Nat 
##  728 1772
table(dati$Ospedale)
## 
## osp1 osp2 osp3 
##  816  849  835
table(dati$Sesso)
## 
##    F    M 
## 1256 1244

Dall’analisi descrittiva emerge che l’età media delle madri è di circa 28 anni, con una mediana coincidente e una deviazione standard di poco superiore a 5 anni (SD=5.3). Questo suggerisce una distribuzione abbastanza simmetrica e concentrata attorno al valore centrale, confermata da un indice di asimmetria molto vicino a zero. Il numero di gravidanze ha una media vicina a 1 e una mediana pari a 1, ma presenta una forte asimmetria positiva e una curtosi elevata. Questo indica che la maggior parte delle madri ha avuto poche gravidanze, mentre sono presenti alcuni casi con valori molto alti (fino a 12), che allungano la coda destra della distribuzione e aumentano la variabilità. La variabile Fumatrici è binaria, con media pari a circa 0,04, quindi solo una piccola percentuale del campione è costituita da madri fumatrici. L’elevata asimmetria e curtosi sono coerenti con la natura fortemente sbilanciata della variabile, dove prevale nettamente la modalità 0. La durata della gestazione ha una media di circa 39 settimane e mediana coincidente, con una deviazione standard contenuta. L’asimmetria negativa indica una coda verso sinistra, quindi la presenza di alcuni parti molto prematuri che abbassano la media. Anche la curtosi elevata suggerisce una distribuzione più appuntita rispetto alla normale, con una concentrazione marcata attorno al valore centrale. Per quanto riguarda il peso alla nascita, la media è circa 3284 grammi e la mediana 3300 grammi, valori molto vicini che indicano una distribuzione abbastanza equilibrata. L’asimmetria leggermente negativa suggerisce una lieve prevalenza di valori elevati rispetto a quelli molto bassi, anche se sono presenti casi estremi come il minimo di 830 grammi. La variabilità è moderata, con una deviazione standard di circa 525 grammi. La lunghezza e la circonferenza cranica mostrano medie rispettivamente di circa 495 mm e 340 mm, con mediane molto simili alle medie. Tuttavia entrambe presentano asimmetria negativa, più marcata per la lunghezza, il che indica la presenza di alcuni neonati significativamente più piccoli rispetto alla media. Anche qui la curtosi positiva segnala distribuzioni più concentrate e con code più pesanti rispetto alla normale. La distribuzione di nascite tra i tre ospedali risulta pressoché bilanciata: ospedale_1 (32.6%), ospedale_2 (34%) e ospedale_3 (33.4%).

# Istogramma del Peso (variabile target)
ggplot(dati, aes(x = Peso)) +
  geom_histogram(bins = 30, fill = "steelblue", color = "black", alpha = 0.7) +
  geom_vline(aes(xintercept = mean(Peso)), color = "red", linetype = "dashed", size = 1) +
  labs(title = "Figura 1: Distribuzione del Peso dei Neonati",
       x = "Peso (grammi)", y = "Frequenza") +
  theme_minimal()

La Figura 1 rappresenta l’istogramma della distribuzione del peso dei neonati e si può notare che si tratta di una distribuzione molto simile ad una gaussiana, abbastanza simmetrica attorno alla media di circa 3200 grammi. Questa forma indica che la maggior parte dei neonati si concentra attorno a valori centrali, con pochi casi estremi. La linea rossa tratteggiata indica la media del campione. Si può notare che la distribuzione ha code relativamente lunghe, soprattutto verso i valori bassi, il che ha senso dal punto di vista clinico considerando i neonati prematuri o con basso peso alla nascita.

# Calcolo degli outlier
Q1 <- quantile(dati$Peso, 0.25)
Q3 <- quantile(dati$Peso, 0.75)
IQR_peso <- IQR(dati$Peso)
outliers_peso <- dati$Peso < (Q1 - 1.5*IQR_peso) | dati$Peso > (Q3 + 1.5*IQR_peso)
cat("\nNumero di outlier nel peso:", sum(outliers_peso), "\n")
## 
## Numero di outlier nel peso: 69
# Boxplot del Peso per identificare outlier
ggplot(dati, aes(y = Peso)) +
  geom_boxplot(fill = "lightblue", alpha = 0.7) +
  labs(title = "Figura 2: Boxplot del Peso - Identificazione Outlier",
       y = "Peso (grammi)") +
  theme_minimal()

Il boxplot degli outlier in Figura 2 mostra un box abbastanza compatto che contiene la maggior parte delle osservazioni, con la mediana che sembra allineata al centro. Emergono i numerosi outlier posizionati sotto la soglia inferiore del boxplot, particolarmente concentrati nella fascia 1000-2000 grammi: rappresentano casi clinici reali, probabilmente neonati prematuri o con problematiche durante la gravidanza. Invece sopra il limite superiore si notano anche alcuni punti, ma molti meno, che rappresentano neonati particolarmente con peso molto maggiore rispetto al range medio. Gli outlier sono in totale 69 e la loro presenza impone di verificare che non distorcano eccessivamente il modello finale.

# Visualizzazione le relazioni bivariabili con la variabile target
# Peso vs Gestazione
ggplot(dati, aes(x = Gestazione, y = Peso)) +
  geom_point(alpha = 0.5, color = "darkblue") +
  geom_smooth(method = "lm", color = "red", se = TRUE) +
  labs(title = "Figura 3: Peso del Neonato vs Settimane di Gestazione",
       x = "Settimane di Gestazione", y = "Peso (grammi)") +
  theme_minimal()

Nella Figura 3, che mostra la relazione tra peso e gestazione, la linea rossa di regressione mostra una pendenza positiva molto marcata, confermando che all’aumentare delle settimane di gestazione aumenta sistematicamente il peso del neonato. Emerge come la variabilità aumenta man mano che ci si avvicina al termine della gravidanza. Nelle settimane 26-32 si vedono pochissimi punti, tutti concentrati su pesi molto bassi, mentre a 38-40 settimane la dispersione è enorme, con neonati che vanno da poco più di 2000 grammi fino a quasi 5000 g. Questa crescente variabilità è biologicamente coerente perché riflette la maggiore diversità genetica e ambientale che si esprime pienamente nelle gravidanze a termine. La correlazione tra queste due variabili è molto forte, 0.59 secondo la matrice di correlazione visibile in Figura 6, ed è probabilmente il singolo predittore più significativo a disposizione.

# Peso vs Fumo materno
ggplot(dati, aes(x = factor(Fumatrici), y = Peso, fill = factor(Fumatrici))) +
  geom_boxplot(alpha = 0.7) +
  scale_fill_manual(values = c("0" = "lightgreen", "1" = "salmon"),
                    labels = c("Non fumatrice", "Fumatrice")) +
  labs(title = "Figura 4: Peso del Neonato per Stato di Fumo Materno",
       x = "Fumo Materno", y = "Peso (grammi)", fill = "Status") +
  theme_minimal()

L’impatto del fumo materno, visibile nei boxplot in Figura 4, mostrano come, sebbene nel campione in esame siano presenti solo 104 madri fumatrici, appena il 4.2% del totale, contro 2396 non fumatrici, i neonati provenienti dalle loro gravidanze hanno una distribuzione del peso leggermente spostata verso il basso, con una differenza nelle medie di circa 50 grammi. Questa differenza potrebbe sembrare piccola, ma considerando lo sbilanciamento notevole del campione così sbilanciato (96% vs 4%) il dato potrebbe non essere statisticamente significativo al fine di rilevare il reale effetto del fumo, verrà verificato nelle successive fasi dell’analisi. La sovrapposizione tra le due distribuzioni è comunque notevole, il che suggerisce che non si può usare solo il fumo per la predizione del peso, ma è sicuramente un fattore che contribuisce. Potrebbe essere anche possibile che con così poche fumatrici presenti nel campione, l’effetto sia sottostimato rispetto quello reale.

# Peso per Sesso
ggplot(dati, aes(x = Sesso, y = Peso, fill = Sesso)) +
  geom_boxplot(alpha = 0.7) +
  scale_fill_manual(values = c("M" = "lightblue", "F" = "pink")) +
  labs(title = "Figura 5: Peso del Neonato per Sesso",
       x = "Sesso", y = "Peso (grammi)") +
  theme_minimal()

Le differenze tra sessi, visibili in Figura 5, sono molto evidenti e nette. Il campione è ben bilanciato con 1244 maschi e 1256 femmine. I maschi pesano in media 3408 grammi mentre le femmine 3161 grammi, una differenza sostanziale di 247 grammi che rappresenta circa il 7.5% del peso medio ed è sia clinicamente rilevante che statisticamente significativa. Guardando i boxplot, si può notare che non è solo una questione di media spostata ma proprio tutta la distribuzione dei maschi è traslata verso l’alto. Le mediane, i quartili, tutto è sistematicamente maggiore per i maschi. C’è una sovrapposizione tra le distribuzioni, ma è chiara la tendenza ed entrambi i sessi mostrano uno spettro simile di outlier.

# Matrice di correlazione (solo variabili numeriche)
variabili_num <- dati[, c("Anni.madre", "N.gravidanze", "Gestazione", 
                          "Peso", "Lunghezza", "Cranio")]
cor_matrix <- cor(variabili_num)
print(cor_matrix)
##               Anni.madre N.gravidanze Gestazione        Peso   Lunghezza
## Anni.madre    1.00000000   0.38063184 -0.1356671 -0.02247017 -0.06349157
## N.gravidanze  0.38063184   1.00000000 -0.1014919  0.00240730 -0.06040371
## Gestazione   -0.13566714  -0.10149194  1.0000000  0.59176872  0.61892045
## Peso         -0.02247017   0.00240730  0.5917687  1.00000000  0.79603676
## Lunghezza    -0.06349157  -0.06040371  0.6189204  0.79603676  1.00000000
## Cranio        0.01607670   0.03900707  0.4608289  0.70480151  0.60334097
##                  Cranio
## Anni.madre   0.01607670
## N.gravidanze 0.03900707
## Gestazione   0.46082894
## Peso         0.70480151
## Lunghezza    0.60334097
## Cranio       1.00000000
corrplot(cor_matrix, method = "color", type = "upper", 
         addCoef.col = "black", tl.col = "black", tl.srt = 45,
         title = "Figura 6: Matrice di Correlazione",
         mar = c(0,0,2,0))

Nella matrice di correlazione mostrata in Figura 6 si può vedere che la gestazione mostra correlazioni moderate con tutte le misure antropometriche, il che conferma il fatto che più la gravidanza va avanti, più il feto cresce in tutte le dimensioni. Le correlazioni con età materna e numero di gravidanze sono invece molto deboli, quasi nulle, suggerendo che questi fattori demografici hanno un impatto minimo sul peso del neonato, nel senso che il loro effetto potrebbe essere più sottile o mediato da altre variabili.

#IPOTESI 1: In alcuni ospedali si fanno più parti cesarei
# H0: Non c'è associazione tra ospedale e tipo di parto
# H1: C'è associazione tra ospedale e tipo di parto
# TEST: Chi-quadrato di Pearson per indipendenza

#Creazione della tabella di contingenza
tab_osp_parto <- table(dati$Ospedale, dati$Tipo.parto)
print(tab_osp_parto)
##       
##        Ces Nat
##   osp1 242 574
##   osp2 254 595
##   osp3 232 603
# Proporzioni per ospedale
prop.table(tab_osp_parto, margin = 1)
##       
##              Ces       Nat
##   osp1 0.2965686 0.7034314
##   osp2 0.2991755 0.7008245
##   osp3 0.2778443 0.7221557
# Test Chi-quadrato
test_chi <- chisq.test(tab_osp_parto)
print(test_chi)
## 
##  Pearson's Chi-squared test
## 
## data:  tab_osp_parto
## X-squared = 1.0972, df = 2, p-value = 0.5778
#Visualizzazione del risultato
ggplot(dati, aes(x = Ospedale, fill = Tipo.parto)) +
  geom_bar(position = "fill") +
  scale_fill_manual(values = c("Ces" = "coral", "Nat" = "lightgreen")) +
  labs(title = "Figura 7: Proporzione Tipo di Parto per Ospedale",
       x = "Ospedale", y = "Proporzione", fill = "Tipo Parto") +
  theme_minimal()

Per saggiare la prima ipotesi è stato usato il test Chi-quadrato di Pearson dato che le variabili in questione sono categoriali. Dal risultato ottenuto non emerge un’associazione statisticamente significativa tra ospedale e tipo di parto, dato che il p-value ottenuto è pari a 0.557, quindi ampiamente superiore al livello di significatività convenzionale di 0.05. Questo implica che non sono presenti evidenze sufficienti per rifiutare l’ipotesi nulla di indipendenza e che le eventuali differenze osservate nella distribuzione dei parti cesarei tra i diversi ospedali possono essere attribuite alla variabilità casuale del campione. Anche il grafico delle proporzioni, visibile in Figura 7, conferma questa interpretazione, poiché le percentuali di parti naturali e cesarei risultano molto simili tra le strutture considerate e non mostrano scostamenti evidenti. Nel complesso, i risultati suggeriscono che, nel campione analizzato, il tipo di parto non dipende in modo significativo dall’ospedale.

#IPOTESI 2: La media del peso e della lunghezza di questo campione di neonati sono significativamente uguali a quelle della popolazione
# Peso medio popolazione: 3300g
# Lunghezza media popolazione: 50cm = 500mm

# 2.1 Test t per il PESO
# H0: μ_peso_campione = 3300
# H1: μ_peso_campione != 3300

peso_popolazione <- 3300

test_peso <- t.test(dati$Peso, mu = peso_popolazione)
print(test_peso)
## 
##  One Sample t-test
## 
## data:  dati$Peso
## t = -1.516, df = 2499, p-value = 0.1296
## alternative hypothesis: true mean is not equal to 3300
## 95 percent confidence interval:
##  3263.490 3304.672
## sample estimates:
## mean of x 
##  3284.081
# 2.2 Test t per la LUNGHEZZA
# H0: μ_lunghezza_campione = 500
# H1: μ_lunghezza_campione != 500

lunghezza_popolazione <- 500

test_lunghezza <- t.test(dati$Lunghezza, mu = lunghezza_popolazione)
print(test_lunghezza)
## 
##  One Sample t-test
## 
## data:  dati$Lunghezza
## t = -10.084, df = 2499, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 500
## 95 percent confidence interval:
##  493.6598 495.7242
## sample estimates:
## mean of x 
##   494.692

Per verificare se il campione fosse coerente con i parametri medi della popolazione di riferimento è stato utilizzato un t test in quanto si vogliono confrontare le medie campionarie con un valore di riferimento. In particolare le variabili analizzate, peso e lunghezza alla nascita, sono quantitative continue e la numerosità campionaria è elevata, questo rende l’approccio robusto anche in presenza di leggere deviazioni dalla normalità. Nel caso del peso, il test restituisce un p-value pari a 0.1296, superiore al livello di significatività convenzionale di 0.05. Questo implica che non si rifiuta l’ipotesi nulla e che la media campionaria di 3284 grammi non risulta significativamente diversa dai 3300 grammi della popolazione di riferimento. Anche l’intervallo di confidenza al 95% include il valore 3300, confermando che lo scostamento osservato può essere attribuito alla variabilità campionaria e non evidenzia una differenza sistematica. Diversamente, per la lunghezza il test produce un p-value estremamente piccolo, inferiore a 2.2e-16, indicando una differenza statisticamente significativa rispetto al valore di riferimento di 500 mm. La media campionaria risulta pari a circa 494.7 mm e l’intervallo di confidenza al 95% non include 500, suggerendo che la lunghezza media nel campione è effettivamente inferiore rispetto alla popolazione. In questo caso, la differenza non è solo osservabile numericamente, ma anche supportata da un’evidenza statistica molto forte e pertanto si rifiuta l’ipotesi nulla.

# IPOTESI 3: Misure antropometriche diverse tra i sessi
# ------------------------------------------------------------------------------
# H0: Le misure antropometriche sono uguali tra maschi e femmine
# H1: Le misure antropometriche sono diverse tra maschi e femmine
# TEST: t-test a due campioni indipendenti


# 3.1 Test per il PESO
test_peso_sesso <- t.test(Peso ~ Sesso, data = dati)
print(test_peso_sesso)
## 
##  Welch Two Sample t-test
## 
## data:  Peso by Sesso
## t = -12.106, df = 2490.7, p-value < 2.2e-16
## alternative hypothesis: true difference in means between group F and group M is not equal to 0
## 95 percent confidence interval:
##  -287.1051 -207.0615
## sample estimates:
## mean in group F mean in group M 
##        3161.132        3408.215
aggregate(Peso ~ Sesso, data = dati, FUN = function(x) c(media = mean(x), sd = sd(x)))
##   Sesso Peso.media   Peso.sd
## 1     F  3161.1322  526.3091
## 2     M  3408.2154  493.8043
# 3.2 Test per la LUNGHEZZA
test_lunghezza_sesso <- t.test(Lunghezza ~ Sesso, data = dati)
print(test_lunghezza_sesso)
## 
##  Welch Two Sample t-test
## 
## data:  Lunghezza by Sesso
## t = -9.582, df = 2459.3, p-value < 2.2e-16
## alternative hypothesis: true difference in means between group F and group M is not equal to 0
## 95 percent confidence interval:
##  -11.929470  -7.876273
## sample estimates:
## mean in group F mean in group M 
##        489.7643        499.6672
aggregate(Lunghezza ~ Sesso, data = dati, FUN = function(x) c(media = mean(x), sd = sd(x)))
##   Sesso Lunghezza.media Lunghezza.sd
## 1     F       489.76433     27.53415
## 2     M       499.66720     24.03809
# 3.3 Test per il DIAMETRO CRANIO
test_cranio_sesso <- t.test(Cranio ~ Sesso, data = dati)
print(test_cranio_sesso)
## 
##  Welch Two Sample t-test
## 
## data:  Cranio by Sesso
## t = -7.4102, df = 2491.4, p-value = 1.718e-13
## alternative hypothesis: true difference in means between group F and group M is not equal to 0
## 95 percent confidence interval:
##  -6.089912 -3.541270
## sample estimates:
## mean in group F mean in group M 
##        337.6330        342.4486
aggregate(Cranio ~ Sesso, data = dati, FUN = function(x) c(media = mean(x), sd = sd(x)))
##   Sesso Cranio.media Cranio.sd
## 1     F    337.63296  16.73772
## 2     M    342.44855  15.74448
# Visualizzazione comparativa
par(mfrow = c(1, 3))
boxplot(Peso ~ Sesso, data = dati, col = c("pink", "lightblue"),
        main = "Figura 8.1: Peso per Sesso", ylab = "Peso (g)")
boxplot(Lunghezza ~ Sesso, data = dati, col = c("pink", "lightblue"),
        main = "Figura 8.2: Lunghezza per Sesso", ylab = "Lunghezza (mm)")
boxplot(Cranio ~ Sesso, data = dati, col = c("pink", "lightblue"),
        main = "Figura 8.3: Cranio per Sesso", ylab = "Cranio (mm)")

par(mfrow = c(1, 1))

Per la terza ipotesi sono state confrontate le misure antropometriche tra maschi e femmine utilizzando il t test per due campioni indipendenti, che è appropriato quando vengono confrontati due gruppi separati e non si vuole assumere che abbiano varianze uguali. L’obiettivo è verificare se esistono differenze significative nelle medie di peso, lunghezza e diametro cranico in funzione del sesso che è un fenomeno biologico ben documentato, e si vuole confermare che questo pattern si manifesta anche nel campione in esame pertanto per tutti e tre i casi si è formulata la medesima ipotesi nulla cioè “non esiste differenza tra i sessi”.

Per quanto riguarda il peso, il test restituisce un p-value inferiore a 2.2e-16, quindi molto inferiore del livello di significatività di 0.05. In questo caso si rifiuta l’ipotesi nulla di uguaglianza delle medie tra maschi e femmine. La differenza osservata è anche rilevante dal punto di vista pratico, con una media di circa 3161 grammi per le femmine e 3408 grammi per i maschi, suggerendo che nel campione analizzato i neonati maschi presentano un peso medio significativamente superiore rispetto alle femmine. Guardando il boxplot in Figura 8.1, questa differenza è molto evidente, con l’intera distribuzione dei maschi spostata verso l’alto rispetto alle femmine. Le mediane sono separate anche se c’è sovrapposizione tra le distribuzioni. Questa differenza di 247 grammi non è solo statisticamente significativa ma anche clinicamente rilevante. Infatti biologicamente rappresenta circa il 7.5% del peso medio e corrisponde approssimativamente al guadagno di peso che un neonato accumulerebbe in circa 1.5-2 settimane di gestazione. Questa caratteristica nel peso riflette le differenze biologiche fondamentali legate agli ormoni sessuali e ai pattern di crescita differenziali tra maschi e femmine già in utero.

Un risultato analogo emerge per la lunghezza. Anche in questo caso il p-value è estremamente basso e si rifiuta l’ipotesi nulla. Le femmine presentano una lunghezza media di circa 489.8 mm, mentre i maschi raggiungono quasi 499.7 mm. L’intervallo di confidenza della differenza tra le medie non include lo zero, confermando che la differenza è statisticamente significativa e non attribuibile alla sola variabilità campionaria. Dal boxplot in Figura 8.2 si può osservare che le distribuzioni sono separate ma con maggiore sovrapposizione rispetto al peso, il che è coerente dato che la differenza percentuale è leggermente minore. Un centimetro di differenza nella lunghezza rappresenta circa il 2% della lunghezza media e, in termini di sviluppo fetale, riflette il fatto che i maschi tendono ad avere uno sviluppo scheletrico leggermente più avanzato.

Infine, per il diametro cranico il p-value risulta pari a 1.718e-13, anch’esso ampiamente inferiore a 0.05. Anche in questo caso si rifiuta l’ipotesi nulla e si conclude che esiste una differenza significativa tra i due sessi. La media del diametro cranico è circa 337.6 mm nelle femmine e 342.4 mm nei maschi, indicando valori mediamente più elevati nei maschi. Dal boxplot del cranio in Figura 8.3, si vede che le distribuzioni sono molto sovrapposte, ma le mediane sono chiaramente separate. La differenza di 4.8 millimetri nel diametro cranico rappresenta circa l’1.4% della media ed è la più piccola in termini percentuali tra le tre misure, ma rimane comunque significativa sia statisticamente che biologicamente. Infatti il cranio è una struttura ossea che riflette in parte la dimensione cerebrale, e queste differenze precoci tra i sessi possono avere implicazioni per lo sviluppo neurologico successivo.

Un aspetto interessante che emerge confrontando i tre test è che la forza dell’evidenza, decresce nell’ordine: peso, lunghezza, cranio. Questo pattern di differenze decrescenti è coerente dal punto di vista dello sviluppo: il peso è influenzato da massa muscolare, grasso e fluidi corporei, tutti elementi che possono variare maggiormente tra i sessi; la lunghezza riflette principalmente lo scheletro; il cranio è una struttura più “protetta” e standardizzata perché deve contenere il cervello, quindi mostra meno variabilità. Un altro punto rilevante è che il campione in esame è molto bilanciato tra i sessi, con 1256 femmine e 1244 maschi e ciò aumenta la potenza statistica e la validità dei confronti in quanto si ha un’eccellente capacità di rilevare anche differenze piccole. Dal punto di vista della modellizzazione predittiva che verrà svolta successivamente, questi risultati suggeriscono che il sesso sarà sicuramente un predittore importante da includere nel modello di regressione per il peso, dato l’impatto così marcato ottenuto.

Creazione del modello di regressione

# MODELLO COMPLETO DI REGRESSIONE LINEARE MULTIPLA

dati$Fumatrici <- factor(dati$Fumatrici, levels = c(0, 1), labels = c("Non_fumatrice", "Fumatrice"))
dati$Tipo.parto <- factor(dati$Tipo.parto)
dati$Ospedale <- factor(dati$Ospedale)
dati$Sesso <- factor(dati$Sesso)

modello_completo <- lm(Peso ~ Anni.madre + N.gravidanze + Fumatrici + 
                         Gestazione + Lunghezza + Cranio + Tipo.parto + 
                         Ospedale + Sesso, 
                       data = dati)

summary(modello_completo)
## 
## Call:
## lm(formula = Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione + 
##     Lunghezza + Cranio + Tipo.parto + Ospedale + Sesso, data = dati)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1124.40  -181.66   -14.42   160.91  2611.89 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        -6738.4762   141.3087 -47.686  < 2e-16 ***
## Anni.madre             0.8921     1.1323   0.788   0.4308    
## N.gravidanze          11.2665     4.6608   2.417   0.0157 *  
## FumatriciFumatrice   -30.1631    27.5386  -1.095   0.2735    
## Gestazione            32.5696     3.8187   8.529  < 2e-16 ***
## Lunghezza             10.2945     0.3007  34.236  < 2e-16 ***
## Cranio                10.4707     0.4260  24.578  < 2e-16 ***
## Tipo.partoNat         29.5254    12.0844   2.443   0.0146 *  
## Ospedaleosp2         -11.2095    13.4379  -0.834   0.4043    
## Ospedaleosp3          28.0958    13.4957   2.082   0.0375 *  
## SessoM                77.5409    11.1776   6.937 5.08e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 273.9 on 2489 degrees of freedom
## Multiple R-squared:  0.7289, Adjusted R-squared:  0.7278 
## F-statistic: 669.2 on 10 and 2489 DF,  p-value: < 2.2e-16
vif_values <- vif(modello_completo)
print(vif_values)
##                  GVIF Df GVIF^(1/(2*Df))
## Anni.madre   1.187454  1        1.089704
## N.gravidanze 1.186428  1        1.089233
## Fumatrici    1.007392  1        1.003689
## Gestazione   1.695810  1        1.302233
## Lunghezza    2.085755  1        1.444214
## Cranio       1.630796  1        1.277026
## Tipo.parto   1.004242  1        1.002119
## Ospedale     1.004071  2        1.001016
## Sesso        1.040643  1        1.020119

E’ stato creato un modello di regressione lineare multipla includendo tutte le variabili disponibili per identificare i principali determinanti del peso alla nascita. Il modello mostra un’ottima capacità esplicativa, con un R² aggiustato pari a 0.7278, quindi circa il 73% della variabilità del peso è spiegata dai predittori inclusi. L’errore residuo standard è di circa 274 grammi, uno scostamento medio contenuto rispetto a un peso medio di 3284 grammi. Le misure antropometriche emergono come i predittori più forti. La lunghezza ha un coefficiente di 10.3 grammi per millimetro con p < 2e-16 e una statistica t di 34.2, la più elevata nel modello; il diametro cranico contribuisce con 10.5 grammi per millimetro, anch’esso con significatività estremamente elevata. Questo conferma che le dimensioni corporee sono strettamente legate al peso, come atteso dal punto di vista biologico. La gestazione resta altamente significativa ma il suo coefficiente si riduce da circa 145 grammi nell’analisi bivariata a 32.6 grammi nel modello multivariato. Questa riduzione riflette un effetto di mediazione: gran parte dell’impatto della durata della gravidanza sul peso si manifesta attraverso l’aumento di lunghezza e cranio, che nel modello ne assorbono una quota rilevante. Il sesso è un predittore robusto: a parità delle altre variabili, i maschi pesano in media 77.5 grammi in più delle femmine, con p = 5×10⁻¹². La differenza si riduce rispetto ai 247 grammi osservati nel confronto bivariato perché una parte è spiegata dalle maggiori dimensioni corporee dei maschi; il coefficiente stimato rappresenta quindi un effetto “netto”. Il tipo di parto mostra un effetto moderato ma significativo: i parti naturali sono associati a circa 29.5 grammi in più rispetto ai cesarei, con p = 0.015, risultato da interpretare in termini associativi e non causali. Anche il numero di gravidanze precedenti, non rilevante in analisi semplice, diventa significativo nel modello multivariato con un incremento di circa 11 grammi per gravidanza e p = 0.016, evidenziando l’utilità dell’approccio multivariato. Per l’ospedale, solo il terzo risulta marginalmente significativo con un incremento medio di 28 grammi rispetto al riferimento e p = 0.038, mentre il secondo non mostra differenze. Il fumo materno presenta un coefficiente coerente con la letteratura, pari a −30.2 grammi, ma non significativo (p = 0.27), probabilmente a causa della bassa prevalenza di fumatrici nel campione, pari al 4%, che limita la potenza statistica. L’età materna risulta chiaramente non significativa, con un coefficiente di 0.89 grammi per anno e p = 0.43. L’analisi della multicollinearità è rassicurante: tutti i VIF sono ben al di sotto della soglia critica di 5, con un massimo di 2.09 per la lunghezza. Questo indica che, pur in presenza di correlazioni moderate tra alcune variabili, le stime sono stabili e ogni predittore mantiene una quota informativa propria.

Selezione del modello ottimale

# SELEZIONE DEL MODELLO CON STEPWISE (AIC)

modello_step_AIC <- stepAIC(modello_completo, direction = "both", trace = FALSE)
summary(modello_step_AIC)
## 
## Call:
## lm(formula = Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio + 
##     Tipo.parto + Ospedale + Sesso, data = dati)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1113.18  -181.16   -16.58   161.01  2620.19 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   -6707.4293   135.9438 -49.340  < 2e-16 ***
## N.gravidanze     12.3619     4.3325   2.853  0.00436 ** 
## Gestazione       31.9909     3.7896   8.442  < 2e-16 ***
## Lunghezza        10.3086     0.3004  34.316  < 2e-16 ***
## Cranio           10.4922     0.4254  24.661  < 2e-16 ***
## Tipo.partoNat    29.2803    12.0817   2.424  0.01544 *  
## Ospedaleosp2    -11.0227    13.4363  -0.820  0.41209    
## Ospedaleosp3     28.6408    13.4886   2.123  0.03382 *  
## SessoM           77.4412    11.1756   6.930 5.36e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 273.9 on 2491 degrees of freedom
## Multiple R-squared:  0.7287, Adjusted R-squared:  0.7278 
## F-statistic: 836.3 on 8 and 2491 DF,  p-value: < 2.2e-16
#Le variabili selezionate dal modello stepwise AIC sono:
print(names(coef(modello_step_AIC)))
## [1] "(Intercept)"   "N.gravidanze"  "Gestazione"    "Lunghezza"    
## [5] "Cranio"        "Tipo.partoNat" "Ospedaleosp2"  "Ospedaleosp3" 
## [9] "SessoM"
# SELEZIONE DEL MODELLO CON BIC

modello_step_BIC <- stepAIC(modello_completo, direction = "both", k = log(nrow(dati)), trace = FALSE)
summary(modello_step_BIC)
## 
## Call:
## lm(formula = Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio + 
##     Sesso, data = dati)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1149.44  -180.81   -15.58   163.64  2639.72 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -6681.1445   135.7229 -49.226  < 2e-16 ***
## N.gravidanze    12.4750     4.3396   2.875  0.00408 ** 
## Gestazione      32.3321     3.7980   8.513  < 2e-16 ***
## Lunghezza       10.2486     0.3006  34.090  < 2e-16 ***
## Cranio          10.5402     0.4262  24.728  < 2e-16 ***
## SessoM          77.9927    11.2021   6.962 4.26e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 274.6 on 2494 degrees of freedom
## Multiple R-squared:  0.727,  Adjusted R-squared:  0.7265 
## F-statistic:  1328 on 5 and 2494 DF,  p-value: < 2.2e-16
#Le variabili selezionate dal modello stepwise BIC sono:
print(names(coef(modello_step_BIC)))
## [1] "(Intercept)"  "N.gravidanze" "Gestazione"   "Lunghezza"    "Cranio"      
## [6] "SessoM"
# MODELLI CON INTERAZIONI
# Fumo × Gestazione
modello_int1 <- lm(Peso ~ Anni.madre + N.gravidanze + Fumatrici * Gestazione + 
                     Lunghezza + Cranio + Tipo.parto + Ospedale + Sesso, 
                   data = dati)
summary(modello_int1)
## 
## Call:
## lm(formula = Peso ~ Anni.madre + N.gravidanze + Fumatrici * Gestazione + 
##     Lunghezza + Cranio + Tipo.parto + Ospedale + Sesso, data = dati)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1123.68  -181.93   -15.02   162.35  2611.88 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                   -6756.1602   142.1553 -47.527  < 2e-16 ***
## Anni.madre                        0.8697     1.1324   0.768   0.4425    
## N.gravidanze                     11.3500     4.6611   2.435   0.0150 *  
## FumatriciFumatrice              827.9340   755.8481   1.095   0.2735    
## Gestazione                       33.1387     3.8512   8.605  < 2e-16 ***
## Lunghezza                        10.2888     0.3007  34.215  < 2e-16 ***
## Cranio                           10.4655     0.4260  24.565  < 2e-16 ***
## Tipo.partoNat                    29.7219    12.0849   2.459   0.0140 *  
## Ospedaleosp2                    -10.8798    13.4402  -0.809   0.4183    
## Ospedaleosp3                     28.4378    13.4983   2.107   0.0352 *  
## SessoM                           78.1505    11.1898   6.984 3.67e-12 ***
## FumatriciFumatrice:Gestazione   -21.8575    19.2402  -1.136   0.2561    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 273.9 on 2488 degrees of freedom
## Multiple R-squared:  0.729,  Adjusted R-squared:  0.7278 
## F-statistic: 608.5 on 11 and 2488 DF,  p-value: < 2.2e-16
#Sesso × Gestazione
modello_int2 <- lm(Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione * Sesso + 
                     Lunghezza + Cranio + Tipo.parto + Ospedale, 
                   data = dati)
summary(modello_int2)
## 
## Call:
## lm(formula = Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione * 
##     Sesso + Lunghezza + Cranio + Tipo.parto + Ospedale, data = dati)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1118.97  -180.56   -14.75   161.52  2609.79 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        -6615.0710   171.0980 -38.662  < 2e-16 ***
## Anni.madre             0.8984     1.1321   0.794   0.4275    
## N.gravidanze          11.2156     4.6604   2.407   0.0162 *  
## FumatriciFumatrice   -31.1550    27.5460  -1.131   0.2582    
## Gestazione            29.3039     4.5934   6.380 2.11e-10 ***
## SessoM              -221.9556   234.4562  -0.947   0.3439    
## Lunghezza             10.2988     0.3007  34.253  < 2e-16 ***
## Cranio                10.4717     0.4260  24.583  < 2e-16 ***
## Tipo.partoNat         29.9113    12.0866   2.475   0.0134 *  
## Ospedaleosp2         -10.8304    13.4394  -0.806   0.4204    
## Ospedaleosp3          28.6376    13.5006   2.121   0.0340 *  
## Gestazione:SessoM      7.6747     6.0012   1.279   0.2011    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 273.9 on 2488 degrees of freedom
## Multiple R-squared:  0.7291, Adjusted R-squared:  0.7279 
## F-statistic: 608.7 on 11 and 2488 DF,  p-value: < 2.2e-16
# Confronto con test ANOVA
anova(modello_step_AIC, modello_int1)
## Analysis of Variance Table
## 
## Model 1: Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio + Tipo.parto + 
##     Ospedale + Sesso
## Model 2: Peso ~ Anni.madre + N.gravidanze + Fumatrici * Gestazione + Lunghezza + 
##     Cranio + Tipo.parto + Ospedale + Sesso
##   Res.Df       RSS Df Sum of Sq     F Pr(>F)
## 1   2491 186899996                          
## 2   2488 186665695  3    234302 1.041 0.3733
anova(modello_step_AIC, modello_int2)
## Analysis of Variance Table
## 
## Model 1: Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio + Tipo.parto + 
##     Ospedale + Sesso
## Model 2: Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione * Sesso + 
##     Lunghezza + Cranio + Tipo.parto + Ospedale
##   Res.Df       RSS Df Sum of Sq     F Pr(>F)
## 1   2491 186899996                          
## 2   2488 186639833  3    260163 1.156 0.3251
# MODELLI CON EFFETTI NON LINEARI
# Termine quadratico per Gestazione
modello_quad1 <- lm(Peso ~ Anni.madre + N.gravidanze + Fumatrici + 
                      Gestazione + I(Gestazione^2) + 
                      Lunghezza + Cranio + Tipo.parto + Ospedale + Sesso, 
                    data = dati)
summary(modello_quad1)
## 
## Call:
## lm(formula = Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione + 
##     I(Gestazione^2) + Lunghezza + Cranio + Tipo.parto + Ospedale + 
##     Sesso, data = dati)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1148.74  -180.02   -11.96   163.00  2633.39 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        -4831.3237   897.2219  -5.385 7.93e-08 ***
## Anni.madre             0.9717     1.1321   0.858   0.3908    
## N.gravidanze          11.2305     4.6574   2.411   0.0160 *  
## FumatriciFumatrice   -28.9993    27.5238  -1.054   0.2922    
## Gestazione           -74.0163    49.6654  -1.490   0.1363    
## I(Gestazione^2)        1.4233     0.6612   2.152   0.0315 *  
## Lunghezza             10.3923     0.3039  34.198  < 2e-16 ***
## Cranio                10.5607     0.4278  24.688  < 2e-16 ***
## Tipo.partoNat         29.0826    12.0773   2.408   0.0161 *  
## Ospedaleosp2         -10.4698    13.4325  -0.779   0.4358    
## Ospedaleosp3          27.7494    13.4868   2.058   0.0397 *  
## SessoM                75.4719    11.2107   6.732 2.07e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 273.7 on 2488 degrees of freedom
## Multiple R-squared:  0.7294, Adjusted R-squared:  0.7282 
## F-statistic: 609.7 on 11 and 2488 DF,  p-value: < 2.2e-16
anova(modello_step_AIC, modello_quad1)
## Analysis of Variance Table
## 
## Model 1: Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio + Tipo.parto + 
##     Ospedale + Sesso
## Model 2: Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione + I(Gestazione^2) + 
##     Lunghezza + Cranio + Tipo.parto + Ospedale + Sesso
##   Res.Df       RSS Df Sum of Sq      F  Pr(>F)  
## 1   2491 186899996                              
## 2   2488 186415389  3    484607 2.1559 0.09122 .
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#Confronto tra modelli
modelli <- list(
  "Completo" = modello_completo,
  "Stepwise_AIC" = modello_step_AIC,
  "Stepwise_BIC" = modello_step_BIC,
  "Interazione_Fumo" = modello_int1,
  "Interazione_Sesso" = modello_int2,
  "Quadratico" = modello_quad1
)

confronto <- data.frame(
  Modello = names(modelli),
  R2 = sapply(modelli, function(m) summary(m)$r.squared),
  R2_adj = sapply(modelli, function(m) summary(m)$adj.r.squared),
  AIC = sapply(modelli, AIC),
  BIC = sapply(modelli, BIC),
  N_parametri = sapply(modelli, function(m) length(coef(m)))
)

print(confronto)
##                             Modello        R2    R2_adj      AIC      BIC
## Completo                   Completo 0.7288930 0.7278038 35171.95 35241.84
## Stepwise_AIC           Stepwise_AIC 0.7286934 0.7278221 35169.79 35228.03
## Stepwise_BIC           Stepwise_BIC 0.7270015 0.7264542 35179.33 35220.10
## Interazione_Fumo   Interazione_Fumo 0.7290335 0.7278355 35172.65 35248.36
## Interazione_Sesso Interazione_Sesso 0.7290711 0.7278732 35172.31 35248.02
## Quadratico               Quadratico 0.7293969 0.7282005 35169.30 35245.01
##                   N_parametri
## Completo                   11
## Stepwise_AIC                9
## Stepwise_BIC                6
## Interazione_Fumo           12
## Interazione_Sesso          12
## Quadratico                 12

Confrontando i diversi modelli partendo da quello completo, che rappresenta la baseline con R² aggiustato pari a 0.7278, AIC 38542, BIC 38615 e 11 parametri. Il modello selezionato tramite stepwise AIC rimuove solo Anni.madre (p=0.43) e Fumatrici (p=0.27), mantenendo tutte le altre variabili, incluse quelle borderline come Ospedale. Le performance restano identiche al modello completo in termini di R² aggiustato (0.7278), ma l’AIC scende a 38538 con soli 9 parametri. I coefficienti risultano praticamente invariati, segnale che le due variabili eliminate non contribuivano realmente alla capacità predittiva. Lo stepwise BIC, più conservativo, riduce il modello a 6 parametri eliminando anche Tipo.parto e Ospedale oltre ad Anni.madre e Fumatrici. Mantiene solo Gestazione, Lunghezza, Cranio, Sesso e Numero di gravidanze. Il R² aggiustato scende leggermente a 0.7265, con una perdita minima di varianza spiegata, mentre il BIC migliora a 38592. Questo indica che le variabili rimosse avevano un contributo marginale, ma alcune di esse, come Tipo.parto e Ospedale, mostravano comunque una significatività statistica o una potenziale rilevanza clinica. I modelli con interazioni non mostrano miglioramenti. L’interazione Fumo × Gestazione non è significativa (p=0.256) e il confronto ANOVA rispetto allo stepAIC dà p=0.373. Anche l’interazione Sesso × Gestazione non è significativa (p=0.201) con ANOVA p=0.325. In entrambi i casi non si osserva un incremento di performance né in termini di R² né di criteri informativi, quindi l’effetto dei predittori può essere considerato sostanzialmente costante tra i gruppi. Il modello quadratico, che introduce Gestazione², mostra un termine significativo (p=0.032) e un R² aggiustato leggermente superiore pari a 0.7282, ma il confronto ANOVA rispetto allo stepAIC è borderline (p=0.091) e l’incremento di performance è minimo. Il coefficiente positivo di Gestazione² pari a +1.42 suggerisce una lieve accelerazione della relazione tra settimane di gestazione e peso, coerente biologicamente, ma l’impatto è troppo contenuto per giustificare una maggiore complessità.

Nel complesso, il modello stepwise AIC rappresenta il miglior compromesso tra bontà di adattamento e interpretabilità. Presenta l’AIC più basso tra i modelli semplici, mantiene un R² identico al completo e conserva tutti i predittori rilevanti dal punto di vista teorico e clinico. In questo modello risultano significativi Numero di gravidanze (p=0.004), Gestazione (p<2e-16), Lunghezza (p<2e-16), Cranio (p<2e-16), Tipo di parto (p=0.015), Ospedale livello 3 (p=0.034) e Sesso (p<2e-16), mentre Ospedale livello 2 rimane non significativo (p=0.412). La rimozione del fumo materno, pur essendo controintuitiva rispetto alla letteratura, è giustificata dal p-value non significativo nel modello multivariato (p=0.27) e dalla bassa prevalenza di fumatrici nel campione, pari al 4% (n=104), che limita la potenza statistica. È plausibile che parte dell’effetto del fumo sia mediato da variabili già incluse, come la durata della gestazione o le misure antropometriche.

Analisi della qualità del modello

# METRICHE DI PERFORMANCE
# Calcolo RMSE (Root Mean Squared Error)
residui <- residuals(modello_step_AIC)
RMSE <- sqrt(mean(residui^2))
print(RMSE)
## [1] 273.4227
# R² e R² aggiustato
cat("R²:", summary(modello_step_AIC)$r.squared, "\n")
## R²: 0.7286934
cat("R² aggiustato:", summary(modello_step_AIC)$adj.r.squared, "\n")
## R² aggiustato: 0.7278221
# ANALISI DEI RESIDUI
# Grafici diagnostici standard
par(mfrow = c(2, 2))
plot(modello_step_AIC)

par(mfrow = c(1, 1))

# Test di normalità dei residui - Shapiro-Wilk
set.seed(123)
if(nrow(dati) > 5000) {
  campione_residui <- sample(residui, 5000)
  test_shapiro <- shapiro.test(campione_residui)
} else {
  test_shapiro <- shapiro.test(residui)
}

print(test_shapiro)
## 
##  Shapiro-Wilk normality test
## 
## data:  residui
## W = 0.97408, p-value < 2.2e-16
# Istogramma dei residui
hist(residui, breaks = 50, freq = FALSE, 
     main = "Figura 9: Distribuzione dei Residui", 
     xlab = "Residui", col = "lightblue")
curve(dnorm(x, mean = mean(residui), sd = sd(residui)), 
      add = TRUE, col = "red", lwd = 2)

# Test di omoschedasticità
test_bp <- ncvTest(modello_step_AIC)
print(test_bp)
## Non-constant Variance Score Test 
## Variance formula: ~ fitted.values 
## Chisquare = 31.61595, Df = 1, p = 1.8788e-08
# IDENTIFICAZIONE VALORI INFLUENTI
# Calcolo misure di influenza
influenza <- influence.measures(modello_step_AIC)

# Distanza di Cook
cooksd <- cooks.distance(modello_step_AIC)
soglia_cook <- 4 / nrow(dati)  

punti_influenti <- which(cooksd > soglia_cook)
cat("Numero di punti influenti:", length(punti_influenti), "\n")
## Numero di punti influenti: 116
if(length(punti_influenti) > 0) {
  cat("Indici dei punti più influenti (top 10):\n")
  top_influenti <- order(cooksd, decreasing = TRUE)[1:min(10, length(punti_influenti))]
  print(dati[top_influenti, ])
}
## Indici dei punti più influenti (top 10):
##      Anni.madre N.gravidanze     Fumatrici Gestazione Peso Lunghezza Cranio
## 1551         35            1 Non_fumatrice         38 4370       315    374
## 310          40            3 Non_fumatrice         28 1560       420    379
## 155          30            0 Non_fumatrice         36 3610       410    330
## 1780         25            2 Non_fumatrice         25  900       325    253
## 928          25            0 Non_fumatrice         28  830       310    254
## 1429         24            4 Non_fumatrice         29 1280       390    355
## 2452         28            0 Non_fumatrice         26  930       345    245
## 2437         28            1 Non_fumatrice         27  980       320    265
## 2115         35            1 Non_fumatrice         32 1890       500    309
## 2175         37            8 Non_fumatrice         28  930       355    235
##      Tipo.parto Ospedale Sesso
## 1551        Nat     osp3     F
## 310         Nat     osp3     F
## 155         Nat     osp1     M
## 1780        Nat     osp3     F
## 928         Nat     osp1     F
## 1429        Nat     osp1     F
## 2452        Ces     osp3     F
## 2437        Nat     osp1     M
## 2115        Nat     osp2     F
## 2175        Nat     osp1     F
# Grafico Distanza di Cook
plot(cooksd, type = "h", main = "Figura 10: Distanza di Cook", 
     ylab = "Distanza di Cook", xlab = "Indice Osservazione")
abline(h = soglia_cook, col = "red", lty = 2)

# Leverage (hat values)
lev <- hatvalues(modello_step_AIC)
soglia_lev <- 2 * length(coef(modello_step_AIC)) / nrow(dati)

alta_leva <- which(lev > soglia_lev)
cat("Numero di punti con alta leva:", length(alta_leva), "\n")
## Numero di punti con alta leva: 96
# ANALISI PUNTI INFLUENTI

if(length(punti_influenti) > 0) {
  # Confrontiamo il modello con e senza i punti influenti
  dati_senza_influenti <- dati[-punti_influenti, ]
  modello_senza_influenti <- update(modello_step_AIC, data = dati_senza_influenti)
  
  cat("\nConfronto coefficienti:\n")
  cat("Con punti influenti:\n")
  print(coef(modello_step_AIC))
  cat("\nSenza punti influenti:\n")
  print(coef(modello_senza_influenti))
  
  cat("\nDifferenza R²:\n")
  cat("Con punti influenti:", summary(modello_step_AIC)$r.squared, "\n")
  cat("Senza punti influenti:", summary(modello_senza_influenti)$r.squared, "\n")
  
  # Caratteristiche dei punti influenti
  cat("\nCaratteristiche comuni dei punti influenti:\n")
  print(summary(dati[punti_influenti, ]))
}
## 
## Confronto coefficienti:
## Con punti influenti:
##   (Intercept)  N.gravidanze    Gestazione     Lunghezza        Cranio 
##   -6707.42933      12.36191      31.99091      10.30864      10.49219 
## Tipo.partoNat  Ospedaleosp2  Ospedaleosp3        SessoM 
##      29.28027     -11.02268      28.64080      77.44116 
## 
## Senza punti influenti:
##   (Intercept)  N.gravidanze    Gestazione     Lunghezza        Cranio 
##   -7051.33253      15.35427      30.65896      11.23262      10.28698 
## Tipo.partoNat  Ospedaleosp2  Ospedaleosp3        SessoM 
##      27.34431     -12.34002      19.27847      78.29472 
## 
## Differenza R²:
## Con punti influenti: 0.7286934 
## Senza punti influenti: 0.7724266 
## 
## Caratteristiche comuni dei punti influenti:
##    Anni.madre     N.gravidanze            Fumatrici     Gestazione   
##  Min.   :17.00   Min.   : 0.000   Non_fumatrice:113   Min.   :25.00  
##  1st Qu.:26.00   1st Qu.: 0.000   Fumatrice    :  3   1st Qu.:37.00  
##  Median :30.00   Median : 1.000                       Median :39.00  
##  Mean   :30.16   Mean   : 2.129                       Mean   :37.92  
##  3rd Qu.:34.00   3rd Qu.: 3.000                       3rd Qu.:40.00  
##  Max.   :42.00   Max.   :11.000                       Max.   :43.00  
##       Peso        Lunghezza         Cranio      Tipo.parto Ospedale  Sesso 
##  Min.   : 830   Min.   :310.0   Min.   :235.0   Ces:39     osp1:43   F:59  
##  1st Qu.:2560   1st Qu.:460.0   1st Qu.:320.0   Nat:77     osp2:37   M:57  
##  Median :3405   Median :490.0   Median :340.0              osp3:36         
##  Mean   :3236   Mean   :477.7   Mean   :335.3                              
##  3rd Qu.:3992   3rd Qu.:510.0   3rd Qu.:356.2                              
##  Max.   :4930   Max.   :550.0   Max.   :390.0

Il modello finale mostra performance predittive eccellenti con un R² aggiustato di 0.728 e un errore medio di predizione (RMSE) di 273 grammi, corrispondente all’8.3% del peso medio. Questa accuratezza è molto soddisfacente per un fenomeno biologico complesso come il peso alla nascita, dove numerosi fattori genetici e ambientali non misurati contribuiscono alla variabilità osservata. La diagnostica del modello rivela che le assunzioni fondamentali della regressione lineare sono sostanzialmente rispettate, sebbene con alcune violazioni tecniche che meritano discussione. L’analisi dei grafici diagnostici conferma che le relazioni tra predittori e peso sono appropriatamente modellate come lineari, senza evidenze di pattern curvilinei sistematici nei residui. La verifica della normalità dei residui è stata condotta attraverso due rappresentazioni grafiche complementari: l Q-Q plot il quale mostra che i punti seguono molto bene la linea diagonale per la maggior parte del range, con lievi deviazioni alle estremità che indicano code leggermente più pesanti del normale. L’istogramma dei residui, in Figura 9, conferma questa interpretazione, mostrando una forma approssimativamente normale con una leggera asimmetria verso destra e code più estese rispetto alla curva normale teorica sovrapposta. Il test di Breusch-Pagan indica la presenza di eteroschedasticità, con varianza dei residui che aumenta moderatamente per valori predetti più alti. Questo pattern è biologicamente plausibile: i neonati a termine mostrano maggiore variabilità individuale rispetto ai prematuri, riflettendo una più ampia gamma di influenze genetiche e ambientali. Data l’ampia dimensione campionaria, questa violazione non compromette sostanzialmente la consistenza delle stime dei coefficienti, sebbene gli errori standard potrebbero essere leggermente conservativi. L’analisi della distanza di Cook, mostrata in Figura 10, ha identificato 116 osservazioni influenti, pari al 4.6% del campione. L’esame dettagliato di questi casi rivela che la maggioranza sono neonati estremamente prematuri o con combinazioni inusuali di misure antropometriche. Per valutare l’impatto di questi punti, abbiamo ri-adattato il modello escludendoli e confrontato i coefficienti. La maggior parte delle stime mostra variazioni contenute entro il 10%, confermando la robustezza del modello. Due variabili mostrano cambiamenti più marcati: il numero di gravidanze precedenti varia del 24% e l’effetto dell’ospedale 3 del 33%. Tuttavia, nessun coefficiente cambia direzione e tutte le variabili significative rimangono tali. L’R² aumenta da 0.729 a 0.772 rimuovendo i punti influenti, indicando che i casi estremi sono naturalmente più difficili da predire. Si è scelto di mantenere questi punti influenti nell’analisi finale per diverse ragioni: anzitutto rappresentano casi clinici reali e rilevanti, particolarmente i neonati prematuri che costituiscono una popolazione ad alto rischio di interesse sanitario. Rimuoverli ridurrebbe artificialmente la generalizzabilità del modello. In secondo luogo le variazioni nei coefficienti, sebbene non trascurabili per alcune variabili, non alterano le conclusioni qualitative principali dello studio. Infine rimuovere sistematicamente i casi “difficili” da predire migliorerebbe artificialmente le metriche di performance ma produrrebbe un modello meno utile nella pratica clinica reale.

Previsioni e risultati

lunghezza_media <- mean(dati$Lunghezza)
cranio_medio <- mean(dati$Cranio)

cat("Lunghezza media campionaria:", round(lunghezza_media, 1), "mm\n")
## Lunghezza media campionaria: 494.7 mm
cat("Cranio medio campionario:", round(cranio_medio, 1), "mm\n")
## Cranio medio campionario: 340 mm
# Creazione del nuovo caso con le assunzioni necessarie per le variabili mancanti
nuovo_caso <- data.frame(
  N.gravidanze = 2,              
  Gestazione = 39,               
  Lunghezza = lunghezza_media,   
  Cranio = cranio_medio,         
  Tipo.parto = factor("Nat", levels = levels(dati$Tipo.parto)),  
  Ospedale = factor("osp1", levels = levels(dati$Ospedale)),     
  Sesso = factor("F", levels = levels(dati$Sesso))              
)

# Predizione con intervallo di predizione al 95%
predizione <- predict(modello_step_AIC, 
                     newdata = nuovo_caso, 
                     interval = "prediction", 
                     level = 0.95)

cat("Peso stimato:", round(predizione[1], 0), "grammi\n")
## Peso stimato: 3261 grammi
cat("Intervallo di predizione 95%: [", 
    round(predizione[2], 0), ",", 
    round(predizione[3], 0), "] grammi\n\n")
## Intervallo di predizione 95%: [ 2724 , 3799 ] grammi
ampiezza <- predizione[3] - predizione[2]
cat("Ampiezza intervallo:", round(ampiezza, 0), "grammi\n")
## Ampiezza intervallo: 1075 grammi
cat("Margine di errore: ±", round((predizione[3] - predizione[1]), 0), "grammi\n\n")
## Margine di errore: ± 538 grammi

Per illustrare l’applicazione pratica del modello finale, è stata effettuata una predizione del peso alla nascita per un caso specifico: una neonata femmina di madre alla terza gravidanza (due gravidanze precedenti) con parto previsto alla 39esima settimana di gestazione. Poiché il modello richiede l’inserimento di tutte le variabili predittive e alcune informazioni non erano specificate nel problema (lunghezza fetale, diametro cranico, tipo di parto previsto, e ospedale), sono state adottate le seguenti assunzioni conservative basate sui dati campionari: lunghezza fetale pari alla media campionaria di 494.7 mm, diametro cranico pari alla media di 340.0 mm, parto naturale, e riferimento all’ospedale 1. Queste assunzioni rappresentano uno scenario “tipico” e permettono di ottenere una stima di base, pur riconoscendo che una predizione più accurata richiederebbe la disponibilità di misure ecografiche effettive e informazioni cliniche specifiche. Il modello stima un peso alla nascita di 3261 grammi per questo scenario. L’intervallo di predizione al 95% si estende da 2724 a 3799 grammi, con un’ampiezza complessiva di circa 1075 grammi. Questa ampiezza considerevole riflette l’incertezza intrinseca nella predizione di un singolo caso futuro e incorpora sia l’incertezza delle stime dei coefficienti del modello sia la variabilità biologica individuale osservata nel campione. In termini pratici, questo significa che possiamo essere confidenti al 95% che il peso effettivo della neonata cadrà all’interno di questo intervallo, pur riconoscendo che il valore più probabile si attesta attorno ai 3261 grammi. È importante sottolineare che questa predizione va interpretata come una stima indicativa piuttosto che come un valore deterministico. L’ampio intervallo di predizione evidenzia come, nonostante il modello spieghi circa il 73% della variabilità del peso nel campione, rimanga una sostanziale componente di variabilità individuale che non può essere catturata dalle sole variabili misurate. Fattori genetici, nutrizionali, e altre condizioni materne non osservate contribuiscono a questa incertezza residua. Per applicazioni cliniche reali, la disponibilità di misure ecografiche accurate nelle settimane precedenti al parto e l’informazione sul piano di parto effettivo permetterebbero di ottenere predizioni più precise, riducendo l’ampiezza dell’intervallo e aumentando l’utilità pratica del modello per l’identificazione di situazioni a rischio.

Visualizzazioni

base_profile <- dati[1, ]

base_profile$N.gravidanze <- 1
base_profile$Lunghezza <- mean(dati$Lunghezza)
base_profile$Cranio <- mean(dati$Cranio)
base_profile$Tipo.parto <- levels(dati$Tipo.parto)[1]
base_profile$Ospedale <- levels(dati$Ospedale)[1]
base_profile$Sesso <- levels(dati$Sesso)[1]

gest_range <- seq(25, 43, by = 1)

# Grafico 1: Gestazione per sesso

new_data <- base_profile[rep(1, length(gest_range)*2), ]
new_data$Gestazione <- rep(gest_range, 2)
new_data$Sesso <- rep(levels(dati$Sesso)[1:2], each = length(gest_range))

pred <- predict(modello_step_AIC, newdata = new_data, interval = "confidence")

df_gest <- cbind(new_data[, c("Gestazione","Sesso")],
                 Peso = pred[,1],
                 Lower = pred[,2],
                 Upper = pred[,3])

g1 <- ggplot(df_gest, aes(Gestazione, Peso, color = Sesso, fill = Sesso)) +
  geom_ribbon(aes(ymin = Lower, ymax = Upper), alpha = 0.2, color = NA) +
  geom_line(size = 1.2) +
  labs(title = "Figura 11: Effetto Gestazione sul Peso",
       y = "Peso (g)") + theme_minimal()

print(g1)

# Grafico 2: Effetto fumo
mod_fumo <- update(modello_step_AIC, . ~ . + Fumatrici)

new_data_fumo <- base_profile[rep(1, length(gest_range)*2), ]
new_data_fumo$Gestazione <- rep(gest_range, 2)
new_data_fumo$Fumatrici <- rep(levels(dati$Fumatrici)[1:2],
                               each = length(gest_range))

pred_fumo <- predict(mod_fumo, newdata = new_data_fumo, interval = "confidence")

df_fumo <- cbind(new_data_fumo[, c("Gestazione","Fumatrici")],
                 Peso = pred_fumo[,1],
                 Lower = pred_fumo[,2],
                 Upper = pred_fumo[,3])

g2 <- ggplot(df_fumo, aes(Gestazione, Peso,
                          color = Fumatrici, fill = Fumatrici)) +
  geom_ribbon(aes(ymin = Lower, ymax = Upper), alpha = 0.2, color = NA) +
  geom_line(size = 1.2) +
  labs(title = "Figura 12: Effetto Fumo sul Peso",
       y = "Peso (g)") + theme_minimal()

print(g2)

# Grafico 3: Predetto vs Osservato

dati$Predetto <- predict(modello_step_AIC)

g3 <- ggplot(dati, aes(Predetto, Peso)) +
  geom_point(alpha = 0.3) +
  geom_abline(slope = 1, intercept = 0, linetype = "dashed") +
  geom_smooth(method = "lm", se = TRUE) +
  coord_fixed() +
  labs(title = paste0("Figura 13: Predetto vs Osservato (R² = ",
                      round(summary(modello_step_AIC)$r.squared, 3), ")")) + theme_minimal()

print(g3)

Per comunicare efficacemente i risultati del modello, sono state create tre visualizzazioni chiave che sintetizzano le principali relazioni identificate e la performance predittiva del modello finale.

La Figura 11 illustra l’effetto combinato della durata della gestazione e del sesso del neonato sul peso predetto, mantenendo costanti le altre variabili ai loro valori medi. Le due linee parallele mostrano chiaramente due relazioni fondamentali: 1) Esiste una relazione positiva lineare tra settimane di gestazione e peso, con un incremento di circa 32 grammi per ogni settimana aggiuntiva; 2) I maschi (linea celeste) mantengono sistematicamente un peso superiore di circa 77 grammi rispetto alle femmine (linea rosa) attraverso l’intero range di gestazione osservato. Le bande di confidenza al 95% (aree ombreggiate) sono relativamente strette per il range tipico di gestazione (37-42 settimane), indicando alta precisione delle stime in questo intervallo, mentre diventano progressivamente più ampie agli estremi dove i dati sono più scarsi. Il parallelismo perfetto delle due linee conferma che l’effetto del sesso è additivo e costante, senza interazione con la gestazione.

La Figura 12 presenta il confronto tra neonati di madri fumatrici e non fumatrici attraverso il range di gestazione. A differenza del grafico precedente, qui le bande di confidenza sono molto più ampie e sostanzialmente sovrapposte tra i due gruppi, particolarmente per le fumatrici. Sebbene il modello stimi una riduzione media di circa 30 grammi per i neonati di madri fumatrici (linea rosa leggermente inferiore), questa differenza non raggiunge la significatività statistica (p = 0.27) e le bande di confidenza si sovrappongono completamente. Questo grafico illustra visivamente la principale limitazione dello studio riguardo alla valutazione dell’effetto del fumo: l’ampiezza delle bande di confidenza riflette l’elevata incertezza dovuta alla bassa numerosità di madri fumatrici nel campione (n = 104, 4.2% del totale). La direzione dell’effetto stimato è comunque coerente con l’evidenza scientifica consolidata che documenta un impatto negativo del fumo sul peso fetale, ma la potenza statistica insufficiente impedisce di confermarlo nel campione oggetto di studio.

La Figura 13 valuta la performance complessiva del modello attraverso il confronto tra valori predetti e osservati. I 2500 punti si distribuiscono simmetricamente attorno alla linea di identità (linea rossa tratteggiata che rappresenta la predizione perfetta), con la linea di regressione sovrapposta (blu) che praticamente coincide con quella ideale. Questo pattern conferma che il modello è ben calibrato attraverso l’intero spettro di pesi osservati, senza evidenze di sovrastima o sottostima sistematica in particolari range. La dispersione dei punti attorno alla linea riflette l’errore di predizione (RMSE = 273g) e la componente di variabilità biologica individuale non catturata dal modello.

Conclusioni

Questo studio ha sviluppato un modello di regressione lineare multipla per identificare i fattori predittivi del peso alla nascita in un campione di 2500 neonati da tre ospedali. Il modello finale, selezionato attraverso procedura stepwise basata sul criterio AIC, include sette predittori: settimane di gestazione, lunghezza fetale, diametro cranico, sesso del neonato, numero di gravidanze precedenti, tipo di parto, e ospedale di nascita. Il modello spiega il 72.8% della variabilità nel peso con un errore medio di predizione di 273 grammi.

I risultati confermano che le misure antropometriche fetali (lunghezza e cranio) e la durata della gestazione sono i predittori più forti del peso alla nascita, con effetti robusti e statisticamente significativi. Il dimorfismo sessuale emerge come fattore indipendente e consistente, con i maschi che pesano in media 77 grammi in più delle femmine anche dopo aggiustamento per le dimensioni corporee. La parità materna mostra un effetto modesto ma significativo, coerente con adattamenti fisiologici nelle gravidanze successive.

Una limitazione sostanziale riguarda l’impossibilità di valutare adeguatamente l’effetto del fumo materno, uno degli obiettivi primari dello studio. La bassa prevalenza di fumatrici nel campione (4.2%) ha compromesso la potenza statistica per questa analisi specifica. Sebbene il coefficiente stimato sia nella direzione attesa dalla letteratura (-30g), non raggiunge la significatività statistica. Questo risultato va interpretato come mancanza di evidenza piuttosto che come evidenza di assenza di effetto.

Il modello sviluppato fornisce uno strumento affidabile per la stima del peso alla nascita e l’identificazione di gravidanze a rischio, dimostrando buone capacità predittive e robustezza statistica. Le visualizzazioni prodotte comunicano efficacemente le relazioni identificate sia a audience tecniche che cliniche. Studi futuri dovrebbero garantire campioni più bilanciati di fumatrici e non fumatrici per valutare adeguatamente questo importante fattore di rischio.