1 Introduzione

Il presente progetto ha l’obiettivo di costruire un modello statistico in grado di prevedere il peso dei neonati alla nascita, sulla base di variabili cliniche raccolte da tre ospedali. Il dataset contiene informazioni su 2500 neonati e include variabili relative alla madre, alla gravidanza e al neonato stesso.


2 Caricamento dei dati e pacchetti

# Caricamento pacchetti necessari
library(moments)   # per skewness e kurtosis
library(lmtest)    # per bptest e dwtest
library(car)       # per vif e outlierTest
library(MASS)      # per stepAIC
library(ggplot2)   # per i grafici

# Caricamento dataset
dati = read.csv("neonati.csv", stringsAsFactors = TRUE)

# Prima esplorazione
head(dati)
##   Anni.madre N.gravidanze Fumatrici Gestazione Peso Lunghezza Cranio Tipo.parto
## 1         26            0         0         42 3380       490    325        Nat
## 2         21            2         0         39 3150       490    345        Nat
## 3         34            3         0         38 3640       500    375        Nat
## 4         28            1         0         41 3690       515    365        Nat
## 5         20            0         0         38 3700       480    335        Nat
## 6         32            0         0         40 3200       495    340        Nat
##   Ospedale Sesso
## 1     osp3     M
## 2     osp1     F
## 3     osp2     M
## 4     osp2     M
## 5     osp3     F
## 6     osp2     F
str(dati)
## 'data.frame':    2500 obs. of  10 variables:
##  $ Anni.madre  : int  26 21 34 28 20 32 26 25 22 23 ...
##  $ N.gravidanze: int  0 2 3 1 0 0 1 0 1 0 ...
##  $ Fumatrici   : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Gestazione  : int  42 39 38 41 38 40 39 40 40 41 ...
##  $ Peso        : int  3380 3150 3640 3690 3700 3200 3100 3580 3670 3700 ...
##  $ Lunghezza   : int  490 490 500 515 480 495 480 510 500 510 ...
##  $ Cranio      : int  325 345 375 365 335 340 345 349 335 362 ...
##  $ Tipo.parto  : Factor w/ 2 levels "Ces","Nat": 2 2 2 2 2 2 2 2 1 1 ...
##  $ Ospedale    : Factor w/ 3 levels "osp1","osp2",..: 3 1 2 2 3 2 3 1 2 2 ...
##  $ Sesso       : Factor w/ 2 levels "F","M": 2 1 2 2 1 1 1 2 1 1 ...

3 Analisi Descrittiva

3.1 Statistiche di sintesi

summary(dati)
##    Anni.madre     N.gravidanze       Fumatrici        Gestazione   
##  Min.   : 0.00   Min.   : 0.0000   Min.   :0.0000   Min.   :25.00  
##  1st Qu.:25.00   1st Qu.: 0.0000   1st Qu.:0.0000   1st Qu.:38.00  
##  Median :28.00   Median : 1.0000   Median :0.0000   Median :39.00  
##  Mean   :28.16   Mean   : 0.9812   Mean   :0.0416   Mean   :38.98  
##  3rd Qu.:32.00   3rd Qu.: 1.0000   3rd Qu.:0.0000   3rd Qu.:40.00  
##  Max.   :46.00   Max.   :12.0000   Max.   :1.0000   Max.   :43.00  
##       Peso        Lunghezza         Cranio    Tipo.parto Ospedale   Sesso   
##  Min.   : 830   Min.   :310.0   Min.   :235   Ces: 728   osp1:816   F:1256  
##  1st Qu.:2990   1st Qu.:480.0   1st Qu.:330   Nat:1772   osp2:849   M:1244  
##  Median :3300   Median :500.0   Median :340              osp3:835           
##  Mean   :3284   Mean   :494.7   Mean   :340                                 
##  3rd Qu.:3620   3rd Qu.:510.0   3rd Qu.:350                                 
##  Max.   :4930   Max.   :565.0   Max.   :390

3.2 Distribuzione della variabile risposta: Peso

par(mfrow = c(1, 2))
hist(dati$Peso, 
     main = "Distribuzione del Peso", 
     xlab = "Peso (g)", 
     col = "lightblue", 
     border = "white")
plot(density(dati$Peso), 
     main = "Densità del Peso", 
     xlab = "Peso (g)", 
     col = "steelblue", 
     lwd = 2)

par(mfrow = c(1, 1))

# Indici di forma
cat("Skewness:", skewness(dati$Peso), "\n")
## Skewness: -0.6470308
cat("Curtosi in eccesso:", kurtosis(dati$Peso) - 3, "\n")
## Curtosi in eccesso: 2.031532
# Test di normalità
shapiro.test(dati$Peso)
## 
##  Shapiro-Wilk normality test
## 
## data:  dati$Peso
## W = 0.97066, p-value < 2.2e-16

La variabile risposta Peso presenta una distribuzione approssimativamente normale, condizione importante per procedere con la regressione lineare.

3.3 Boxplot delle variabili quantitative

par(mfrow = c(2, 3))
boxplot(dati$Peso,       main = "Peso (g)",          col = "lightblue")
boxplot(dati$Lunghezza,  main = "Lunghezza (mm)",    col = "lightgreen")
boxplot(dati$Cranio,     main = "Cranio (mm)",       col = "lightyellow")
boxplot(dati$Gestazione, main = "Gestazione (sett)", col = "lightpink")
boxplot(dati$Anni.madre, main = "Età madre",         col = "lavender")
boxplot(dati$N.gravidanze, main = "N. gravidanze",   col = "peachpuff")

par(mfrow = c(1, 1))

3.4 Variabili qualitative: frequenze

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

4 Test di Ipotesi

4.1 Test 1 — Differenze nei parti cesarei tra ospedali

Vogliamo verificare se la proporzione di parti cesarei varia significativamente tra i tre ospedali.

H0: La proporzione di parti cesarei è uguale nei tre ospedali
H1: Almeno un ospedale ha una proporzione diversa

# Tabella di contingenza
tab_parto_osp = table(dati$Ospedale, dati$Tipo.parto)
tab_parto_osp
##       
##        Ces Nat
##   osp1 242 574
##   osp2 254 595
##   osp3 232 603
# Frequenze relative per ospedale
prop.table(tab_parto_osp, margin = 1)
##       
##              Ces       Nat
##   osp1 0.2965686 0.7034314
##   osp2 0.2991755 0.7008245
##   osp3 0.2778443 0.7221557
# Visualizzazione
barplot(prop.table(tab_parto_osp, margin = 1),
        beside = TRUE,
        legend.text = rownames(tab_parto_osp),
        col = c("steelblue", "tomato", "seagreen"),
        main = "Proporzione tipo di parto per ospedale",
        xlab = "Tipo di parto",
        ylab = "Proporzione")

# Test chi-quadro
chisq.test(tab_parto_osp)
## 
##  Pearson's Chi-squared test
## 
## data:  tab_parto_osp
## X-squared = 1.0972, df = 2, p-value = 0.5778

Se il p-value è inferiore a 0.05, si rifiuta H0: esistono differenze statisticamente significative nella proporzione di parti cesarei tra i tre ospedali.


4.2 Test 2 — Confronto media Peso e Lunghezza con i valori di riferimento della popolazione

Si assume che nella popolazione generale il peso medio alla nascita sia 3300 g e la lunghezza media sia 500 mm. Vogliamo verificare se le medie del nostro campione sono significativamente diverse da questi valori.

4.2.1 Peso

H0: μ_Peso = 3300 g
H1: μ_Peso ≠ 3300 g

t.test(dati$Peso, 
       mu = 3300, 
       conf.level = 0.95, 
       alternative = "two.sided")
## 
##  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

4.2.2 Lunghezza

H0: μ_Lunghezza = 500 mm
H1: μ_Lunghezza ≠ 500 mm

t.test(dati$Lunghezza, 
       mu = 500, 
       conf.level = 0.95, 
       alternative = "two.sided")
## 
##  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

Dalla lettura del p-value si determina se le medie del campione sono o meno significativamente uguali a quelle della popolazione di riferimento.


4.3 Test 3 — Differenze antropometriche tra i due sessi

Vogliamo verificare se Peso, Lunghezza e Cranio differiscono significativamente tra maschi e femmine.

# Boxplot per variabile e sesso
par(mfrow = c(1, 3))
boxplot(Peso      ~ Sesso, data = dati, main = "Peso per Sesso",      col = c("pink","lightblue"))
boxplot(Lunghezza ~ Sesso, data = dati, main = "Lunghezza per Sesso", col = c("pink","lightblue"))
boxplot(Cranio    ~ Sesso, data = dati, main = "Cranio per Sesso",    col = c("pink","lightblue"))

par(mfrow = c(1, 1))

# T test indipendente per ciascuna variabile
# H0: le medie dei due sessi sono uguali
# H1: le medie dei due sessi sono diverse

cat("--- Peso ---\n")
## --- Peso ---
t.test(Peso ~ Sesso, data = dati, alternative = "two.sided")
## 
##  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
cat("--- Lunghezza ---\n")
## --- Lunghezza ---
t.test(Lunghezza ~ Sesso, data = dati, alternative = "two.sided")
## 
##  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
cat("--- Cranio ---\n")
## --- Cranio ---
t.test(Cranio ~ Sesso, data = dati, alternative = "two.sided")
## 
##  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

Se i p-value risultano inferiori a 0.05, si rifiuta H0: le misure antropometriche sono significativamente diverse tra maschi e femmine.


5 Matrice di Correlazione

Prima di costruire il modello di regressione, analizziamo le correlazioni tra le variabili quantitative.

# Selezioniamo solo le variabili numeriche
dati_num = dati[, c("Anni.madre", "N.gravidanze", "Gestazione", "Peso", "Lunghezza", "Cranio")]

# Matrice di correlazione
round(cor(dati_num), 2)
##              Anni.madre N.gravidanze Gestazione  Peso Lunghezza Cranio
## Anni.madre         1.00         0.38      -0.14 -0.02     -0.06   0.02
## N.gravidanze       0.38         1.00      -0.10  0.00     -0.06   0.04
## Gestazione        -0.14        -0.10       1.00  0.59      0.62   0.46
## Peso              -0.02         0.00       0.59  1.00      0.80   0.70
## Lunghezza         -0.06        -0.06       0.62  0.80      1.00   0.60
## Cranio             0.02         0.04       0.46  0.70      0.60   1.00
# Funzione per visualizzare le correlazioni nella matrice pairs
panel.cor <- function(x, y, digits = 2, prefix = "", cex.cor, ...) {
  par(usr = c(0, 1, 0, 1))
  r   <- abs(cor(x, y))
  txt <- format(c(r, 0.123456789), digits = digits)[1]
  txt <- paste0(prefix, txt)
  if (missing(cex.cor)) cex.cor <- 0.8 / strwidth(txt)
  text(0.5, 0.5, txt, cex = cex.cor * r)
}

pairs(dati_num, 
      upper.panel = panel.smooth, 
      lower.panel = panel.cor,
      main = "Matrice di Correlazione e Scatterplot")


6 Modello di Regressione Lineare Multipla

6.1 Modello completo

Inseriamo tutte le variabili nel modello di partenza.

n = nrow(dati)

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

summary(mod1)
## 
## 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 *  
## Fumatrici       -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

6.2 Selezione automatica del modello (stepwise BIC)

Utilizziamo la procedura stepwise con criterio BIC per selezionare il modello più parsimonioso.

stepwise.mod = MASS::stepAIC(mod1,
                              direction = "both",
                              k = log(n),   # BIC
                              trace = FALSE)

summary(stepwise.mod)
## 
## 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

6.3 Confronto AIC e BIC tra modelli

# Definiamo il modello ridotto sulla base della stepwise
mod_fin = stepwise.mod

AIC(mod1, mod_fin)
##         df      AIC
## mod1    12 35171.95
## mod_fin  7 35179.33
BIC(mod1, mod_fin)
##         df      BIC
## mod1    12 35241.84
## mod_fin  7 35220.10

Il modello selezionato in modo automatico minimizza il BIC, garantendo un buon equilibrio tra fit e parsimonia.

6.4 Valutazione della multicollinearità (VIF)

vif(mod_fin)
## N.gravidanze   Gestazione    Lunghezza       Cranio        Sesso 
##     1.023475     1.669189     2.074689     1.624465     1.040054

Valori di VIF inferiori a 5 indicano l’assenza di problemi di multicollinearità.


7 Analisi dei Residui

7.1 Grafici diagnostici

par(mfrow = c(2, 2))
plot(mod_fin)

par(mfrow = c(1, 1))

7.2 Test sui residui

# Normalità dei residui
shapiro.test(residuals(mod_fin))
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(mod_fin)
## W = 0.97408, p-value < 2.2e-16
# Omoschedasticità (varianza costante) — Breusch-Pagan
bptest(mod_fin)
## 
##  studentized Breusch-Pagan test
## 
## data:  mod_fin
## BP = 90.253, df = 5, p-value < 2.2e-16
# Indipendenza dei residui — Durbin-Watson
dwtest(mod_fin)
## 
##  Durbin-Watson test
## 
## data:  mod_fin
## DW = 1.9535, p-value = 0.1224
## alternative hypothesis: true autocorrelation is greater than 0
  • Shapiro-Wilk: se p > 0.05, i residui sono normali
  • Breusch-Pagan: se p > 0.05, la varianza è costante (omoschedasticità)
  • Durbin-Watson: se p > 0.05, i residui non sono autocorrelati

7.3 Valori di Leva (Leverage)

lev   = hatvalues(mod_fin)
p     = sum(lev)
soglia = 2 * p / n

plot(lev, 
     main = "Valori di Leva", 
     ylab = "Leverage", 
     pch  = 20, 
     col  = "steelblue")
abline(h = soglia, col = 2, lty = 2)

# Osservazioni con leverage elevato
cat("Osservazioni con leverage elevato:\n")
## Osservazioni con leverage elevato:
which(lev > soglia)
##   13   15   34   67   89   96  101  106  131  134  151  155  161  189  190  204 
##   13   15   34   67   89   96  101  106  131  134  151  155  161  189  190  204 
##  205  206  220  294  305  310  312  315  378  440  442  445  486  492  497  516 
##  205  206  220  294  305  310  312  315  378  440  442  445  486  492  497  516 
##  582  587  592  614  638  656  657  684  697  702  729  748  750  757  765  805 
##  582  587  592  614  638  656  657  684  697  702  729  748  750  757  765  805 
##  828  893  895  913  928  946  947  956  985 1008 1014 1049 1067 1091 1106 1130 
##  828  893  895  913  928  946  947  956  985 1008 1014 1049 1067 1091 1106 1130 
## 1166 1181 1188 1200 1219 1238 1248 1273 1291 1293 1311 1321 1325 1356 1357 1385 
## 1166 1181 1188 1200 1219 1238 1248 1273 1291 1293 1311 1321 1325 1356 1357 1385 
## 1395 1400 1402 1411 1420 1428 1429 1450 1505 1551 1553 1556 1573 1593 1606 1610 
## 1395 1400 1402 1411 1420 1428 1429 1450 1505 1551 1553 1556 1573 1593 1606 1610 
## 1617 1619 1628 1686 1693 1701 1712 1718 1727 1735 1780 1781 1809 1827 1868 1892 
## 1617 1619 1628 1686 1693 1701 1712 1718 1727 1735 1780 1781 1809 1827 1868 1892 
## 1962 1967 1977 2037 2040 2046 2086 2089 2098 2114 2115 2120 2140 2146 2148 2149 
## 1962 1967 1977 2037 2040 2046 2086 2089 2098 2114 2115 2120 2140 2146 2148 2149 
## 2157 2175 2200 2215 2216 2220 2221 2224 2225 2244 2257 2307 2317 2318 2337 2359 
## 2157 2175 2200 2215 2216 2220 2221 2224 2225 2244 2257 2307 2317 2318 2337 2359 
## 2408 2422 2436 2437 2452 2458 2471 2478 
## 2408 2422 2436 2437 2452 2458 2471 2478

7.4 Outlier

# Residui studentizzati
plot(rstudent(mod_fin), 
     main = "Residui Studentizzati", 
     ylab = "r studentizzato", 
     pch  = 20, 
     col  = "steelblue")
abline(h = c(-2, 2), col = 2, lty = 2)

# Test formale per outlier
car::outlierTest(mod_fin)
##       rstudent unadjusted p-value Bonferroni p
## 1551 10.051908         2.4906e-23   6.2265e-20
## 155   5.027798         5.3138e-07   1.3285e-03
## 1306  4.827238         1.4681e-06   3.6702e-03

7.5 Distanza di Cook

cook = cooks.distance(mod_fin)
plot(cook, 
     main = "Distanza di Cook", 
     ylab = "Cook's Distance", 
     pch  = 20, 
     col  = "steelblue")
abline(h = 0.5, col = "orange", lty = 2)
abline(h = 1.0, col = "red",    lty = 2)

Valori di Cook superiori a 0.5 (soglia di attenzione) o a 1 (soglia critica) indicano osservazioni fortemente influenti sul modello.


8 Previsioni

Stimiamo il peso di una neonata femmina da una madre alla terza gravidanza, non fumatrice, che partorirà alla 39esima settimana in modo naturale all’ospedale 1. Usiamo i valori medi di lunghezza e cranio per le femmine.

# Valori medi di riferimento per una femmina
media_lunghezza_F = mean(dati$Lunghezza[dati$Sesso == "F"])
media_cranio_F    = mean(dati$Cranio[dati$Sesso == "F"])
media_anni_madre  = mean(dati$Anni.madre)

nuova_obs = data.frame(
  Anni.madre   = media_anni_madre,
  N.gravidanze = 3,
  Fumatrici    = 0,
  Gestazione   = 39,
  Lunghezza    = media_lunghezza_F,
  Cranio       = media_cranio_F,
  Tipo.parto   = factor("Nat", levels = levels(dati$Tipo.parto)),
  Ospedale     = factor("osp1", levels = levels(dati$Ospedale)),
  Sesso        = factor("F", levels = levels(dati$Sesso))
)

previsione = predict(mod_fin, newdata = nuova_obs, interval = "prediction", level = 0.95)
cat("Peso previsto:", round(previsione[1], 0), "g\n")
## Peso previsto: 3195 g
cat("Intervallo di previsione al 95%: [", round(previsione[2], 0), ",", round(previsione[3], 0), "] g\n")
## Intervallo di previsione al 95%: [ 2656 , 3734 ] g

9 Visualizzazioni

9.1 Effetto delle settimane di gestazione e del fumo sul peso

ggplot(data = dati) +
  geom_point(aes(x = Gestazione, y = Peso, col = factor(Fumatrici)), 
             alpha = 0.4, size = 1.5) +
  geom_smooth(aes(x = Gestazione, y = Peso, col = factor(Fumatrici)), 
              method = "lm", se = FALSE) +
  scale_color_manual(values = c("steelblue", "tomato"),
                     labels = c("Non fumatrice", "Fumatrice"),
                     name   = "Fumo materno") +
  labs(title = "Effetto della gestazione e del fumo sul peso",
       x = "Settimane di gestazione",
       y = "Peso (g)") +
  theme_minimal()

9.2 Peso per sesso e ospedale

ggplot(data = dati) +
  geom_boxplot(aes(x = Ospedale, y = Peso, fill = Sesso), alpha = 0.7) +
  scale_fill_manual(values = c("pink", "lightblue")) +
  labs(title = "Distribuzione del peso per ospedale e sesso",
       x = "Ospedale", y = "Peso (g)") +
  theme_minimal()


10 Conclusioni

Il modello di regressione lineare multipla selezionato permette di spiegare una parte significativa della variabilità del peso neonatale. Le variabili risultate più predittive sono:

  • Settimane di gestazione: maggiore la durata, maggiore il peso
  • Lunghezza e diametro del cranio: strettamente correlate al peso
  • Sesso del neonato: i maschi tendono ad avere peso maggiore
  • Fumo materno: associato a una riduzione del peso alla nascita

L’analisi dei residui ha confermato la bontà del modello: normalità, omoschedasticità e assenza di autocorrelazione. I valori influenti individuati (leverage, outlier, distanza di Cook) non compromettono la stabilità delle stime.

Le previsioni prodotte possono supportare il personale clinico nella gestione proattiva delle gravidanze a rischio. ```