Step 1 - Raccolta dei Dati e Struttura del Dataset

kable(summary(neonati))
Anni.madre N.gravidanze Fumatrici Gestazione Peso Lunghezza Cranio Tipo.parto Ospedale Sesso
Min. : 0.00 Min. : 0.0000 Min. :0.0000 Min. :25.00 Min. : 830 Min. :310.0 Min. :235 Length:2500 Length:2500 Length:2500
1st Qu.:25.00 1st Qu.: 0.0000 1st Qu.:0.0000 1st Qu.:38.00 1st Qu.:2990 1st Qu.:480.0 1st Qu.:330 Class :character Class :character Class :character
Median :28.00 Median : 1.0000 Median :0.0000 Median :39.00 Median :3300 Median :500.0 Median :340 Mode :character Mode :character Mode :character
Mean :28.16 Mean : 0.9812 Mean :0.0416 Mean :38.98 Mean :3284 Mean :494.7 Mean :340 NA NA NA
3rd Qu.:32.00 3rd Qu.: 1.0000 3rd Qu.:0.0000 3rd Qu.:40.00 3rd Qu.:3620 3rd Qu.:510.0 3rd Qu.:350 NA NA NA
Max. :46.00 Max. :12.0000 Max. :1.0000 Max. :43.00 Max. :4930 Max. :565.0 Max. :390 NA NA NA

È stato effettuato un controllo preliminare sulla presenza di dati mancanti all’interno del dataset e non sono stati rilevati valori mancanti.

Come possiamo notare il dataset è composto da 2500 osservazioni e 10 variabili riguardanti dei neonati e le loro madri, in particolare:

neonati$Fumatrici <- factor(neonati$Fumatrici, levels = c(0,1), labels = c("NO", "SI"))
neonati$Tipo.parto <- as.factor(neonati$Tipo.parto)
neonati$Ospedale <- as.factor(neonati$Ospedale)
neonati$Sesso <- as.factor(neonati$Sesso)

neonati$Anni.madre[neonati$Anni.madre %in% c(0,1)] <- 28

Procedo a convertire in fattori le variabili qualitative del dataset. Inoltre analizzando il dataset ho riscontrato che sono presenti due osservazioni Anni.madre con un’età riportata in modo errato, ossia pari ad 1 e a 0. Poiché gli altri dati sembrano corretti, possiamo assumere che si tratti di errori e sostituirli con il valore mediano dell’età.

Step 2 - Analisi e Modellizzazione

2.1 - Analisi Preliminare

# Funzione per calcolare l'indice di Gini normalizzato
gini.index <- function(x){
  ni = table(x)
  fi = ni / length(x)
  fi2 = fi^2
  J = length(table(x))
  gini = 1 - sum(fi2)
  gini.norm = gini / ((J - 1) / J)
  return(round(gini.norm, 2))
}
# Funzione per calcolare le statistiche delle variabili numeriche
calculate_numeric_stats <- function(x) {
  stats <- c(
    min = min(x),
    Q1 = quantile(x)[2],
    Q2 = quantile(x)[3],
    Q3 = quantile(x)[4],
    max = max(x),
    mean = mean(x),
    median = median(x),
    std_dev = sd(x),
    CV = sd(x) / mean(x) * 100,
    skewness = moments::skewness(x),
    kurtosis = moments::kurtosis(x)-3,
    gini = gini.index(x)
  )
  return(round(stats, 2))
}

# Funzione per calcolare le statistiche delle variabili qualitative
calculate_categorical_stats <- function(x, nome_var = "Variabile") {
  freq <- table(x)
  freq_rel <- prop.table(freq)

  freq_df <- data.frame(
    Categoria = names(freq),
    Fr_Abs = as.integer(freq),
    Fr_Rel = round(as.numeric(freq_rel), 2)
  )
  colnames(freq_df) <- c(nome_var, "Fr. Assoluta", "Fr. Relativa")
  kable(freq_df) %>%
    kable_styling(full_width = FALSE, position = "left")
}
kable(numeric_stats_df)
min Q1.25% Q2.50% Q3.75% max mean median std_dev CV skewness kurtosis gini
Anni.madre 13 25 28 32 46 28.19 28 5.22 18.50 0.15 -0.10 0.97
Gestazione 25 38 39 40 43 38.98 39 1.87 4.79 -2.07 8.26 0.85
N.gravidanze 0 0 1 1 12 0.98 1 1.28 130.51 2.51 10.99 0.73
Cranio 235 330 340 350 390 340.03 340 16.43 4.83 -0.79 2.95 0.97
Lunghezza 310 480 500 510 565 494.69 500 26.32 5.32 -1.51 6.49 0.94
Peso 830 2990 3300 3620 4930 3284.08 3300 525.04 15.99 -0.65 2.03 1.00

La tabella riassume le principali statistiche descrittive per sei variabili del dataset neonatale. L’età delle madri varia da 13 a 46 anni, con una media di 28 anni e una distribuzione simmetrica (skewness ≈ 0). La gestazione mostra una media di 39 settimane, con una bassa variabilità (CV = 4,79%) e una distribuzione leggermente negativa ma molto leptocurtica (kurtosis = 8,26), indicando una forte concentrazione attorno alla media.

Il numero di gravidanze è in media vicino a 1, ma con una forte asimmetria positiva (skewness = 2,51) e una variabilità elevata (CV = 130,51%), suggerendo la presenza di pochi casi con molte gravidanze. Le misure antropometriche del neonato (cranio, lunghezza e peso) mostrano distribuzioni tendenzialmente simmetriche o leggermente negative, con valori medi rispettivamente di 340 mm per la circonferenza cranica, 495 mm per la lunghezza e 3284 grammi per il peso.

Le variabili Peso e Lunghezza presentano una dispersione moderata (CV intorno al 5%), mentre Cranio è la più concentrata. Il coefficiente di Gini, che misura l’ineguaglianza, è massimo per il Peso (1,00) e minimo per Gestazione (0,85), coerente con la maggiore regolarità del periodo gestazionale rispetto alla variabilità nei parametri neonatali.

calculate_categorical_stats(Sesso, "Sesso")
Sesso Fr. Assoluta Fr. Relativa
F 1256 0.5
M 1244 0.5
calculate_categorical_stats(Fumatrici, "Fumatrici")
Fumatrici Fr. Assoluta Fr. Relativa
0 2396 0.96
1 104 0.04
calculate_categorical_stats(Tipo.parto, "Tipo.Parto")
Tipo.Parto Fr. Assoluta Fr. Relativa
Ces 728 0.29
Nat 1772 0.71
calculate_categorical_stats(Ospedale, "Ospedale")
Ospedale Fr. Assoluta Fr. Relativa
osp1 816 0.33
osp2 849 0.34
osp3 835 0.33

La distribuzione della variabile Sesso mostra una popolazione neonatale equamente suddivisa tra femmine e maschi, indicando un perfetto bilanciamento tra i sessi nel campione analizzato.

Per quanto riguarda il comportamento materno, solo il 4% delle madri dichiara di essere fumatrici durante la gravidanza, mentre la stragrande maggioranza (96%) non fuma, evidenziando una tendenza positiva in termini di salute prenatale.

La variabile Tipo.parto evidenzia che il 71% dei parti è avvenuto in modo naturale, mentre il 29% tramite cesareo. Questa distribuzione suggerisce che, pur essendo il parto cesareo frequente, rimane meno comune rispetto al parto naturale.

Infine, la variabile Ospedale indica una distribuzione equilibrata dei parti tra le tre strutture ospedaliere: osp1 (33%), osp2 (34%) e osp3 (33%). Questa omogeneità suggerisce un’equa distribuzione dei casi tra i tre centri.

Test Statistici

# Test Chi-quadrato
tab_parto_ospedale <- table(Tipo.parto, Ospedale)
chi_test <- chisq.test(tab_parto_ospedale)

Test del Chi-quadrato

  • Statistica: 1.1
  • Gradi di libertà: 2
  • p_value: 0.578

Il test del Chi-quadrato non ha rilevato un’associazione significativa tra il tipo di parto e l’ospedale (p-value = 0,578). Di conseguenza, la distribuzione del tipo di parto risulta simile tra i diversi ospedali, senza differenze statisticamente significative.

Attraverso una ricerca online, sono stati reperiti i seguenti dati medi di riferimento per il peso e la lunghezza dei neonati, utili per confrontare i nostri risultati:

  • Peso medio alla nascita della popolazione: 3300 g

  • Lunghezza media alla nascita della popolazione: 500 mm

Fonte

# test t con la popolazione media
test_peso <- t.test(Peso, mu = 3300, alternative = "two.sided")
test_lunghezza <- t.test(Lunghezza, mu = 500, alternative = "two.sided")
Test t con la popolazione media
Peso
  • Media campionaria: 3284.08
  • Statistica t: -1.52
  • Intervallo di confidenza al 95%: [3263.49; 3304.67]
  • p_value:0.13
Lunghezza
  • Media campionaria: 494.7
  • Statistica t: -10.084
  • Intervallo di confidenza al 95%: [493.7; 495.7]
  • p_value: <0.001

Il peso medio dei neonati (3284,08 g) non presenta una differenza significativa rispetto alla media teorica della popolazione, con un valore di p-value pari a 0,13. Pertanto, non si può rifiutare l’ipotesi nulla.

La lunghezza media dei neonati (494,70 mm), invece, risulta significativamente inferiore alla media ipotizzata di 500 mm (p < 0,001), portando al rifiuto dell’ipotesi nulla.

weight <- extract_info(t.test(Peso ~ Sesso, data = neonati))
length <- extract_info(t.test(Lunghezza ~ Sesso, data = neonati))
head <- extract_info(t.test(Cranio ~ Sesso, data = neonati))

Test t tra sessi

Peso

  • Media Femmine: 3161.1
  • Media Maschi: 3408.2
  • Statistica t: -12.106
  • Intervallo di confidenza al 95%: [-287.1; -207.1]
  • p_value: <0.001

Lunghezza

  • Media Femmine: 489.8
  • Media Maschi: 499.7
  • Statistica t: -9.582
  • Intervallo di confidenza al 95%: [-11.9; -7.9]
  • p_value: <0.001

Circonferenza cranica

  • Media Femmine: 337.6
  • Media Maschi: 342.4
  • Statistica t: -7.41
  • Intervallo di confidenza al 95%: [-6.1; -3.5]
  • p_value: <0.001

I neonati di sesso maschile presentano un peso medio significativamente superiore rispetto a quelli di sesso femminile (p < 0,001), con una differenza media di 247 grammi.

Anche la lunghezza media alla nascita risulta maggiore nei maschi rispetto alle femmine, con una differenza statisticamente significativa (p < 0,001).

Lo stesso vale per la circonferenza cranica media, che nei maschi è significativamente più elevata rispetto alle femmine (p < 0,001).

# Funzione per mostrare la correlazione tra variabili
panel.cor <- function(x, y, digits = 2, prefix = "", cex.cor, ...) {
  par(usr = c(0, 1, 0, 1))
  r <- 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, col = "red")
}

pairs(neonati, lower.panel = panel.cor, upper.panel = panel.smooth)

Dal grafico si osserva che le variabili maggiormente correlate al peso del neonato sono la Lunghezza (r = 0,80) e il Cranio (r = 0,70), entrambe con correlazioni positive e di intensità elevata. Questi risultati confermano la coerenza attesa tra le principali misure antropometriche alla nascita.

# Shapiro-Wilk test per verificare la normalità della variabile Peso
test_norm_peso <- shapiro.test(Peso)

Test di normalità di Shapiro-Wilk sulla distribuzione del peso

  • Statistica W: 0.97
  • p_value: <0.001

Il test ha rilevato che la variabile non segue una distribuzione normale.

2.2 - Creazione del Modello di Regressione

# Creazione del primo modello di regressione
mod1 <- lm(Peso ~ . -Tipo.parto -Ospedale, data = neonati)
Coefficiente del modello di regressione lineare
Coefficiente Estimate Std. Error t value p_value Significance
(Intercept) -6711.54 141.25 -47.51 <0.001 ***
Anni.madre 0.88 1.15 0.76 0.4452
N.gravidanze 11.40 4.67 2.44 0.0148
FumatriciSI -30.29 27.60 -1.10 0.2726
Gestazione 32.89 3.83 8.60 <0.001 ***
Lunghezza 10.23 0.30 34.01 <0.001 ***
Cranio 10.52 0.43 24.64 <0.001 ***
SessoM 78.09 11.20 6.97 <0.001 ***

Per prevedere il peso di un neonato, costruiamo un modello di regressione lineare multipla, inizialmente con tutte le variabili ad esclusione però di Tipo.parto e Ospedale, in quanto non sono logicamente rilevanti per la previsione del peso alla nascita.

Le variabili N.gravidanze, Gestazione, Lunghezza, Cranio e SessoM sono risultate statisticamente significative, con dei p-value molto bassi. Segnaliamo in particolare le variabili Lunghezzae Cranio che hanno t-value elevati.

Al contrario, le variabili Anni.madre e Fumatrici non sono risultate significative nel modello, indicando che non hanno un impatto rilevante sul peso del neonato.

Il valore dell’R² aggiustato ottenuto è pari 0,7264, il che significa che il modello spiega circa il 73% della variabilità del peso di un neonato, un risultato sufficiente ma non del tutto soddisfacente. L’F-statistic è pari 949 con un p-value < 2.2e-16, indicando che il modello è statisticamente significativo.

2.3 - Selezione del Modello Ottimale

Per provare a migliorare il modello, procediamo rimuovendo alcune variabili con il metodo di selezione Stepwise, eliminando quindi le variabili con p-value elevato Anni.madre e Fumatrici.

mod2 <- update(mod1, ~ . -Anni.madre -Fumatrici)
Coefficiente del modello di regressione lineare
Coefficiente Estimate Std. Error t value p_value Significance
(Intercept) -6681.14 135.72 -49.23 < 0.001 ***
N.gravidanze 12.47 4.34 2.87 0.00408 **
Gestazione 32.33 3.80 8.51 < 0.001 ***
Lunghezza 10.25 0.30 34.09 < 0.001 ***
Cranio 10.54 0.43 24.73 < 0.001 ***
SessoM 77.99 11.20 6.96 < 0.001 ***

L’R² aggiustato è rimasto pressochè identico, ossia pari a 0,7265.

Per verificare la validità del modello, utilizziamo la funzione anova(), che confronta i modelli e fornisce il p-value dell’F-statistic.

# Confronto ANOVA tra mod1 e mod2
anova_df <- anova(mod1, mod2)
Confronto tra modelli tramite ANOVA
Modello RSS RSS residui Gradi di libertà Sum of Sq F value p-value
1 2492 187929681 NA NA NA NA
2 2494 188065546 -2 -135865.2 0.901 0.406

Il p-value, pari a 0,406, non risulta significativo, procediamo quindi al calcolo e al confronto dei valori BIC dei due modelli.

# Calcolo e confronto dei valori BIC per mod1 e mod2
bic_values <- BIC(mod1, mod2)
BIC tra mod1 e mod2
df BIC
mod1 9 35233.94
mod2 7 35220.10

In questo caso, il BIC di mod2 risulta pari a 35220,10, inferiore (e quindi preferibile) rispetto al BIC di mod1, pari invece a 35233,94.

Possiamo ora verificare il VIF del modello ottimizzato nella tabella seguente:

vif_mod <- car::vif(mod2)
Valori di VIF per il modello di regressione
Variabile VIF
N.gravidanze 1.023
Gestazione 1.669
Lunghezza 2.075
Cranio 1.624
Sesso 1.040

Essendo inferiore a 5 per ogni variabile, non sono presenti problemi di multicollinearità.

Selezioniamo mod2 per la sua maggiore semplicità e solidità.

Approfondiamo inoltre la possibilità che alcune variabili esplicative influenzino il peso del neonato in modo non lineare, in particolare consideriamo i termini di interazione tra le variabili Gestazione e Lunghezza, e tra Gestazione e Cranio.

mod3 <- update(mod2, ~ . + Gestazione:Lunghezza + Gestazione:Cranio)
Coefficiente del modello di regressione lineare
Coefficiente Estimate Std. Error t value p_value Significance
(Intercept) -202.31 1106.90 -0.18 0.85499
N.gravidanze 13.15 4.31 3.05 0.00232 **
Gestazione -140.59 29.53 -4.76 < 0.001 ***
Lunghezza 9.09 3.76 2.42 0.01560
Cranio -7.84 6.44 -1.22 0.22293
SessoM 71.88 11.18 6.43 < 0.001 ***
Gestazione:Lunghezza 0.04 0.10 0.37 0.71303
Gestazione:Cranio 0.48 0.17 2.90 0.00379 **

La significatività della variabile Cranio si è ridotta, così come l’interazione tra Gestazione e Lunghezza sembra non essere significativa.

Rimuoviamo l’interazione tra Gestazione e Lunghezza e otteniamo il seguente risultato:

mod4 <- update(mod3, ~ . - Gestazione:Lunghezza)
Coefficiente del modello di regressione lineare
Coefficiente Estimate Std. Error t value p_value Significance
(Intercept) -193.12 1106.43 -0.17 0.86145
N.gravidanze 13.14 4.31 3.05 0.00233 **
Gestazione -140.68 29.53 -4.76 < 0.001 ***
Lunghezza 10.47 0.30 34.79 < 0.001 ***
Cranio -9.84 3.47 -2.83 0.00468 **
SessoM 72.06 11.17 6.45 < 0.001 ***
Gestazione:Cranio 0.53 0.09 5.91 < 0.001 ***

Infine, possiamo considerare l’aggiunta di effetti non lineari al modello, ad esempio un effetto logaritmico per le variabili Gestazione e Lunghezza.

mod5 <- update(mod4, ~ . + log(Gestazione) + log(Lunghezza))
Coefficiente del modello di regressione lineare
Coefficiente Estimate Std. Error t value p_value Significance
(Intercept) 49224.11 8780.14 5.61 <0.001 ***
N.gravidanze 14.64 4.24 3.46 <0.001 ***
Gestazione -404.76 106.29 -3.81 <0.001 ***
Lunghezza 45.01 3.75 12.01 <0.001 ***
Cranio -1.44 5.82 -0.25 0.8042
SessoM 71.26 10.97 6.49 <0.001 ***
log(Gestazione) 13012.20 2581.31 5.04 <0.001 ***
log(Lunghezza) -16723.57 1804.92 -9.27 <0.001 ***
Gestazione:Cranio 0.31 0.15 2.05 0.0409

L’R² aggiustato è pari a 0,7398, leggermente migliore rispetto al modello precedente.

Notiamo inoltre, che è possibile rimuovere il termine di interazione tra le variabili Gestazione e Cranio.

mod6 <- update(mod5, ~ . - Gestazione:Cranio)
Coefficiente del modello di regressione lineare
Coefficiente Estimate Std. Error t value p_value Significance
(Intercept) 61020.67 6625.99 9.21 <0.001 ***
N.gravidanze 14.54 4.24 3.43 <0.001 ***
Gestazione -218.52 54.90 -3.98 <0.001 ***
Lunghezza 47.95 3.46 13.86 <0.001 ***
Cranio 10.43 0.42 24.93 <0.001 ***
SessoM 71.99 10.97 6.56 <0.001 ***
log(Gestazione) 9845.88 2067.28 4.76 <0.001 ***
log(Lunghezza) -18152.95 1665.30 -10.90 <0.001 ***

LR² aggiustato ottenuto ora è pari di 0,7395, che è pressochè identico all’R² aggiustato del modello precedente.

# Confronto ANOVA tra i vari modelli
anova_df <- anova(mod1, mod2, mod3, mod4, mod5, mod6)
Confronto tra modelli tramite ANOVA
Modello RSS RSS residui Gradi di libertà Sum of Sq F value p-value
1 2492 187929681 NA NA NA NA
2 2494 188065546 -2 -135865.2 0.947 0.388
3 2492 185458770 2 2606776.3 18.170 0.000
4 2493 185468839 -1 -10068.9 0.140 0.708
5 2491 178686756 2 6782083.0 47.273 0.000
6 2492 178987036 -1 -300280.0 4.186 0.041
# Calcolo e confronto dei valori BIC tra i vari modelli
bic_values <- BIC(mod1, mod2, mod3, mod4, mod5, mod6)
BIC tra i vari modelli
df BIC
mod1 9 35233.94
mod2 7 35220.10
mod3 9 35200.85
mod4 8 35193.16
mod5 10 35115.68
mod6 9 35112.05

Il confronto tramite ANOVA mostra che mod5 introduce miglioramenti altamente significativi (p < 0.001), mentre il passaggio a mod6, che rimuove un termine, comporta una piccola ma significativa perdita (p-value = 0,041). Tuttavia, il BIC più basso è proprio quello di mod6 (BIC = 35112,05), indicando che questo è il modello ottimale per prevedere il peso del neonato, in quanto mantiene alte prestazioni predittive con un numero minore di parametri rispetto a mod5.

Si conclude quindi che mod6 è il modello preferito, in quanto statisticamente solido e più parsimonioso.

Analizzando il modello scelto si evidenzia in particolare che:

  • ogni gravidanza precedente sembra aumentare il peso del neonato in media di 14,5 grammi;

  • l’effetto della gestazione sul peso non è lineare: il termine logaritmico indica un forte aumento iniziale, mentre quello lineare suggerisce una stabilizzazione o lieve calo nelle ultime settimane;

  • discorso analogo per la lunghezza: inizialmente l’aumento è marcato, ma tende a ridursi con valori maggiori;

  • Ogni centimetro in più nella dimensione cranica è associato, in media, a un aumento di 10,4 grammi nel peso del neonato;

  • i neonati maschi pesano in media 72 grammi in più rispetto alle femmine.

2.4 - Analisi della Qualità del Modello

Possiamo analizzare i residui del modello facendo riferimento al grafico seguente.

# Diagnostica grafica del modello
par(mfrow=c(2,2))
plot(mod6)

L’analisi dei residui nella figura suggerisce alcuni aspetti problematici del modello. In primo luogo, la mancata normalità dei residui indica che potrebbero esserci delle deviazioni sistematiche, che potrebbero rendere i risultati del modello meno affidabili per l’inferenza. L’eteroschedasticità, cioè la variabilità non costante dei residui, può portare a una sovrastima o sottostima degli intervalli di confidenza e dei test statistici. La mancanza di correlazione lineare tra i residui e i predittori suggerisce che il modello cattura in parte la relazione con i predittori, ma potrebbe non aver incluso altre variabili rilevanti. La presenza di outlier e punti di leverage indica che ci sono dati che esercitano un’influenza sproporzionata sul modello. Questo può distorcere i risultati, causando un bias nei parametri e potenzialmente compromettendo la validità del modello.

# Shapiro-Wilk test per la normalità dei residui
test_norm <- shapiro.test(residuals(mod6))

Test di normalità di Shapiro-Wilk sui residui di mod6

  • Statistica W: 0.99
  • p_value: <0.001
# Test di Breusch-Pagan per eteroschedasticità
bp <- bptest(mod6)
# Test di Durbin-Watson per autocorrelazione dei residui
dw <- dwtest(mod6)

Test di eteroschedasticità (Breusch-Pagan)

  • Statistica: 75.28
  • Gradi di libertà: 7
  • p_value: <0.001

Test di autocorrelazione (Durbin-Watson)

  • Statistica: 1.95
  • p_value: 0.108

La situazione precedente è confermata dal test di Shapiro-Wilk, che verifica la normalità dei residui e fornisce un p-value decisamente inferiore a 0,05, il che ci porta a rifiutare l’ipotesi nulla di normalità. L’omoschedasticità dei residui può essere valutata attraverso il test di Breusch-Pagan, che restituisce anch’esso un p-value decisamente inferiore a 0.05, portandoci quindi a rifiutare l’ipotesi nulla di omoschedasticità. Infine, verifichiamo l’indipendenza dei residui utilizzando il test di Durbin-Watson, il quale restituisce un p-value di 0,108, superiore a 0,05, consentendoci di accettare l’ipotesi nulla di indipendenza.

Nella grafico seguente, possiamo vedere un’altra rappresentazione dei residui del modello che ci permette di osservare: la distribuzione dei residui, i punti di leverage, gli outlier e la distanza di Cook.

par(mfrow=c(2,2))

residui <- residuals(mod2)
plot(density(residui), main = "", xlab = "Densità", ylab = "Residui")

# Calcolo dei leverage
lev <- hatvalues(mod2)
plot(lev, ylab = "Leverage", pch = 20)
p <- sum(lev)
n <- length(lev)
soglia <- 2*p/n
abline(h=soglia,col=2)

# Identificazione di possibili outlier tramite i residui studentizzati
rstud <- rstudent(mod2)
plot(rstud, ylab = "Residui Studentizzati", pch = 1)
abline(h = c(-2, 2), col = "red")
outlier_result <- car::outlierTest(mod2)

# Analisi della distanza di Cook per individuare osservazioni influenti
cook <- cooks.distance(mod2)
plot(cook, ylab = "Distanza di Cook", pch = 1, ylim = c(0, 1.5))
Test degli Outlier (Bonferroni)
Residuo_Studentizzato p_Bonferroni
1551 10.05 < 2.2e-16
155 5.03 5.314e-07
1306 4.83 1.468e-06

Per quanto riguarda i punti di leva, il grafico dei leverage mostra alcune osservazioni con valori superiori alla soglia critica (2*p/n ≈ 0,004). Tra queste, sono state segnalate, tra le altre, le osservazioni 15, 155 e 161.

Il grafico degli outlier indica che l’osservazione 1551 supera nettamente la soglia di ±2, risultando un outlier significativo, come confermato anche dal test di Bonferroni. Ulteriori osservazioni potenzialmente influenti sono 155 e 1306, anch’esse con p-value corretti significativi.

Il grafico della distanza di Cook evidenzia che alcune osservazioni, in particolare la 1551, esercitano una forte influenza sul modello.

L’analisi dei residui mette in luce alcune violazioni delle assunzioni classiche del modello lineare, soprattutto per quanto riguarda la normalità e l’omoschedasticità. Sono stati inoltre identificati diversi punti con leverage elevato e outlier influenti, in particolare l’osservazione 1551, che potrebbero compromettere la robustezza delle stime e l’affidabilità delle inferenze statistiche.

kable(neonati[1551, ])
Anni.madre N.gravidanze Fumatrici Gestazione Peso Lunghezza Cranio Tipo.parto Ospedale Sesso
1551 35 1 NO 38 4370 315 374 Nat osp3 F

Questa osservazione riporta un valore di lunghezza pari a 315 mm, molto inferiore rispetto alla media della lunghezza neonatale, che risulta intorno ai 500 mm. Un valore così basso non è plausibile dal punto di vista biologico e suggerisce la presenza di un possibile errore di inserimento dati. Per questo motivo, si è deciso di escludere questa osservazione dall’analisi, per preservare la qualità e l’affidabilità dei risultati ottenuti.

# Creazione di un nuovo dataframe escludendo l’osservazione 1551
neonati_no_outliers <- neonati[-1551, ]

mod_no_outliers <- update(mod6, data = neonati_no_outliers)
Coefficiente del modello di regressione lineare
Coefficiente Estimate Std. Error t value p_value Significance
(Intercept) 45604.28 7154.04 6.37 <0.001 ***
N.gravidanze 14.42 4.21 3.42 <0.001 ***
Gestazione -103.10 58.44 -1.76 0.0778
Lunghezza 37.44 3.93 9.52 <0.001 ***
Cranio 10.11 0.42 24.09 <0.001 ***
SessoM 72.89 10.91 6.68 <0.001 ***
log(Gestazione) 5338.64 2211.23 2.41 0.0158
log(Lunghezza) -12876.20 1911.40 -6.74 <0.001 ***

Il modello con l’outlier rimosso non presenta sostanziali variazioni e i coefficienti sono quasi identici. L’unica differenza è che il coefficiente della variabile log(Gestazione) perde significatività, quindi possiamo rimuoverlo dal modello.

mod2_no_outliers <- update(mod_no_outliers, ~ . - log(Gestazione))
Coefficiente del modello di regressione lineare
Coefficiente Estimate Std. Error t value p_value Significance
(Intercept) 43006.02 7079.48 6.07 <0.001 ***
N.gravidanze 14.23 4.22 3.37 <0.001 ***
Gestazione 37.69 3.87 9.73 <0.001 ***
Lunghezza 30.96 2.87 10.77 <0.001 ***
Cranio 10.16 0.42 24.20 <0.001 ***
SessoM 71.93 10.92 6.59 <0.001 ***
log(Lunghezza) -9675.53 1378.28 -7.02 <0.001 ***
# Calcolo e confronto dei valori BIC
bic_values <- BIC(mod6, mod_no_outliers, mod2_no_outliers)
Calcolo e confronto dei valori BIC
df BIC
mod6 9 35112.05
mod_no_outliers 9 35068.61
mod2_no_outliers 8 35066.63
# Test di Breusch-Pagan per eteroschedasticità
bp <- bptest(mod2_no_outliers)
# Test di Durbin-Watson per autocorrelazione dei residui
dw <- dwtest(mod2_no_outliers)

Test di eteroschedasticità (Breusch-Pagan)

  • Statistica: 13.12
  • Gradi di libertà: 6
  • p_value: 0.0411

Test di autocorrelazione (Durbin-Watson)

  • Statistica: 1.95
  • p_value: 0.108

Scegliamo come modello finale mod2_no_outliers. Dal confronto dei valori BIC, emerge che questo è il modello preferibile, seppur di poco, rispetto a mod_no_outliers

Il valore di è pari a 0,7423, indicando che circa il 74% della variabilità del peso dei neonati è spiegata dal modello. Inoltre, il valore di R² aggiustato, pari a 0,7417, suggerisce che il modello è generalizzabile e non sovra-adattato ai dati.

Analizzando le statistiche riportate nell’ultima tabella, tutti i predittori risultano significativi (p < 0,05), e la maggior parte presenta valori p < 0,001, il che rende il modello robusto e consistente.

Per quanto riguarda la validazione dei residui, il test di Breusch-Pagan restituisce un p-value pari a 0,0411, inferiore alla soglia convenzionale di 0,05. Ciò porta a rifiutare l’ipotesi nulla di omoschedasticità, suggerendo la presenza di eteroschedasticità nel modello.

Al contrario, il test di Durbin-Watson restituisce un p-value di 0,108, ben al di sopra della soglia di significatività. Possiamo quindi accettare l’ipotesi nulla di indipendenza dei residui, e concludere che non vi è autocorrelazione tra essi.

In sintesi, il modello di regressione lineare sviluppato si è dimostrato un buon strumento per predire il peso dei neonati e fornire indicazioni utili per la comprensione delle relazioni tra le variabili.

Step 3 - Previsioni e Risultati

Per effettuare una previsione applicativa, è stato considerato il caso di una neonata (sesso femminile), nata alla terza gravidanza della madre, con una gestazione di 39 settimane. In assenza di valori specifici per le variabili Lunghezza e Cranio, si è fatto ricorso ai rispettivi valori medi, calcolati in precedenza mediante la funzione calculate_numeric_stats, al fine di stimare il peso alla nascita.

# Estrazione dei valori medi di Lunghezza e Cranio
mean_length <- numeric_stats_df["Lunghezza", "mean"]
mean_head <- numeric_stats_df["Cranio", "mean"]

# Creazione di un nuovo dataframe contenente le caratteristiche di una neonata ipotetica
neonati_prev  <- data.frame(
  N.gravidanze = 3,
  Gestazione = 39,
  Lunghezza = mean_length,
  Cranio = mean_head,
  Tipo.parto = "Nat",
  Sesso = factor("F", levels = c("F", "M"))
)

# Creazione della variabile dummy SessoM
neonati_prev$SessoM <- ifelse(neonati_prev$Sesso == "M", 1, 0)

# Calcolo della previsione con il modello mod2_no_outliers
weight_prev <- predict(mod2_no_outliers, newdata = neonati_prev)

Il peso previsto è in media di: 3262.28 grammi.

Step 4 - Visualizzazioni

Per rappresentare visivamente i risultati del modello e le principali relazioni tra le variabili, sono stati realizzati diversi grafici esplicativi. Questi strumenti grafici permettono di comprendere meglio l’influenza dei predittori sul peso alla nascita. Si precisa che la variabile Fumatrici non è stata inclusa nel modello finale; pertanto, come variabile di stratificazione si è scelto di utilizzare Sesso.

Grafico 1: Relazione tra Durata della Gestazione e Peso alla Nascita, stratificata per Sesso

ggplot(data = neonati_no_outliers) +
  geom_point(aes(x = Gestazione,
                 y = Peso,
                 col = Sesso), position = "jitter") +
  geom_smooth(aes(x = Gestazione,
                  y = Peso,
                  col = Sesso), se = FALSE, method = "lm") +
  labs(title = "Relazione tra Durata della Gestazione e Peso alla Nascita",
       x = "Durata della Gestazione (settimane)",
       y = "Peso alla Nascita (grammi)",
       color = "Sesso") +
  theme_minimal()

È evidente una relazione positiva tra la durata della gestazione e il peso alla nascita per entrambi i sessi. Le linee di tendenza indicano che, a parità di settimane gestazionali, i neonati di sesso maschile tendono ad avere un peso leggermente superiore rispetto alle femmine. Questo risultato è coerente con l’effetto significativo della variabile Sesso nel modello.

Grafico 2: Relazione tra Numero di Gravidanze e Peso alla Nascita, stratificata per Sesso

ggplot(data = neonati_no_outliers) +
  geom_point(aes(x = N.gravidanze,
                 y = Peso,
                 col = Sesso), position = "jitter") +
  geom_smooth(aes(x = N.gravidanze,
                  y = Peso,
                  col = Sesso), se = FALSE, method = "lm") +
  labs(title = "Relazione tra N.gravidanze e Peso alla Nascita",
       x = "Numero di gravidanze",
       y = "Peso alla Nascita (grammi)",
       color = "Sesso") +
  theme_minimal()

La rappresentazione grafica della relazione tra il numero di gravidanze e il peso alla nascita, suddivisa per sesso, evidenzia una tendenza molto lieve. Si nota un piccolo divario nel peso medio tra maschi e femmine, in linea con quanto rilevato dal modello, mentre l’effetto del numero di gravidanze sul peso risulta sostanzialmente marginale.

Grafico 3: Relazione tra Lunghezza e Peso alla Nascita, stratificata per Sesso

ggplot(data = neonati_no_outliers) +
  geom_point(aes(x = Lunghezza,
                 y = Peso,
                 col = Sesso), position = "jitter") +
  geom_smooth(aes(x = Lunghezza,
                  y = Peso,
                  col = Sesso), se = FALSE, method = "lm") +
  labs(title = "Relazione tra Lunghezza del Neonato e Peso alla Nascita",
       x = "Lunghezza del Neonato (cm)",
       y = "Peso alla Nascita (grammi)",
       color = "Sesso") +
  theme_minimal()

Il grafico evidenzia una marcata relazione positiva tra la lunghezza del neonato e il peso alla nascita, distinta per sesso. A parità di lunghezza, si osserva che i neonati maschi tendono a presentare un peso leggermente superiore rispetto alle femmine, confermando l’importanza della variabile Sesso nel modello finale.

Grafico 4: Relazione tra Diametro Cranico e Peso alla Nascita, stratificata per Sesso

ggplot(data = neonati_no_outliers) +
  geom_point(aes(x = Cranio,
                 y = Peso,
                 col = Sesso), position = "jitter") +
  geom_smooth(aes(x = Cranio,
                  y = Peso,
                  col = Sesso), se = FALSE, method = "lm") +
  labs(title = "Relazione tra Diametro Cranico e Peso alla Nascita",
       x = "Diametro Cranico (cm)",
       y = "Peso alla Nascita (grammi)",
       color = "Sesso") +
  theme_minimal()

La visualizzazione mette in evidenza una chiara correlazione positiva tra il diametro cranico e il peso alla nascita. Analogamente a quanto osservato per la lunghezza, anche in questo caso i neonati maschi tendono a mostrare un peso leggermente superiore rispetto alle femmine per lo stesso diametro cranico, confermando così il ruolo significativo della variabile Sesso come predittore nel modello.

Step 5 - Conclusioni

Il progetto si è focalizzato sulla costruzione e selezione di un modello predittivo robusto per il peso neonatale, basato su un’ampia varietà di variabili demografiche e cliniche. Il processo di modellazione ha previsto diverse fasi di raffinamento, partendo da un modello completo fino a giungere a una versione più parsimoniosa. Il modello finale scelto, mod2_no_outliers rappresenta il miglior equilibrio tra accuratezza di adattamento e semplicità interpretativa. In sintesi, questo lavoro ha prodotto un modello predittivo efficace e interpretabile, identificando i principali fattori che influenzano la variabilità del peso alla nascita. Le conoscenze acquisite possono costituire una solida base per studi clinici futuri e per interventi mirati a migliorare gli esiti neonatali.