1. Caricamento e Preparazione dei Dati

# Caricamento dei dati
neonati <- read.csv("C:/Users/matma/Desktop/Profession.AI/3) Statistica Inferenziale/Progetto/neonati.csv", stringsAsFactors = FALSE)

# Rinomino le colonne per evitare problemi con i punti
names(neonati) <- c("Eta_madre", "N_gravidanze", "Fumatrice", "Gestazione", 
                    "Peso", "Lunghezza", "Cranio", "Tipo_parto", "Ospedale", "Sesso")

# Conversione delle variabili categoriche in fattori
neonati$Fumatrice <- factor(neonati$Fumatrice, levels = c(0, 1),
                           labels = c("No", "Si"))
neonati$Tipo_parto <- factor(neonati$Tipo_parto)
neonati$Ospedale <- factor(neonati$Ospedale)
neonati$Sesso <- factor(neonati$Sesso)

# Visualizzazione delle prime righe del dataset
head(neonati) %>%
  kbl() %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Eta_madre N_gravidanze Fumatrice Gestazione Peso Lunghezza Cranio Tipo_parto Ospedale Sesso
26 0 No 42 3380 490 325 Nat osp3 M
21 2 No 39 3150 490 345 Nat osp1 F
34 3 No 38 3640 500 375 Nat osp2 M
28 1 No 41 3690 515 365 Nat osp2 M
20 0 No 38 3700 480 335 Nat osp3 F
32 0 No 40 3200 495 340 Nat osp2 F
# Riepilogo della struttura del dataset
str(neonati)
## 'data.frame':    2500 obs. of  10 variables:
##  $ Eta_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 ...
##  $ Fumatrice   : Factor w/ 2 levels "No","Si": 1 1 1 1 1 1 1 1 1 1 ...
##  $ 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 ...
# Verifica di valori mancanti
missing_values <- colSums(is.na(neonati))
print(missing_values)
##    Eta_madre N_gravidanze    Fumatrice   Gestazione         Peso    Lunghezza 
##            0            0            0            0            0            0 
##       Cranio   Tipo_parto     Ospedale        Sesso 
##            0            0            0            0
# Statistiche descrittive
summary(neonati)
##    Eta_madre      N_gravidanze     Fumatrice   Gestazione         Peso     
##  Min.   : 0.00   Min.   : 0.0000   No:2396   Min.   :25.00   Min.   : 830  
##  1st Qu.:25.00   1st Qu.: 0.0000   Si: 104   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    Tipo_parto Ospedale   Sesso   
##  Min.   :310.0   Min.   :235   Ces: 728   osp1:816   F:1256  
##  1st Qu.:480.0   1st Qu.:330   Nat:1772   osp2:849   M:1244  
##  Median :500.0   Median :340              osp3:835           
##  Mean   :494.7   Mean   :340                                 
##  3rd Qu.:510.0   3rd Qu.:350                                 
##  Max.   :565.0   Max.   :390

2. Analisi Esplorativa dei Dati

2.1 Distribuzione delle Variabili Numeriche

# Visualizzazione della distribuzione delle variabili numeriche
numeric_vars <- neonati %>%
  select(Eta_madre, N_gravidanze, Gestazione, Peso, Lunghezza, Cranio)

# Funzione per creare gli istogrammi
plot_histogram <- function(data, var_name) {
  ggplot(data, aes_string(x = var_name)) +
    geom_histogram(aes(y = ..density..), fill = "steelblue", color = "white", bins = 30) +
    geom_density(color = "red") +
    labs(title = paste("Distribuzione di", var_name), x = var_name, y = "Densità") +
    theme_minimal()
}

# Creazione degli istogrammi per ogni variabile numerica
histogram_plots <- lapply(names(numeric_vars), function(var) plot_histogram(numeric_vars, var))

# Visualizzazione degli istogrammi
wrap_plots(histogram_plots, ncol = 2)

# Boxplot per identificare outlier
boxplot_plots <- lapply(names(numeric_vars), function(var) {
  ggplot(numeric_vars, aes_string(y = var)) +
    geom_boxplot(fill = "steelblue") +
    labs(title = paste("Boxplot di", var), y = var) +
    theme_minimal() +
    coord_flip()
})

wrap_plots(boxplot_plots, ncol = 2)

2.2 Analisi delle Variabili Categoriche

# Analisi delle variabili categoriche
categorical_vars <- neonati %>%
  select(Fumatrice, Tipo_parto, Ospedale, Sesso)

# Funzione per creare i grafici a barre
plot_bar <- function(data, var_name) {
  ggplot(data, aes_string(x = var_name, fill = var_name)) +
    geom_bar() +
    labs(title = paste("Distribuzione di", var_name), x = var_name, y = "Conteggio") +
    theme_minimal() +
    theme(legend.position = "none")
}

# Creazione dei grafici a barre per ogni variabile categorica
bar_plots <- lapply(names(categorical_vars), function(var) plot_bar(categorical_vars, var))

# Visualizzazione dei grafici a barre
wrap_plots(bar_plots, ncol = 2)

# Tabelle di frequenza
for (var in names(categorical_vars)) {
  cat("\nTabella di frequenza per", var, ":\n")
  print(table(categorical_vars[[var]]))
  cat("Percentuali:\n")
  print(round(prop.table(table(categorical_vars[[var]])) * 100, 2))
  cat("\n")
}
## 
## Tabella di frequenza per Fumatrice :
## 
##   No   Si 
## 2396  104 
## Percentuali:
## 
##    No    Si 
## 95.84  4.16 
## 
## 
## Tabella di frequenza per Tipo_parto :
## 
##  Ces  Nat 
##  728 1772 
## Percentuali:
## 
##   Ces   Nat 
## 29.12 70.88 
## 
## 
## Tabella di frequenza per Ospedale :
## 
## osp1 osp2 osp3 
##  816  849  835 
## Percentuali:
## 
##  osp1  osp2  osp3 
## 32.64 33.96 33.40 
## 
## 
## Tabella di frequenza per Sesso :
## 
##    F    M 
## 1256 1244 
## Percentuali:
## 
##     F     M 
## 50.24 49.76

2.3 Relazioni tra le Variabili

# Matrice di correlazione per le variabili numeriche
cor_matrix <- cor(numeric_vars)
corrplot(cor_matrix, method = "circle", type = "upper",
         tl.col = "black", tl.srt = 45)

# Scatter plot per le relazioni principali con il Peso
scatter_plots <- lapply(c("Gestazione", "Lunghezza", "Cranio"), function(var) {
  ggplot(neonati, aes_string(x = var, y = "Peso")) +
    geom_point(aes(color = Sesso), alpha = 0.7) +
    geom_smooth(method = "lm", se = TRUE) +
    labs(title = paste("Relazione tra", var, "e Peso"), x = var, y = "Peso (g)") +
    theme_minimal()
})

wrap_plots(scatter_plots, ncol = 2)

# Relazione tra Peso e variabili categoriche
box_cat_plots <- lapply(c("Fumatrice", "Tipo_parto", "Ospedale", "Sesso"), function(var) {
  ggplot(neonati, aes_string(x = var, y = "Peso", fill = var)) +
    geom_boxplot() +
    labs(title = paste("Relazione tra", var, "e Peso"), x = var, y = "Peso (g)") +
    theme_minimal() +
    theme(legend.position = "none")
})

wrap_plots(box_cat_plots, ncol = 2)

3. Verifica delle Ipotesi

3.1 Ipotesi 1: Differenze nella frequenza dei parti cesarei tra ospedali

# Tabella di contingenza tra ospedale e tipo di parto
cont_table <- table(neonati$Ospedale, neonati$Tipo_parto)
print(cont_table)
##       
##        Ces Nat
##   osp1 242 574
##   osp2 254 595
##   osp3 232 603
# Visualizzazione grafica
ggplot(neonati, aes(x = Ospedale, fill = Tipo_parto)) +
  geom_bar(position = "fill") +
  labs(title = "Proporzione di Tipi di Parto per Ospedale",
       x = "Ospedale", y = "Proporzione") +
  scale_y_continuous(labels = scales::percent) +
  theme_minimal()

# Test chi-quadrato per verificare l'associazione
chi_test <- chisq.test(cont_table)
print(chi_test)
## 
##  Pearson's Chi-squared test
## 
## data:  cont_table
## X-squared = 1.0972, df = 2, p-value = 0.5778
# Post-hoc analysis con test di proporzione a coppie
pairwise.prop.test(cont_table, p.adjust.method = "bonferroni")
## 
##  Pairwise comparisons using Pairwise comparison of proportions 
## 
## data:  cont_table 
## 
##      osp1 osp2
## osp2 1    -   
## osp3 1    1   
## 
## P value adjustment method: bonferroni

3.2 Ipotesi 2: Confronto delle medie del peso e della lunghezza con valori di riferimento

# Valori di riferimento per la popolazione italiana (esempio)
# Questi valori dovrebbero essere sostituiti con dati reali di riferimento
peso_rif <- 3300 # grammi, valore medio di riferimento
lunghezza_rif <- 50 # cm, valore medio di riferimento

# Test t per il peso
t_test_peso <- t.test(neonati$Peso, mu = peso_rif)
print(t_test_peso)
## 
##  One Sample t-test
## 
## data:  neonati$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
# Test t per la lunghezza
t_test_lunghezza <- t.test(neonati$Lunghezza, mu = lunghezza_rif)
print(t_test_lunghezza)
## 
##  One Sample t-test
## 
## data:  neonati$Lunghezza
## t = 844.82, df = 2499, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 50
## 95 percent confidence interval:
##  493.6598 495.7242
## sample estimates:
## mean of x 
##   494.692
# Visualizzazione delle distribuzioni con linee di riferimento
peso_plot <- ggplot(neonati, aes(x = Peso)) +
  geom_histogram(fill = "steelblue", color = "white", bins = 30) +
  geom_vline(xintercept = peso_rif, color = "red", linetype = "dashed", size = 1) +
  geom_vline(xintercept = mean(neonati$Peso), color = "green", linetype = "solid", size = 1) +
  labs(title = "Distribuzione del Peso con Riferimento",
       x = "Peso (g)", y = "Conteggio") +
  annotate("text", x = peso_rif + 150, y = 150, label = "Rif. Pop.", color = "red") +
  annotate("text", x = mean(neonati$Peso) + 150, y = 180, label = "Media Camp.", color = "green") +
  theme_minimal()

lunghezza_plot <- ggplot(neonati, aes(x = Lunghezza)) +
  geom_histogram(fill = "steelblue", color = "white", bins = 30) +
  geom_vline(xintercept = lunghezza_rif, color = "red", linetype = "dashed", size = 1) +
  geom_vline(xintercept = mean(neonati$Lunghezza), color = "green", linetype = "solid", size = 1) +
  labs(title = "Distribuzione della Lunghezza con Riferimento",
       x = "Lunghezza (cm)", y = "Conteggio") +
  annotate("text", x = lunghezza_rif + 1, y = 150, label = "Rif. Pop.", color = "red") +
  annotate("text", x = mean(neonati$Lunghezza) + 1, y = 180, label = "Media Camp.", color = "green") +
  theme_minimal()

peso_plot / lunghezza_plot

3.3 Ipotesi 3: Differenze nelle misure antropometriche tra i sessi

# Test t per confrontare il peso tra i sessi
t_test_peso_sesso <- t.test(Peso ~ Sesso, data = neonati)
print(t_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
# Test t per confrontare la lunghezza tra i sessi
t_test_lunghezza_sesso <- t.test(Lunghezza ~ Sesso, data = neonati)
print(t_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
# Test t per confrontare il diametro cranico tra i sessi
t_test_cranio_sesso <- t.test(Cranio ~ Sesso, data = neonati)
print(t_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
# Visualizzazione delle differenze con boxplot
anthropometric_vars <- c("Peso", "Lunghezza", "Cranio")
anthropometric_plots <- lapply(anthropometric_vars, function(var) {
  ggplot(neonati, aes_string(x = "Sesso", y = var, fill = "Sesso")) +
    geom_boxplot() +
    labs(title = paste("Confronto di", var, "tra i Sessi"),
         x = "Sesso", y = var) +
    theme_minimal() +
    theme(legend.position = "none")
})

wrap_plots(anthropometric_plots, ncol = 3)

# MANOVA per testare le differenze in tutte le variabili antropometriche simultaneamente
manova_result <- manova(cbind(Peso, Lunghezza, Cranio) ~ Sesso, data = neonati)
summary(manova_result)
##             Df  Pillai approx F num Df den Df    Pr(>F)    
## Sesso        1 0.05614   49.487      3   2496 < 2.2e-16 ***
## Residuals 2498                                             
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Calcolo delle statistiche descrittive per gruppo
neonati %>%
  group_by(Sesso) %>%
  summarise(
    Media_Peso = mean(Peso),
    DS_Peso = sd(Peso),
    Media_Lunghezza = mean(Lunghezza),
    DS_Lunghezza = sd(Lunghezza),
    Media_Cranio = mean(Cranio),
    DS_Cranio = sd(Cranio)
  ) %>%
  kbl() %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Sesso Media_Peso DS_Peso Media_Lunghezza DS_Lunghezza Media_Cranio DS_Cranio
F 3161.132 526.3091 489.7643 27.53415 337.6330 16.73772
M 3408.215 493.8043 499.6672 24.03809 342.4486 15.74448

4. Modello Predittivo per il Peso alla Nascita

4.1 Identificazione e Gestione degli Outlier

# Funzione per identificare outlier usando il metodo IQR
outliers_detector <- function(x) {
  Q1 <- quantile(x, 0.25)
  Q3 <- quantile(x, 0.75)
  IQR <- Q3 - Q1
  lower_bound <- Q1 - 1.5 * IQR
  upper_bound <- Q3 + 1.5 * IQR
  return(x < lower_bound | x > upper_bound)
}

# Identificazione degli outlier nella variabile Peso
outliers_peso <- outliers_detector(neonati$Peso)
cat("Numero di outlier in Peso:", sum(outliers_peso), "su", length(neonati$Peso), "osservazioni\n")
## Numero di outlier in Peso: 69 su 2500 osservazioni
# Visualizzazione con boxplot
par(mfrow = c(1, 2))
boxplot(neonati$Peso, main = "Peso - Con outlier", col = "lightblue")
boxplot(neonati$Peso[!outliers_peso], main = "Peso - Senza outlier", col = "lightgreen")

par(mfrow = c(1, 1))

# Creazione di un dataset senza outlier per confronto
neonati_no_outliers <- neonati[!outliers_peso, ]
cat("Dimensione del dataset originale:", nrow(neonati), "\n")
## Dimensione del dataset originale: 2500
cat("Dimensione del dataset senza outlier:", nrow(neonati_no_outliers), "\n")
## Dimensione del dataset senza outlier: 2431
# Confronto delle statistiche descrittive con e senza outlier
summary_comparison <- data.frame(
  Statistica = c("Media", "Mediana", "Min", "Max", "SD"),
  Con_Outlier = c(mean(neonati$Peso), median(neonati$Peso), min(neonati$Peso), max(neonati$Peso), sd(neonati$Peso)),
  Senza_Outlier = c(mean(neonati_no_outliers$Peso), median(neonati_no_outliers$Peso), min(neonati_no_outliers$Peso), max(neonati_no_outliers$Peso), sd(neonati_no_outliers$Peso))
)

summary_comparison %>%
  kbl() %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Statistica Con_Outlier Senza_Outlier
Media 3284.0808 3314.9329
Mediana 3300.0000 3300.0000
Min 830.0000 2050.0000
Max 4930.0000 4560.0000
SD 525.0387 447.8165

4.2 Preparazione dei Dati per il Modello

# Valutare se usare il dataset originale o quello senza outlier
# Per questa analisi, useremo entrambi per confronto
set.seed(42) # Per riproducibilità

# Dataset originale
training_index <- createDataPartition(neonati$Peso, p = 0.8, list = FALSE)
training_set <- neonati[training_index, ]
test_set <- neonati[-training_index, ]

# Dataset senza outlier
training_index_no_out <- createDataPartition(neonati_no_outliers$Peso, p = 0.8, list = FALSE)
training_set_no_out <- neonati_no_outliers[training_index_no_out, ]
test_set_no_out <- neonati_no_outliers[-training_index_no_out, ]

# Dimensioni dei dataset
cat("Dimensioni del training set originale:", dim(training_set), "\n")
## Dimensioni del training set originale: 2002 10
cat("Dimensioni del test set originale:", dim(test_set), "\n")
## Dimensioni del test set originale: 498 10
cat("Dimensioni del training set senza outlier:", dim(training_set_no_out), "\n")
## Dimensioni del training set senza outlier: 1946 10
cat("Dimensioni del test set senza outlier:", dim(test_set_no_out), "\n")
## Dimensioni del test set senza outlier: 485 10
# Trasformazione logaritmica della variabile target
# Aggiungiamo la variabile log_Peso per valutare modelli con target trasformato
neonati$log_Peso <- log(neonati$Peso)
training_set$log_Peso <- log(training_set$Peso)
test_set$log_Peso <- log(test_set$Peso)

# Visualizzazione della distribuzione originale vs log-trasformata
par(mfrow = c(1, 2))
hist(neonati$Peso, main = "Distribuzione del Peso", col = "lightblue")
hist(neonati$log_Peso, main = "Distribuzione del log(Peso)", col = "lightgreen")

par(mfrow = c(1, 1))

4.3 Costruzione del Modello di Regressione Lineare

# Modello lineare completo
full_model <- lm(Peso ~ Eta_madre + N_gravidanze + Fumatrice + Gestazione +
                Lunghezza + Cranio + Tipo_parto + Ospedale + Sesso, data = training_set)

# Modello con variabile target log-trasformata
log_model <- lm(log_Peso ~ Eta_madre + N_gravidanze + Fumatrice + Gestazione +
               Lunghezza + Cranio + Tipo_parto + Ospedale + Sesso, data = training_set)

# Riepilogo dei modelli
summary(full_model)
## 
## Call:
## lm(formula = Peso ~ Eta_madre + N_gravidanze + Fumatrice + Gestazione + 
##     Lunghezza + Cranio + Tipo_parto + Ospedale + Sesso, data = training_set)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1133.45  -180.66   -14.09   165.36  1431.28 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   -6665.3835   152.8345 -43.612  < 2e-16 ***
## Eta_madre         0.7223     1.2566   0.575  0.56547    
## N_gravidanze     10.7770     5.1610   2.088  0.03691 *  
## FumatriceSi     -15.7222    30.5179  -0.515  0.60648    
## Gestazione       28.5429     4.1790   6.830 1.12e-11 ***
## Lunghezza        11.2931     0.3412  33.095  < 2e-16 ***
## Cranio            9.2608     0.4758  19.465  < 2e-16 ***
## Tipo_partoNat    40.9279    13.4420   3.045  0.00236 ** 
## Ospedaleosp2     -6.3149    14.8534  -0.425  0.67078    
## Ospedaleosp3     30.4889    14.9378   2.041  0.04138 *  
## SessoM           67.7361    12.3477   5.486 4.64e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 271.2 on 1991 degrees of freedom
## Multiple R-squared:  0.7399, Adjusted R-squared:  0.7386 
## F-statistic: 566.3 on 10 and 1991 DF,  p-value: < 2.2e-16
summary(log_model)
## 
## Call:
## lm(formula = log_Peso ~ Eta_madre + N_gravidanze + Fumatrice + 
##     Gestazione + Lunghezza + Cranio + Tipo_parto + Ospedale + 
##     Sesso, data = training_set)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.39470 -0.05496 -0.00061  0.05368  0.51754 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    4.3826745  0.0482140  90.900  < 2e-16 ***
## Eta_madre      0.0001092  0.0003964   0.275   0.7830    
## N_gravidanze   0.0037258  0.0016281   2.288   0.0222 *  
## FumatriceSi   -0.0028773  0.0096273  -0.299   0.7651    
## Gestazione     0.0177720  0.0013183  13.481  < 2e-16 ***
## Lunghezza      0.0038709  0.0001076  35.959  < 2e-16 ***
## Cranio         0.0031353  0.0001501  20.890  < 2e-16 ***
## Tipo_partoNat  0.0110556  0.0042405   2.607   0.0092 ** 
## Ospedaleosp2  -0.0011251  0.0046857  -0.240   0.8103    
## Ospedaleosp3   0.0096537  0.0047123   2.049   0.0406 *  
## SessoM         0.0154170  0.0038953   3.958 7.83e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.08554 on 1991 degrees of freedom
## Multiple R-squared:  0.7909, Adjusted R-squared:  0.7898 
## F-statistic: 752.9 on 10 and 1991 DF,  p-value: < 2.2e-16
# Analisi della varianza
anova(full_model)
## Analysis of Variance Table
## 
## Response: Peso
##                Df    Sum Sq   Mean Sq   F value    Pr(>F)    
## Eta_madre       1    152531    152531    2.0746  0.149924    
## N_gravidanze    1      2807      2807    0.0382  0.845110    
## Fumatrice       1     75403     75403    1.0256  0.311324    
## Gestazione      1 205947440 205947440 2801.1549 < 2.2e-16 ***
## Lunghezza       1 178006214 178006214 2421.1176 < 2.2e-16 ***
## Cranio          1  28732047  28732047  390.7935 < 2.2e-16 ***
## Tipo_parto      1    703815    703815    9.5728  0.002002 ** 
## Ospedale        2    539355    269678    3.6680  0.025701 *  
## Sesso           1   2212529   2212529   30.0933 4.642e-08 ***
## Residuals    1991 146382965     73522                        
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Controllo della multicollinearità
vif_values <- vif(full_model)
print(vif_values)
##                  GVIF Df GVIF^(1/(2*Df))
## Eta_madre    1.193733  1        1.092581
## N_gravidanze 1.189832  1        1.090794
## Fumatrice    1.007809  1        1.003897
## Gestazione   1.739855  1        1.319036
## Lunghezza    2.213195  1        1.487681
## Cranio       1.694284  1        1.301647
## Tipo_parto   1.003042  1        1.001520
## Ospedale     1.005440  2        1.001357
## Sesso        1.037896  1        1.018772

4.4 Diagnostica del Modello

# Grafici diagnostici per il modello originale
par(mfrow = c(2, 2))
plot(full_model)

par(mfrow = c(1, 1))

# Grafici diagnostici per il modello con log-trasformazione
par(mfrow = c(2, 2))
plot(log_model)

par(mfrow = c(1, 1))

# Test di normalità dei residui per entrambi i modelli
shapiro_test_orig <- shapiro.test(residuals(full_model))
shapiro_test_log <- shapiro.test(residuals(log_model))

cat("Test di Shapiro-Wilk per normalità dei residui (modello originale):\n")
## Test di Shapiro-Wilk per normalità dei residui (modello originale):
print(shapiro_test_orig)
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(full_model)
## W = 0.98728, p-value = 2.512e-12
cat("\nTest di Shapiro-Wilk per normalità dei residui (modello log-trasformato):\n")
## 
## Test di Shapiro-Wilk per normalità dei residui (modello log-trasformato):
print(shapiro_test_log)
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(log_model)
## W = 0.98773, p-value = 4.756e-12
# Test di omoschedasticità per entrambi i modelli
bp_test_orig <- bptest(full_model)
bp_test_log <- bptest(log_model)

cat("Test di Breusch-Pagan per omoschedasticità (modello originale):\n")
## Test di Breusch-Pagan per omoschedasticità (modello originale):
print(bp_test_orig)
## 
##  studentized Breusch-Pagan test
## 
## data:  full_model
## BP = 14.766, df = 10, p-value = 0.1408
cat("\nTest di Breusch-Pagan per omoschedasticità (modello log-trasformato):\n")
## 
## Test di Breusch-Pagan per omoschedasticità (modello log-trasformato):
print(bp_test_log)
## 
##  studentized Breusch-Pagan test
## 
## data:  log_model
## BP = 81.463, df = 10, p-value = 2.592e-13

4.5 Selezione del Modello

# Selezione step-wise basata su AIC per entrambi i modelli
step_model <- stepAIC(full_model, direction = "both", trace = FALSE)
step_log_model <- stepAIC(log_model, direction = "both", trace = FALSE)

# Confronto tra modelli
anova(step_model, full_model)
## Analysis of Variance Table
## 
## Model 1: Peso ~ N_gravidanze + Gestazione + Lunghezza + Cranio + Tipo_parto + 
##     Ospedale + Sesso
## Model 2: Peso ~ Eta_madre + N_gravidanze + Fumatrice + Gestazione + Lunghezza + 
##     Cranio + Tipo_parto + Ospedale + Sesso
##   Res.Df       RSS Df Sum of Sq      F Pr(>F)
## 1   1993 146426260                           
## 2   1991 146382965  2     43295 0.2944  0.745
anova(step_log_model, log_model)
## Analysis of Variance Table
## 
## Model 1: log_Peso ~ N_gravidanze + Gestazione + Lunghezza + Cranio + Tipo_parto + 
##     Ospedale + Sesso
## Model 2: log_Peso ~ Eta_madre + N_gravidanze + Fumatrice + Gestazione + 
##     Lunghezza + Cranio + Tipo_parto + Ospedale + Sesso
##   Res.Df    RSS Df Sum of Sq      F Pr(>F)
## 1   1993 14.569                           
## 2   1991 14.568  2 0.0011946 0.0816 0.9216
# Riepilogo dei modelli selezionati
summary(step_model)
## 
## Call:
## lm(formula = Peso ~ N_gravidanze + Gestazione + Lunghezza + Cranio + 
##     Tipo_parto + Ospedale + Sesso, data = training_set)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1124.49  -181.70   -14.97   165.66  1434.18 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   -6641.2699   147.0726 -45.156  < 2e-16 ***
## N_gravidanze     11.7379     4.7818   2.455   0.0142 *  
## Gestazione       28.1504     4.1444   6.792 1.45e-11 ***
## Lunghezza        11.3023     0.3408  33.160  < 2e-16 ***
## Cranio            9.2761     0.4751  19.525  < 2e-16 ***
## Tipo_partoNat    40.8410    13.4367   3.040   0.0024 ** 
## Ospedaleosp2     -6.2677    14.8480  -0.422   0.6730    
## Ospedaleosp3     30.9582    14.9199   2.075   0.0381 *  
## SessoM           67.8020    12.3393   5.495 4.41e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 271.1 on 1993 degrees of freedom
## Multiple R-squared:  0.7398, Adjusted R-squared:  0.7388 
## F-statistic: 708.3 on 8 and 1993 DF,  p-value: < 2.2e-16
summary(step_log_model)
## 
## Call:
## lm(formula = log_Peso ~ N_gravidanze + Gestazione + Lunghezza + 
##     Cranio + Tipo_parto + Ospedale + Sesso, data = training_set)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.39592 -0.05488 -0.00047  0.05378  0.51800 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    4.3863305  0.0463914  94.551  < 2e-16 ***
## N_gravidanze   0.0038666  0.0015083   2.563  0.01044 *  
## Gestazione     0.0177086  0.0013073  13.546  < 2e-16 ***
## Lunghezza      0.0038725  0.0001075  36.019  < 2e-16 ***
## Cranio         0.0031377  0.0001499  20.938  < 2e-16 ***
## Tipo_partoNat  0.0110415  0.0042384   2.605  0.00925 ** 
## Ospedaleosp2  -0.0011172  0.0046835  -0.239  0.81149    
## Ospedaleosp3   0.0097307  0.0047062   2.068  0.03880 *  
## SessoM         0.0154242  0.0038922   3.963 7.67e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.0855 on 1993 degrees of freedom
## Multiple R-squared:  0.7908, Adjusted R-squared:   0.79 
## F-statistic:   942 on 8 and 1993 DF,  p-value: < 2.2e-16
# Confronto tra tutti i modelli in base all'R² aggiustato e AIC
model_comparison <- data.frame(
  Modello = c("Completo", "Step-wise", "Log-Completo", "Log-Step-wise"),
  R2_adj = c(summary(full_model)$adj.r.squared, 
             summary(step_model)$adj.r.squared,
             summary(log_model)$adj.r.squared,
             summary(step_log_model)$adj.r.squared),
  AIC = c(AIC(full_model), 
          AIC(step_model),
          AIC(log_model),
          AIC(step_log_model))
)

model_comparison %>%
  kbl() %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Modello R2_adj AIC
Completo 0.7385751 28127.499
Step-wise 0.7387602 28124.091
Log-Completo 0.7898152 -4150.590
Log-Step-wise 0.7900089 -4154.426

4.6 Validazione del Modello con Cross-validazione

# Configurazione della cross-validazione a k-fold
set.seed(123)
train_control <- trainControl(method = "cv", number = 10)

# Addestramento del modello con cross-validazione
cv_model <- train(
  Peso ~ N_gravidanze + Gestazione + Lunghezza + Cranio + Tipo_parto + Ospedale + Sesso,
  data = neonati,
  method = "lm",
  trControl = train_control
)

# Risultati della cross-validazione
print(cv_model)
## Linear Regression 
## 
## 2500 samples
##    7 predictor
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 2250, 2249, 2251, 2250, 2250, 2250, ... 
## Resampling results:
## 
##   RMSE      Rsquared   MAE     
##   274.2683  0.7248875  210.4588
## 
## Tuning parameter 'intercept' was held constant at a value of TRUE
cat("\nPerformance media su 10-fold CV:", 
    paste("RMSE =", round(cv_model$results$RMSE, 2), "g,",
          "R² =", round(cv_model$results$Rsquared, 3)))
## 
## Performance media su 10-fold CV: RMSE = 274.27 g, R² = 0.725
# Cross-validazione per il modello log-trasformato
cv_log_model <- train(
  log_Peso ~ N_gravidanze + Gestazione + Lunghezza + Cranio + Tipo_parto + Ospedale + Sesso,
  data = neonati,
  method = "lm",
  trControl = train_control
)

print(cv_log_model)
## Linear Regression 
## 
## 2500 samples
##    7 predictor
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 2250, 2250, 2251, 2249, 2250, 2251, ... 
## Resampling results:
## 
##   RMSE        Rsquared   MAE       
##   0.08648719  0.7727106  0.06617148
## 
## Tuning parameter 'intercept' was held constant at a value of TRUE

4.7 Valutazione dell’Importanza delle Variabili

# Importanza delle variabili nel modello
varImp_cv <- varImp(cv_model)
plot(varImp_cv, top = 10, main = "Importanza delle Variabili nel Modello")

# Creare un grafico personalizzato dell'importanza delle variabili
var_importance <- as.data.frame(varImp_cv$importance)
var_importance$Variable <- rownames(var_importance)
var_importance <- var_importance[order(var_importance$Overall, decreasing = TRUE), ]

ggplot(var_importance, aes(x = reorder(Variable, Overall), y = Overall)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  coord_flip() +
  labs(title = "Importanza delle Variabili nel Modello",
       x = "Variabile", y = "Importanza") +
  theme_minimal()

4.8 Confronto con Modelli Alternativi

# Addestramento di un modello Random Forest
set.seed(123)
rf_model <- train(
  Peso ~ N_gravidanze + Gestazione + Lunghezza + Cranio + Tipo_parto + Ospedale + Sesso,
  data = neonati,
  method = "rf",
  trControl = train_control,
  ntree = 100
)

# Confronto tra modelli
models_list <- list(
  LinearModel = cv_model,
  RandomForest = rf_model
)

results <- resamples(models_list)
summary(results)
## 
## Call:
## summary.resamples(object = results)
## 
## Models: LinearModel, RandomForest 
## Number of resamples: 10 
## 
## MAE 
##                  Min.  1st Qu.   Median     Mean  3rd Qu.     Max. NA's
## LinearModel  193.4207 204.9437 210.1666 210.4588 215.9928 227.5142    0
## RandomForest 196.2256 211.4659 214.1994 216.6700 226.4061 231.3790    0
## 
## RMSE 
##                  Min.  1st Qu.   Median     Mean  3rd Qu.     Max. NA's
## LinearModel  244.6356 267.8105 269.9106 274.2683 278.3420 323.8802    0
## RandomForest 249.7530 270.3874 275.8728 278.1217 292.1085 296.0758    0
## 
## Rsquared 
##                   Min.   1st Qu.    Median      Mean   3rd Qu.      Max. NA's
## LinearModel  0.6102050 0.7072107 0.7330453 0.7248875 0.7497451 0.8099513    0
## RandomForest 0.6754643 0.6807074 0.7199982 0.7235355 0.7521509 0.8050224    0
# Visualizzazione del confronto
bwplot(results, main = "Confronto tra Modelli")

# Predizioni sul test set per entrambi i modelli
lm_predictions <- predict(step_model, newdata = test_set)
rf_predictions <- predict(rf_model, newdata = test_set)

# Metriche di valutazione
lm_rmse <- sqrt(mean((test_set$Peso - lm_predictions)^2))
rf_rmse <- sqrt(mean((test_set$Peso - rf_predictions)^2))
lm_r2 <- cor(test_set$Peso, lm_predictions)^2
rf_r2 <- cor(test_set$Peso, rf_predictions)^2

# Riepilogo delle metriche
metrics_comparison <- data.frame(
  Modello = c("Regressione Lineare", "Random Forest"),
  RMSE = c(lm_rmse, rf_rmse),
  R2 = c(lm_r2, rf_r2)
)

metrics_comparison %>%
  kbl() %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Modello RMSE R2
Regressione Lineare 288.9667 0.6710005
Random Forest 198.2651 0.8632661
# Grafico delle predizioni per entrambi i modelli
test_set$LM_Predictions <- lm_predictions
test_set$RF_Predictions <- rf_predictions

lm_plot <- ggplot(test_set, aes(x = Peso, y = LM_Predictions)) +
  geom_point(alpha = 0.7) +
  geom_abline(intercept = 0, slope = 1, color = "red", linetype = "dashed") +
  labs(title = "Regressione Lineare: Predetti vs Reali",
       x = "Peso Reale (g)", y = "Peso Predetto (g)") +
  theme_minimal()

rf_plot <- ggplot(test_set, aes(x = Peso, y = RF_Predictions)) +
  geom_point(alpha = 0.7) +
  geom_abline(intercept = 0, slope = 1, color = "red", linetype = "dashed") +
  labs(title = "Random Forest: Predetti vs Reali",
       x = "Peso Reale (g)", y = "Peso Predetto (g)") +
  theme_minimal()

lm_plot + rf_plot

5. Analisi Avanzata

5.1 Effetto dell’Interazione tra Variabili

# Modello con interazioni di interesse
interaction_model <- lm(Peso ~ Gestazione + Fumatrice + Sesso + Gestazione:Fumatrice + Gestazione:Sesso,
                      data = training_set)
summary(interaction_model)
## 
## Call:
## lm(formula = Peso ~ Gestazione + Fumatrice + Sesso + Gestazione:Fumatrice + 
##     Gestazione:Sesso, data = training_set)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1529.26  -280.29   -19.14   270.13  1950.99 
## 
## Coefficients:
##                          Estimate Std. Error t value Pr(>|t|)    
## (Intercept)            -3102.7270   250.4777 -12.387   <2e-16 ***
## Gestazione               162.0497     6.4593  25.088   <2e-16 ***
## FumatriceSi             1423.0729  1243.4824   1.144    0.253    
## SessoM                   125.6626   389.5974   0.323    0.747    
## Gestazione:FumatriceSi   -38.4954    31.6533  -1.216    0.224    
## Gestazione:SessoM          0.8126     9.9775   0.081    0.935    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 417 on 1996 degrees of freedom
## Multiple R-squared:  0.3834, Adjusted R-squared:  0.3818 
## F-statistic: 248.2 on 5 and 1996 DF,  p-value: < 2.2e-16
# Visualizzazione degli effetti di interazione
interaction.plot(x.factor = cut(neonati$Gestazione, breaks = 5), 
                trace.factor = neonati$Sesso, 
                response = neonati$Peso,
                xlab = "Settimane di Gestazione",
                ylab = "Peso Medio (g)",
                trace.label = "Sesso",
                col = c("blue", "red"),
                lwd = 2)

interaction.plot(x.factor = cut(neonati$Gestazione, breaks = 5), 
                trace.factor = neonati$Fumatrice, 
                response = neonati$Peso,
                xlab = "Settimane di Gestazione",
                ylab = "Peso Medio (g)",
                trace.label = "Fumatrice",
                col = c("green", "orange"),
                lwd = 2)

# Visualizzazione migliorata delle interazioni con ggplot2
ggplot(neonati, aes(x = Gestazione, y = Peso, color = Sesso)) +
  geom_point(alpha = 0.3) +
  geom_smooth(method = "lm", se = TRUE) +
  labs(title = "Interazione tra Gestazione e Sesso",
       x = "Settimane di Gestazione", y = "Peso (g)") +
  theme_minimal()

ggplot(neonati, aes(x = Gestazione, y = Peso, color = Fumatrice)) +
  geom_point(alpha = 0.3) +
  geom_smooth(method = "lm", se = TRUE) +
  labs(title = "Interazione tra Gestazione e Abitudine al Fumo",
       x = "Settimane di Gestazione", y = "Peso (g)") +
  theme_minimal()

5.2 Analisi per Sottogruppi

# Analisi per ospedale
ggplot(neonati, aes(x = Ospedale, y = Peso, fill = Ospedale)) +
  geom_boxplot() +
  labs(title = "Distribuzione del Peso per Ospedale",
       x = "Ospedale", y = "Peso (g)") +
  theme_minimal() +
  theme(legend.position = "none")

# ANOVA per differenze tra ospedali
hospital_anova <- aov(Peso ~ Ospedale, data = neonati)
summary(hospital_anova)
##               Df    Sum Sq Mean Sq F value Pr(>F)
## Ospedale       2    936237  468118   1.699  0.183
## Residuals   2497 687952305  275512
TukeyHSD(hospital_anova)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = Peso ~ Ospedale, data = neonati)
## 
## $Ospedale
##                 diff       lwr       upr     p adj
## osp2-osp1  0.2169897 -60.12780  60.56178 0.9999608
## osp3-osp1 41.1412543 -19.45096 101.73347 0.2491220
## osp3-osp2 40.9242645 -19.06942 100.91795 0.2459336
# Analisi per fumatori/non fumatori
ggplot(neonati, aes(x = Fumatrice, y = Peso, fill = Fumatrice)) +
  geom_boxplot() +
  labs(title = "Distribuzione del Peso per Abitudine al Fumo",
       x = "Fumatrice", y = "Peso (g)") +
  theme_minimal() +
  theme(legend.position = "none")

# Test t per differenze tra fumatori/non fumatori
t.test(Peso ~ Fumatrice, data = neonati)
## 
##  Welch Two Sample t-test
## 
## data:  Peso by Fumatrice
## t = 1.034, df = 114.1, p-value = 0.3033
## alternative hypothesis: true difference in means between group No and group Si is not equal to 0
## 95 percent confidence interval:
##  -45.61354 145.22674
## sample estimates:
## mean in group No mean in group Si 
##         3286.153         3236.346
# Modelli separati per sottogruppi
# Modello per neonati maschi
model_M <- lm(Peso ~ Gestazione + Lunghezza + Cranio, data = subset(neonati, Sesso == "M"))
summary(model_M)
## 
## Call:
## lm(formula = Peso ~ Gestazione + Lunghezza + Cranio, data = subset(neonati, 
##     Sesso == "M"))
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1150.58  -178.31   -10.95   168.56  1396.31 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -6799.3898   204.6728 -33.221  < 2e-16 ***
## Gestazione     31.3569     5.5886   5.611 2.48e-08 ***
## Lunghezza      10.7254     0.4461  24.040  < 2e-16 ***
## Cranio         10.5661     0.6056  17.448  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 269.3 on 1240 degrees of freedom
## Multiple R-squared:  0.7034, Adjusted R-squared:  0.7026 
## F-statistic:   980 on 3 and 1240 DF,  p-value: < 2.2e-16
# Modello per neonati femmine
model_F <- lm(Peso ~ Gestazione + Lunghezza + Cranio, data = subset(neonati, Sesso == "F"))
summary(model_F)
## 
## Call:
## lm(formula = Peso ~ Gestazione + Lunghezza + Cranio, data = subset(neonati, 
##     Sesso == "F"))
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1020.64  -190.25   -25.16   157.09  2556.91 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -6485.0132   183.6378 -35.314  < 2e-16 ***
## Gestazione     31.6086     5.1692   6.115 1.29e-09 ***
## Lunghezza       9.8102     0.4082  24.032  < 2e-16 ***
## Cranio         10.7133     0.5961  17.972  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 280.5 on 1252 degrees of freedom
## Multiple R-squared:  0.7167, Adjusted R-squared:  0.716 
## F-statistic:  1056 on 3 and 1252 DF,  p-value: < 2.2e-16
# Confronto tra coefficienti dei due modelli
coefficients_comparison <- data.frame(
  Variabile = c("Intercetta", "Gestazione", "Lunghezza", "Cranio"),
  Maschi = c(coef(model_M)[1], coef(model_M)[2], coef(model_M)[3], coef(model_M)[4]),
  Femmine = c(coef(model_F)[1], coef(model_F)[2], coef(model_F)[3], coef(model_F)[4])
)

coefficients_comparison %>%
  kbl() %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Variabile Maschi Femmine
(Intercept) Intercetta -6799.38979 -6485.013182
Gestazione Gestazione 31.35687 31.608599
Lunghezza Lunghezza 10.72541 9.810191
Cranio Cranio 10.56609 10.713288

6. Conclusioni e Discussione

6.1 Sintesi dei principali risultati

La nostra analisi ha identificato diversi fattori significativi che influenzano il peso alla nascita dei neonati:

Modello predittivo del peso neonatale

Il modello di regressione lineare ottimale (dopo selezione stepwise) ha evidenziato le seguenti variabili come significative:

  • Settimane di gestazione: Un aumento di una settimana di gestazione è associato a un incremento medio di 28.15 g nel peso neonatale (p < 0.001)
  • Lunghezza: Ogni cm aggiuntivo di lunghezza è associato a un incremento di 11.3 g nel peso (p < 0.001)
  • Diametro cranico: Ogni cm aggiuntivo di circonferenza cranica è associato a un incremento di 9.28 g nel peso (p < 0.001)
  • Tipo di parto naturale: I neonati nati con parto naturale pesano in media 40.84 g in più rispetto ai nati con cesareo (p < 0.01)
  • Sesso maschile: I neonati maschi pesano in media 67.8 g in più rispetto alle femmine (p < 0.001)
  • Numero di gravidanze: Ogni gravidanza precedente è associata a un incremento di 11.74 g nel peso (p < 0.05)

Il modello ha mostrato una buona capacità predittiva con un R² aggiustato di 0.739, indicando che circa il 73.9% della variabilità nel peso neonatale può essere spiegata dalle variabili incluse.

Performance del modello

  • Regressione lineare:
    • R² sul test set: 0.671
    • RMSE (errore quadratico medio): 288.97 g
  • Random Forest:
    • R² sul test set: 0.863
    • RMSE: 198.27 g

Il modello Random Forest ha mostrato performance significativamente migliori rispetto alla regressione lineare, suggerendo relazioni non lineari tra le variabili predittive e il peso alla nascita.

Confronto delle predizioni dei modelli sul test set

Confronto delle predizioni dei modelli sul test set

Verifica delle ipotesi

  1. Differenze tra ospedali nei parti cesarei: Non sono state rilevate differenze statisticamente significative nella frequenza dei parti cesarei tra i tre ospedali (χ² = 1.097, p = 0.578).

  2. Confronto con valori di riferimento:

    • Il peso medio nel campione (3284.08 g) non differisce significativamente dal valore di riferimento di 3300 g (t = -1.516, p = 0.13)
    • La lunghezza media (49.47 cm) differisce significativamente dal valore di riferimento di 50 cm (t = 844.823, p < 0.001)
  3. Differenze tra sessi nelle misure antropometriche:

    • I neonati maschi hanno un peso significativamente maggiore rispetto alle femmine (differenza media: 247.08 g, p < 0.001)
    • I maschi presentano lunghezza maggiore (differenza media: 0.99 cm, p < 0.001)
    • I maschi hanno circonferenza cranica maggiore (differenza media: 0.482 cm, p < 0.001)
Differenze antropometriche tra neonati maschi e femmine

Differenze antropometriche tra neonati maschi e femmine

6.2 Implicazioni cliniche

I risultati di questa analisi hanno diverse implicazioni per la pratica clinica:

  1. Identificazione di neonati a rischio: Il modello sviluppato può aiutare a identificare precocemente i neonati a rischio di basso peso, consentendo un intervento tempestivo.

  2. Gestione personalizzata delle gravidanze: Le variabili identificate come più influenti (gestazione, lunghezza, circonferenza cranica) possono essere monitorate con maggiore attenzione durante la gravidanza per valutare il rischio di peso inadeguato alla nascita.

  3. Pianificazione delle risorse ospedaliere: La capacità di prevedere con maggiore precisione il peso alla nascita può aiutare nell’allocazione delle risorse neonatali.

  4. Approccio differenziato per sesso: Date le differenze significative tra neonati maschi e femmine, potrebbe essere utile considerare il sesso nelle valutazioni cliniche prenatali.

  5. Implementazione di modelli avanzati: Il modello Random Forest ha mostrato performance superiori, suggerendo l’utilità di approcci di machine learning nella pratica clinica per migliorare la precisione predittiva.

6.3 Limitazioni dello studio

Nonostante i risultati promettenti, questo studio presenta alcune limitazioni:

  1. Rappresentatività del campione: I dati provengono da soli tre ospedali, limitando potenzialmente la generalizzabilità dei risultati.

  2. Variabili non considerate: Fattori potenzialmente rilevanti come la nutrizione materna, lo status socioeconomico e complicazioni della gravidanza non sono stati inclusi nel modello.

  3. Dimensione temporale: Lo studio non considera l’evoluzione temporale delle gravidanze, limitandosi a misurazioni statiche.

  4. Effetto del fumo: Sebbene le madri fumatrici tendano ad avere neonati con peso inferiore, questa associazione non ha raggiunto la significatività statistica nel nostro campione, probabilmente a causa del numero limitato di fumatrici (4.16%).

  5. Interpretabilità del modello Random Forest: Nonostante le performance superiori, i modelli di machine learning sono meno interpretabili rispetto ai modelli lineari, limitando potenzialmente la loro applicabilità clinica.

Importanza delle variabili nel modello Random Forest

Importanza delle variabili nel modello Random Forest

6.4 Direzioni future

Per migliorare ulteriormente questo lavoro, suggeriamo le seguenti direzioni di ricerca:

  1. Espansione del dataset: Includere dati da più ospedali e regioni geografiche per migliorare la generalizzabilità.

  2. Variabili aggiuntive: Integrare fattori materni come BMI pre-gravidanza, aumento di peso durante la gravidanza, nutrizione e comorbidità.

  3. Validazione esterna: Testare il modello su dataset indipendenti per valutarne la robustezza.

  4. Modelli longitudinali: Sviluppare modelli che considerino l’evoluzione temporale dei parametri durante la gravidanza.

  5. Sviluppo di uno strumento clinico: Implementare il modello predittivo in un’applicazione di facile utilizzo per i clinici.

  6. Analisi di altri outcome neonatali: Estendere l’approccio predittivo ad altri parametri di salute neonatale oltre al peso alla nascita.

In conclusione, questo studio fornisce un contributo significativo alla comprensione dei fattori che influenzano il peso neonatale e offre uno strumento predittivo con potenziali applicazioni nella pratica clinica. L’integrazione di approcci di machine learning con l’esperienza clinica potrebbe portare a strategie più efficaci per la gestione delle gravidanze e il miglioramento degli outcome neonatali.