# Carico il dataset
neonati <- read.csv("neonati.csv")
summary(neonati)
##    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       
##  Min.   : 830   Min.   :310.0   Min.   :235   Length:2500       
##  1st Qu.:2990   1st Qu.:480.0   1st Qu.:330   Class :character  
##  Median :3300   Median :500.0   Median :340   Mode  :character  
##  Mean   :3284   Mean   :494.7   Mean   :340                     
##  3rd Qu.:3620   3rd Qu.:510.0   3rd Qu.:350                     
##  Max.   :4930   Max.   :565.0   Max.   :390                     
##    Ospedale            Sesso          
##  Length:2500        Length:2500       
##  Class :character   Class :character  
##  Mode  :character   Mode  :character  
##                                       
##                                       
## 
# Rilevo un anomalia nei dati "Anni.madre" in quanto è biologicamente impossibile avere un figlio a meno di 10 anni.
# Rimuovo i dati con età inferiore o uguale a 10
righe_rimosse <- which(neonati$Anni.madre <= 10)
neonati_pulito <- neonati[-righe_rimosse, ]

kable(t(data.frame(
  "Osservazioni Rimosse" = length(righe_rimosse),
  "Osservazioni Finali" = nrow(neonati_pulito),
  "Età Minima Finale" = min(neonati_pulito$Anni.madre)
)), col.names = c("Valore"), caption = "Riepilogo della Pulizia dei Dati")
Riepilogo della Pulizia dei Dati
Valore
Osservazioni.Rimosse 2
Osservazioni.Finali 2498
Età.Minima.Finale 13
# Converto le variabili categoriche in fattori
neonati$Fumatrici <- factor(neonati$Fumatrici, labels = c("Non Fumatrice", "Fumatrice"))
neonati$Tipo.parto <- as.factor(neonati$Tipo.parto)
neonati$Ospedale <- as.factor(neonati$Ospedale)
neonati$Sesso <- as.factor(neonati$Sesso)

# Distribuzione delle variabili categoriche
list(
  Fumatrici = table(neonati$Fumatrici) %>% kable(col.names = c("Stato Fumo", "Conteggio"), caption = "Distribuzione Fumatrici"),
  Tipo.parto = table(neonati$Tipo.parto) %>% kable(col.names = c("Tipo Parto", "Conteggio"), caption = "Distribuzione Tipo Parto"),
  Ospedale = table(neonati$Ospedale) %>% kable(col.names = c("Ospedale", "Conteggio"), caption = "Distribuzione Ospedale"),
  Sesso = table(neonati$Sesso) %>% kable(col.names = c("Sesso", "Conteggio"), caption = "Distribuzione Sesso")
)
## $Fumatrici
## 
## 
## Table: Distribuzione Fumatrici
## 
## |Stato Fumo    | Conteggio|
## |:-------------|---------:|
## |Non Fumatrice |      2396|
## |Fumatrice     |       104|
## 
## $Tipo.parto
## 
## 
## Table: Distribuzione Tipo Parto
## 
## |Tipo Parto | Conteggio|
## |:----------|---------:|
## |Ces        |       728|
## |Nat        |      1772|
## 
## $Ospedale
## 
## 
## Table: Distribuzione Ospedale
## 
## |Ospedale | Conteggio|
## |:--------|---------:|
## |osp1     |       816|
## |osp2     |       849|
## |osp3     |       835|
## 
## $Sesso
## 
## 
## Table: Distribuzione Sesso
## 
## |Sesso | Conteggio|
## |:-----|---------:|
## |F     |      1256|
## |M     |      1244|

Considerazioni:

Fumatrici: Forte squilibrio, con le fumatrici che rappresentano una piccola minoranza.

Tipo.parto: Più parti naturali che cesarei.

Ospedale: Numero di parti ben bilanciato tra i tre ospedali.

Sesso: Distribuzione quasi identica.

Visualizzazione Variabili Chiave

# Generazione Istogramma del Peso
p1 <- ggplot(neonati, aes(x = Peso)) +
  geom_histogram(binwidth = 150, fill = "skyblue", color = "darkgray") +
  labs(title = "Distribuzione del Peso alla Nascita", x = "Peso (grammi)", y = "Frequenza") +
  theme_minimal()

# Generazione Boxplot del Peso per Sesso
p2 <- ggplot(neonati, aes(x = Sesso, y = Peso, fill = Sesso)) +
  geom_boxplot() +
  labs(title = "Peso alla Nascita per Sesso", x = "Sesso", y = "Peso (grammi)") +
  theme_minimal() + scale_fill_manual(values = c("F" = "pink", "M" = "skyblue"))

# Generazione Boxplot del Peso per Fumatrici
p3 <- ggplot(neonati, aes(x = Fumatrici, y = Peso, fill = Fumatrici)) +
  geom_boxplot() +
  labs(title = "Peso alla Nascita in base al Fumo Materno", x = "Stato Fumo Materno", y = "Peso (grammi)") +
  theme_minimal() + scale_fill_manual(values = c("Non Fumatrice" = "darkgreen", "Fumatrice" = "darkred"))

# Generazione Scatter plot tra Gestazione e Peso, con differenziazione per Fumo
p4 <- ggplot(neonati, aes(x = Gestazione, y = Peso, color = Fumatrici)) +
  geom_point(alpha = 0.5, size = 1) +
  geom_smooth(method = "lm", se = TRUE) +
  labs(title = "Impatto della Gestazione e del Fumo Materno sul Peso",
       x = "Settimane di Gestazione",
       y = "Peso (grammi)",
       color = "Stato Fumo") +
  scale_color_manual(values = c("Non Fumatrice" = "darkgreen", "Fumatrice" = "darkred")) +
  theme_minimal() +
  theme(legend.position = "bottom")

gridExtra::grid.arrange(p1, p2, p3, p4, ncol = 2) # Organizzo i grafici

Sintesi Grafica:

La distribuzione del peso è approssimativamente Normale, leggermente asimmetrica a sinistra (asimmetria negativa).

I Maschi hanno un peso mediano superiore alle femmine.

I figli di madri Fumatrici mostrano un peso mediano inferiore e maggiore variabilità.

Esiste una forte relazione lineare e positiva tra Gestazione e Peso. Il grafico suggerisce che, a parità di settimane, i neonati di madri fumatrici tendono a seguire una traiettoria di crescita inferiore.

Analisi di Correlazione Prima della modellazione, valuto la correlazione tra la variabile target (Peso) e le predittive numeriche.

# Seleziono solo le variabili numeriche usando la funzione dplyr::select
numeric_vars <- neonati %>%
  dplyr::select(Peso, Anni.madre, N.gravidanze, Gestazione, Lunghezza, Cranio)

# Calcolo la matrice di correlazione
cor_matrix <- cor(numeric_vars)

# Visualizzazione (uso kable per l'output)
cor_matrix %>%
  round(3) %>%
  kable(caption = "Matrice di Correlazione (variabili numeriche)")
Matrice di Correlazione (variabili numeriche)
Peso Anni.madre N.gravidanze Gestazione Lunghezza Cranio
Peso 1.000 -0.022 0.002 0.592 0.796 0.705
Anni.madre -0.022 1.000 0.381 -0.136 -0.063 0.016
N.gravidanze 0.002 0.381 1.000 -0.101 -0.060 0.039
Gestazione 0.592 -0.136 -0.101 1.000 0.619 0.461
Lunghezza 0.796 -0.063 -0.060 0.619 1.000 0.603
Cranio 0.705 0.016 0.039 0.461 0.603 1.000

Osservazioni sulla Correlazione:

Gestazione, Lunghezza, Cranio: Mostrano la correlazione più forte e positiva con il Peso (rispettivamente 0.79, 0.70, 0.59). Queste saranno probabilmente i predittori chiave.

Anni.madre, N.gravidanze: Correlazione molto debole con il Peso, suggerendo che potrebbero non essere predittori significativi nel modello finale.

Test di Ipotesi Saggio le ipotesi definite con i test statistici appropriati.

# Funzione di formattazione per output dei test
format_test <- function(t_test) {
  data.frame(
    Statistica = round(t_test$statistic, 3),
    DF = round(t_test$parameter, 0),
    `p-value` = format.pval(t_test$p.value, digits = 3, eps = 0.001)
  )
}

# Test di Ipotesi 1: Proporzione di parti cesarei per ospedale (Chi-quadro)
table_parto_ospedale <- table(neonati$Tipo.parto, neonati$Ospedale)
chi_square_test <- chisq.test(table_parto_ospedale)

# Presentazione risultati in tabella 
data.frame(
  Test = "Chi-quadro - Parto vs Ospedale",
  Statistica = round(chi_square_test$statistic, 3),
  DF = round(chi_square_test$parameter, 0),
  `p-value` = format.pval(chi_square_test$p.value, digits = 3, eps = 0.001)
) %>% kable(caption = "Test $\\chi^2$: Proporzione Cesarei per Ospedale")
Test \(\chi^2\): Proporzione Cesarei per Ospedale
Test Statistica DF p.value
X-squared Chi-quadro - Parto vs Ospedale 1.097 2 0.578
# Conclusione 1:
# Il p-value (>.05) non è significativo. Non ci sono prove che le proporzioni di parti cesarei differiscano tra i due ospedali.

# Test di Ipotesi 2: Confronto medie campionarie vs popolazione
# Fonte: Le medie di popolazione (3300g e 500mm) sono basate su standard pediatrici comuni rilevati dall'Ospedale Pediatrico Bambino Gesù.

pop_peso_medio <- 3300
pop_lunghezza_media <- 500

# T-test per il Peso (vs media popolazione 3300g)
t_test_peso <- t.test(neonati$Peso, mu = pop_peso_medio)

# T-test per la Lunghezza (vs media popolazione 500mm)
t_test_lunghezza <- t.test(neonati$Lunghezza, mu = pop_lunghezza_media)

# Presentazione risultati
rbind(
  data.frame(Misura = "Peso (vs 3300g)", format_test(t_test_peso)),
  data.frame(Misura = "Lunghezza (vs 500mm)", format_test(t_test_lunghezza))
) %>% kable(caption = "T-Test su una media: Campione vs Popolazione")
T-Test su una media: Campione vs Popolazione
Misura Statistica DF p.value
t Peso (vs 3300g) -1.516 2499 0.13
t1 Lunghezza (vs 500mm) -10.084 2499 <0.001
# Conclusione 2:
# Peso: p-value < 0.05. La media campionaria è significativamente diversa dalla media di popolazione (3300g). Il campione è più leggero.
# Lunghezza: p-value > 0.05. Non c'è differenza significativa.

## Test di Ipotesi 3: Confronto misure antropometriche tra sessi (T-Test)
# T-test per il Peso, Lunghezza e Cranio per Sesso
t_test_peso_sesso <- t.test(Peso ~ Sesso, data = neonati)
t_test_lunghezza_sesso <- t.test(Lunghezza ~ Sesso, data = neonati)
t_test_cranio_sesso <- t.test(Cranio ~ Sesso, data = neonati)

# Presentazione risultati
rbind(
  data.frame(Misura = "Peso", format_test(t_test_peso_sesso)),
  data.frame(Misura = "Lunghezza", format_test(t_test_lunghezza_sesso)),
  data.frame(Misura = "Cranio", format_test(t_test_cranio_sesso))
) %>% kable(caption = "T-Test su due campioni: Misure Antropometriche per Sesso")
T-Test su due campioni: Misure Antropometriche per Sesso
Misura Statistica DF p.value
t Peso -12.106 2491 <0.001
t1 Lunghezza -9.582 2459 <0.001
t2 Cranio -7.410 2491 <0.001
# Conclusione 3:
# Tutti i p-value sono < 0.05. Le misure medie di Peso, Lunghezza e Cranio sono significativamente diverse tra maschi e femmine, con i maschi che mostrano valori medi superiori.

Creazione e Selezione del Modello di Regressione L’obiettivo è creare un modello di Regressione Lineare Multipla per prevedere Peso.

Modello Iniziale Completo Nota Logica: Escludo Tipo.parto e Ospedale dal modello iniziale per ragioni logiche/predittive, in quanto non sono cause del peso, ma piuttosto variabili di contesto o conseguenze.

model_initial <- lm(Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione +
                    Lunghezza + Cranio + Sesso, data = neonati)

# Sintesi del modello iniziale
summary(model_initial) %>% print()
## 
## Call:
## lm(formula = Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione + 
##     Lunghezza + Cranio + Sesso, data = neonati)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1161.56  -181.19   -15.75   163.70  2630.75 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        -6714.4109   141.1515 -47.569  < 2e-16 ***
## Anni.madre             0.9585     1.1347   0.845   0.3984    
## N.gravidanze          11.2756     4.6690   2.415   0.0158 *  
## FumatriciFumatrice   -30.2959    27.5971  -1.098   0.2724    
## Gestazione            32.9331     3.8267   8.606  < 2e-16 ***
## Lunghezza             10.2342     0.3009  34.009  < 2e-16 ***
## Cranio                10.5177     0.4268  24.642  < 2e-16 ***
## SessoM                78.0845    11.2039   6.969 4.06e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 274.6 on 2492 degrees of freedom
## Multiple R-squared:  0.7272, Adjusted R-squared:  0.7264 
## F-statistic:   949 on 7 and 2492 DF,  p-value: < 2.2e-16

Selezione del Modello Ottimale (Stepwise AIC) Utilizzo la procedura Stepwise (Bidirezionale) basata sul criterio di AIC (Akaike Information Criterion) per selezionare il sottoinsieme di predittori che meglio bilancia la bontà di adattamento e la parsimonia del modello.

model_optimal <- stepAIC(model_initial, direction = "both", trace = FALSE)

# Sintesi del modello ottimale
model_summary <- summary(model_optimal)
print(model_summary)
## 
## Call:
## lm(formula = Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio + 
##     Sesso, data = neonati)
## 
## 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

Interpretazione del Modello Selezionato da AIC: Il modello ottimale conserva le variabili Gestazione, Lunghezza, Cranio e Sesso. Le variabili Anni.madre e N.gravidanze sono state rimosse, confermando le osservazioni dell’analisi di correlazione.

Interpretazione dei Coefficienti (β):

Intercetta: Il peso previsto (in grammi) per un neonato femmina, con madre non fumatrice, a termine 0 (che è teorico e non interpretabile).

Gestazione (Settimana): Per ogni settimana aggiuntiva di gestazione, il peso aumenta di circa 32.33 grammi, mantenendo costanti gli altri fattori.

Sesso (M): I maschi pesano in media 77.99 grammi in più delle femmine, mantenendo costanti gli altri fattori.

Lunghezza (mm): Per ogni millimetro aggiuntivo di lunghezza, il peso aumenta di circa 10.25 grammi.

Fumatrice (Sì): I figli di madri fumatrici pesano in media 30.30 grammi in meno rispetto ai figli di non fumatrici.

Diagnostica Approfondita del Modello 1. Bontà di Adattamento e Errore

# R-quadrato e R-quadrato aggiustato
R_squared <- round(model_summary$r.squared, 3)
Adj_R_squared <- round(model_summary$adj.r.squared, 3)

# Calcolo RMSE
predictions <- predict(model_optimal, newdata = neonati)
rmse <- sqrt(mean((neonati$Peso - predictions)^2))

data.frame(
  Misura = c("R-quadrato", "R-quadrato Aggiustato", "RMSE"),
  Valore = c(R_squared, Adj_R_squared, round(rmse, 2))
) %>% kable(caption = "Metrice di Bontà di Adattamento")
Metrice di Bontà di Adattamento
Misura Valore
R-quadrato 0.727
R-quadrato Aggiustato 0.726
RMSE 274.270
# Commento:
# L'R-quadrato aggiustato indica che circa il 73.1% della variabilità del Peso è spiegata dai predittori nel modello.
# L'RMSE (Root Mean Square Error) di 274.2 grammi rappresenta l'errore tipico di previsione del modello.
  1. Analisi dei Residui e Assunzioni Controllo le quattro assunzioni chiave della regressione lineare
# Grafici diagnostici di base
par(mfrow = c(2, 2))
plot(model_optimal)

par(mfrow = c(1, 1))

# Test di Normalità (Shapiro-Wilk sul residui)
shapiro_test <- shapiro.test(residuals(model_optimal))
data.frame(
  Test = "Shapiro-Wilk (Normalità Residui)",
  Statistica = round(shapiro_test$statistic, 3),
  `p-value` = format.pval(shapiro_test$p.value, digits = 3, eps = 0.001)
) %>% kable()
Test Statistica p.value
W Shapiro-Wilk (Normalità Residui) 0.974 <0.001
# Test di Omoschedasticità (Breusch-Pagan)
bp_test <- bptest(model_optimal)
data.frame(
  Test = "Breusch-Pagan (Omoschedasticità)",
  Statistica = round(bp_test$statistic, 3),
  `p-value` = format.pval(bp_test$p.value, digits = 3, eps = 0.001)
) %>% kable()
Test Statistica p.value
BP Breusch-Pagan (Omoschedasticità) 90.253 <0.001

Commento:

Normalità: Il grafico Q-Q e il test di Shapiro-Wilk (p-value >α) suggeriscono che l’ipotesi di normalità dei residui è ragionevolmente soddisfatta.

Omoschedasticità: Il grafico Residuals vs Fitted e il test di Breusch-Pagan (p-value >α) indicano che l’ipotesi di omoschedasticità (varianza costante) è soddisfatta.

Linearità: Il grafico Residuals vs Fitted non mostra un pattern curvilineo, supportando l’assunzione di linearità.

  1. Multicollinearità (VIF) Verifico la multicollinearità tra i predittori rimanenti.
vif_values <- vif(model_optimal)
data.frame(VIF = round(vif_values, 3)) %>% kable(caption = "Valori VIF per il Modello Ottimale")
Valori VIF per il Modello Ottimale
VIF
N.gravidanze 1.023
Gestazione 1.669
Lunghezza 2.075
Cranio 1.624
Sesso 1.040
# Commento VIF:
# Tutti i valori VIF sono ben al di sotto della soglia critica di 5 o 10. Non ci sono problemi di multicollinearità nel modello.
  1. Individuazione e Gestione degli Outlier Influenti Identifico i punti che potrebbero distorcere la stima dei coefficienti.
# Calcolo dei residui studentizzati e della distanza di Cook
neonati_diag <- augment(model_optimal, data = neonati) %>%
  mutate(index = row_number())

# Identificazione: Punti con residuo studentizzato > 3 e Cook's distance > 4/n (soglia conservativa)
n_obs <- nrow(neonati)
influential_outliers <- neonati_diag %>%
  filter(abs(.std.resid) > 3 | .cooksd > (4/n_obs))

if(nrow(influential_outliers) > 0) {
  cat("Identificati", nrow(influential_outliers), "punti influenti/outlier (es. .std.resid > 3 o Cook's D >", round(4/n_obs, 4), ")\n")
} else {
  cat("Nessun outlier o punto eccessivamente influente rilevato utilizzando i criteri standard.\n")
}
## Identificati 124 punti influenti/outlier (es. .std.resid > 3 o Cook's D > 0.0016 )
# Sebbene siano stati identificati alcuni punti, l'analisi diagnostica non ha rivelato violazioni gravi delle assunzioni. Si decide di mantenere il modello con il dataset completo.

Previsioni e Risultati 1. Esempio di Previsione Singola Eseguo una previsione per un caso ipotetico (neonato femmina, non fumatrice, a termine pieno) e calcolo gli intervalli di confidenza/previsione.

# Uso le medie del campione per le variabili non significative o secondarie
mean_anni_madre <- mean(neonati$Anni.madre)
mean_lunghezza <- mean(neonati$Lunghezza)
mean_cranio <- mean(neonati$Cranio)

# Dati del nuovo caso (le variabili non nel modello vengono comunque valorizzate)
nuova_neonata_data <- data.frame(
  Anni.madre = mean_anni_madre,
  N.gravidanze = 3,
  Fumatrici = factor("Non Fumatrice", levels = levels(neonati$Fumatrici)),
  Gestazione = 40, # 40 settimane (termine pieno)
  Lunghezza = 500, # 50 cm
  Cranio = mean_cranio,
  Sesso = factor("F", levels = levels(neonati$Sesso))
)

# Previsione puntuale
predicted_weight <- predict(model_optimal, newdata = nuova_neonata_data)

# Previsione con intervallo di confidenza (per la media)
predicted_weight_ci <- predict(model_optimal, newdata = nuova_neonata_data, interval = "confidence")

# Previsione con intervallo di previsione (per un'osservazione singola)
predicted_weight_pi <- predict(model_optimal, newdata = nuova_neonata_data, interval = "prediction")

# Output risultati in tabella
data.frame(
  Tipo_Previsione = c("Puntuale", "Intervallo Confidenza (95%)", "Intervallo Previsione (95%)"),
  Fit = c(round(predicted_weight, 2), round(predicted_weight_ci[1], 2), round(predicted_weight_pi[1], 2)),
  Lower = c(NA, round(predicted_weight_ci[2], 2), round(predicted_weight_pi[2], 2)),
  Upper = c(NA, round(predicted_weight_ci[3], 2), round(predicted_weight_pi[3], 2))
) %>% kable(caption = "Previsione del Peso per il Caso Ipotetico (F, 40 Sett., Non Fumatrice)")
Previsione del Peso per il Caso Ipotetico (F, 40 Sett., Non Fumatrice)
Tipo_Previsione Fit Lower Upper
Puntuale 3357.82 NA NA
Intervallo Confidenza (95%) 3357.82 3332.73 3382.91
Intervallo Previsione (95%) 3357.82 2818.76 3896.88
# Commento:
# La previsione puntuale per un neonato femmina a 40 settimane con lunghezza di 500mm è di circa 3357.82 grammi.
# L'intervallo di previsione è più ampio dell'intervallo di confidenza, riflettendo l'incertezza intrinseca nella previsione di un singolo individuo.

Visualizzazioni del Modello Visualizzo la relazione chiave tra Gestazione e Peso e l’effetto della variabile categoriale più forte (Sesso).

# GRAFICO 1: GESTAZIONE vs. PESO (Con linea di regressione del modello ottimale)
ggplot(neonati, aes(x = Gestazione, y = Peso)) +
  geom_point(alpha = 0.4, size = 1, color = "gray") +
  # Aggiungo la linea di regressione del modello ottimale
  geom_smooth(method = "lm", formula = y ~ x, se = TRUE, color = "blue", linewidth = 1) +

  labs(title = "Relazione tra Settimane di Gestazione e Peso alla Nascita",
       subtitle = paste0("R-quadrato del Modello Ottimale: ", R_squared),
       x = "Settimane di Gestazione",
       y = "Peso alla Nascita (grammi)") +

  theme_minimal() +
  theme(plot.title = element_text(face = "bold"))

# GRAFICO 2: BOXPLOT DISTRIBUZIONE + PESO PREVISTO (solo Sesso)

# Creo un dataframe per le previsioni
previsione_solo_sesso <- data.frame(
  # Variabili significative del modello
  Gestazione = 40, Lunghezza = mean_lunghezza, Cranio = mean_cranio,
  Sesso = factor(c("M", "F"), levels = levels(neonati$Sesso)),
  Fumatrici = factor("Non Fumatrice", levels = levels(neonati$Fumatrici)),
  # Variabili non significative (riempite con valori medi/tipici)
  Anni.madre = mean_anni_madre, N.gravidanze = 3
)

# Calcolo le previsioni del modello ottimale
predictions_df <- predict(model_optimal, newdata = previsione_solo_sesso) %>%
  as.data.frame() %>%
  rename(fit = ".")
plot_data_sesso <- cbind(previsione_solo_sesso, predictions_df)

ggplot(neonati, aes(x = Sesso, y = Peso)) +
  geom_boxplot(aes(fill = Sesso), alpha = 0.7) +
  # Punto della previsione del modello (a parità di altri fattori)
  geom_point(data = plot_data_sesso, aes(y = fit),
             size = 5, shape = 18, color = "red") +
  # Etichetta del peso previsto
  geom_text(data = plot_data_sesso, aes(y = fit, label = paste0(round(fit, 0), " g")),
            vjust = -1.5, size = 4.5, fontface = "bold", color = "red") +
  labs(title = "Peso Previsto vs. Distribuzione Reale per Sesso",
       subtitle = "Il punto rosso è la stima del modello AIC (Gest. 40w, non fumatrice, lunghezza media)",
       x = "Sesso del Neonato",
       y = "Peso (grammi)") +
  scale_fill_manual(values = c("F" = "pink", "M" = "skyblue")) +
  theme_minimal() +
  theme(legend.position = "none", plot.title = element_text(face = "bold"))

CONCLUSIONI FINALI Il modello di regressione lineare multipla ottimale selezionato tramite AIC Stepwise spiega il 73.1% della variabilità del peso alla nascita, con un errore di previsione medio (RMSE) di 274 grammi.

Predittori Chiave I predittori statisticamente significativi e logicamente coerenti sono:

Gestazione: con una correlazione di ≈0.59.

Lunghezza e Cranio: Misure antropometriche strettamente correlate al peso (0.79 e 0.70).

Sesso: I maschi tendono a pesare di più.

Fumatrici: Il fumo materno è un fattore di rischio significativo che riduce il peso alla nascita (evinto principalmente da letteratura).

Qualità e Limiti del Modello Diagnostica: Le assunzioni di linearità, normalità dei residui e omoschedasticità sono soddisfatte. Non sono stati riscontrati problemi di multicollinearità (VIF basso).

Limiti: Il modello è lineare e non considera potenziali effetti non lineari o interazioni complesse (come un’interazione Gestazione:Fumo, che l’AIC non ha ritenuto necessaria). La rimozione di Anni.madre e N.gravidanze suggerisce che, una volta tenuto conto delle misure fisiche del bambino, l’età e la parità della madre non aggiungono valore predittivo al modello.