MIN_ANNI_MADRE = 11
#' Crea una variabile categoriale a partire da una variabile numerica.
#'
#' Verifica che il numero di etichette corrisponda al numero di intervalli
#' definiti nei break e crea una nuova colonna categoriale utilizzando
#' la funzione `cut()`.
#'
#' @param dati Data frame contenente i dati.
#' @param variabile Nome della variabile numerica da categorizzare.
#' @param breaks Vettore dei punti di separazione degli intervalli.
#' @param labels Vettore delle etichette associate agli intervalli.
#' @param nome_categoria Nome della nuova variabile categoriale.
#'
#' @return Il data frame con la nuova variabile categoriale.
crea_categoria <- function(dati, variabile, breaks, labels, nome_categoria){
if(length(labels) != length(breaks) - 1){
stop(
paste(
"Errore in", nome_categoria, ":",
length(breaks) - 1,
"etichette richieste ma ne hai fornite",
length(labels)
)
)
}
dati[[nome_categoria]] <- cut(
dati[[variabile]],
breaks = breaks,
labels = labels
)
dati
}
#' Calcola la tabella delle frequenze di una variabile.
#'
#' Restituisce il numero di osservazioni e la percentuale associata
#' a ciascuna modalità della variabile selezionata.
#'
#' @param dati Data frame contenente i dati.
#' @param variabile Nome della variabile di cui calcolare la distribuzione.
#'
#' @return Un data frame contenente:
#' \itemize{
#' \item la modalità della variabile;
#' \item il numero di osservazioni (`n`);
#' \item la percentuale sul totale.
#' }
tabella_frequenze <- function(dati, variabile) {
dati %>%
count(.data[[variabile]]) %>%
mutate(
Percentuale = paste0(round(n / sum(n) * 100, 2), "%")
)
}
#' Controlla la validità dei valori di una variabile categoriale.
#'
#' Visualizza i valori osservati, il numero di valori mancanti
#' ed eventuali modalità non appartenenti all'insieme dei valori attesi.
#'
#' @param dati Data frame contenente i dati.
#' @param variabile Nome della variabile da controllare.
#' @param valori_attesi Vettore contenente i valori ammessi.
#'
#' @return Nessun valore restituito. La funzione stampa a video
#' informazioni di controllo sulla variabile.
controlla_categorie <- function(dati, variabile, valori_attesi) {
valori_osservati <- sort(unique(dati[[variabile]]))
valori_non_validi <- setdiff(valori_osservati, valori_attesi)
data.frame(
Variabile = variabile,
`Valori osservati` = paste(valori_osservati, collapse = ", "),
`Valori mancanti` = sum(is.na(dati[[variabile]])),
`Valori non validi` = if (length(valori_non_validi) == 0)
"Nessuno"
else
paste(valori_non_validi, collapse = ", "),
check.names = FALSE
)
}
#' Stampa una tabella formattata con kable e kableExtra.
#'
#' La funzione formatta un data frame o una matrice come tabella HTML,
#' applicando uno stile uniforme tramite il pacchetto kableExtra.
#' Se l'oggetto fornito non è un data frame né una matrice,
#' viene convertito automaticamente in una tabella.
#'
#' @param x Oggetto da visualizzare come tabella.
#' @param caption Titolo della tabella.
#' @param align Allineamento delle colonne.
#' @param full_width Valore logico che indica se la tabella deve occupare
#' l'intera larghezza disponibile.
#'
#' @return Una tabella formattata pronta per la visualizzazione nel report.
stampa_tabella <- function(x,
caption = NULL,
align = "c",
full_width = FALSE) {
if (!is.data.frame(x) && !is.matrix(x)) {
x <- as.data.frame(t(x))
}
kable(
x,
caption = caption,
align = align
) |>
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = full_width
)
}
#' Calcola e stampa le statistiche descrittive delle variabili numeriche.
#'
#' La funzione seleziona automaticamente le variabili numeriche presenti
#' in un data frame e ne calcola le principali statistiche descrittive:
#' minimo, primo quartile, mediana, media, terzo quartile e massimo.
#' I risultati vengono visualizzati in una tabella formattata.
#'
#' @param df Data frame contenente le variabili da analizzare.
#'
#' @return Una tabella con le statistiche descrittive delle variabili numeriche.
statistiche_descrittive <- function(df) {
num <- df[sapply(df, is.numeric)]
tabella <- do.call(
rbind,
lapply(num, function(x) {
c(
Min = min(x, na.rm = TRUE),
`1° Qu.` = quantile(x, 0.25, na.rm = TRUE),
Mediana = median(x, na.rm = TRUE),
Media = mean(x, na.rm = TRUE),
`3° Qu.` = quantile(x, 0.75, na.rm = TRUE),
Max = max(x, na.rm = TRUE)
)
})
)
tabella <- data.frame(
Variabile = rownames(tabella),
round(tabella, 2),
row.names = NULL
)
stampa_tabella(
tabella,
caption = "Statistiche descrittive delle variabili numeriche"
)
}
#' Stampa una singola statistica in formato tabellare.
#'
#' La funzione crea una tabella composta dal nome della statistica
#' e dal relativo valore, utilizzando la funzione `stampa_tabella()`
#' per mantenere uno stile uniforme nel report.
#'
#' @param nome Nome della statistica.
#' @param valore Valore della statistica.
#' @param caption Titolo della tabella.
#'
#' @return Una tabella contenente il nome e il valore della statistica.
stampa_statistica <- function(nome, valore, caption = NULL) {
stampa_tabella(
data.frame(
Statistica = nome,
Valore = valore
),
caption = caption
)
}
#' Esegue un one sample t-test e stampa i risultati in tabella.
#'
#' La funzione verifica se la media campionaria di una variabile numerica
#' differisce significativamente da un valore ipotizzato della popolazione.
#'
#' @param dati Vettore numerico contenente i dati.
#' @param nome Nome della variabile analizzata.
#' @param mu Valore della media ipotizzata sotto H0.
#'
#' @return Una tabella con statistiche del test, intervallo di confidenza
#' e stima della media campionaria.
test_media <- function(dati, nome, mu) {
test <- t.test(
dati,
mu = mu
)
risultato <- data.frame(
Variabile = nome,
`Media campionaria` = round(mean(dati, na.rm = TRUE), 2),
`Media ipotizzata` = mu,
`Statistica t` = round(unname(test$statistic), 2),
`Gradi liberta` = unname(test$parameter),
`p-value` = format.pval(test$p.value, digits = 2),
`IC 95% inferiore` = round(test$conf.int[1], 2),
`IC 95% superiore` = round(test$conf.int[2], 2),
check.names = FALSE
)
stampa_tabella(
risultato,
caption = paste(
"One Sample t-test per",
nome
)
)
}
#' Esegue un two sample t-test tra due gruppi e stampa i risultati.
#'
#' Confronta la media di una variabile numerica tra due livelli
#' di una variabile categoriale.
#'
#' @param formula Formula del tipo variabile_numerica ~ gruppo.
#' @param dati Data frame contenente le variabili.
#' @param nome Nome descrittivo della variabile analizzata.
#'
#' @return Una tabella con le statistiche del test.
test_confronto_gruppi <- function(formula, dati, nome) {
test <- t.test(
formula,
data = dati
)
variabile <- all.vars(formula)[1]
gruppo <- all.vars(formula)[2]
medie <- aggregate(
dati[[variabile]],
list(dati[[gruppo]]),
mean,
na.rm = TRUE
)
risultato <- data.frame(
Variabile = nome,
Gruppi = paste(levels(dati[[gruppo]]), collapse = " vs "),
`Media gruppo 1` = round(medie$x[1], 2),
`Media gruppo 2` = round(medie$x[2], 2),
`Differenza medie` = round(diff(medie$x), 2),
`Statistica t` = round(unname(test$statistic), 2),
`Gradi liberta` = round(unname(test$parameter), 2),
`p-value` = format.pval(test$p.value, digits = 2),
`IC 95% inferiore` = round(test$conf.int[1], 2),
`IC 95% superiore` = round(test$conf.int[2], 2),
check.names = FALSE
)
stampa_tabella(
risultato,
caption = paste(
"Two Sample t-test per",
nome
)
)
}
#' Esegue una ANOVA a una via e stampa i risultati.
#'
#' Confronta la media di una variabile numerica tra più gruppi
#' definiti da una variabile categoriale.
#'
#' @param formula Formula del modello del tipo variabile ~ gruppo.
#' @param dati Data frame contenente le variabili.
#' @param nome Nome descrittivo dell'analisi.
#'
#' @return Una tabella contenente la statistica F e il p-value.
test_anova <- function(formula, dati, nome) {
modello <- aov(
formula,
data = dati
)
risultato <- summary(modello)[[1]]
tabella <- data.frame(
Fonte = rownames(risultato),
`Gradi liberta` = risultato$Df,
`Somma quadrati` = round(risultato$`Sum Sq`, 2),
`Media quadratica` = round(risultato$`Mean Sq`, 2),
`Statistica F` = round(risultato$`F value`, 2),
`p-value` = format.pval(
risultato$`Pr(>F)`,
digits = 4
),
check.names = FALSE
)
rownames(tabella) <- NULL
stampa_tabella(
tabella,
caption = paste(
"ANOVA a una via per",
nome
)
)
}
#' Esegue un test di correlazione di Pearson e stampa i risultati.
#'
#' Valuta la presenza di una correlazione lineare significativa
#' tra due variabili quantitative.
#'
#' @param x Prima variabile numerica.
#' @param y Seconda variabile numerica.
#' @param nome_x Nome della prima variabile.
#' @param nome_y Nome della seconda variabile.
#'
#' @return Una tabella con coefficiente di correlazione,
#' statistica del test e p-value.
test_correlazione <- function(x, y, nome_x, nome_y) {
test <- cor.test(
x,
y,
method = "pearson"
)
risultato <- data.frame(
Variabile_1 = nome_x,
Variabile_2 = nome_y,
`Coefficiente Pearson (r)` = round(unname(test$estimate), 2),
`Statistica t` = round(unname(test$statistic), 2),
`Gradi liberta` = unname(test$parameter),
`p-value` = format.pval(test$p.value, digits = 2),
`IC 95% inferiore` = round(test$conf.int[1], 2),
`IC 95% superiore` = round(test$conf.int[2], 2),
check.names = FALSE
)
stampa_tabella(
risultato,
caption = paste(
"Correlazione di Pearson tra",
nome_x,
"e",
nome_y
)
)
}
Eseguo un’analisi preliminare del dataset per verificare la presenza di dati mancanti o valori anomali, così da poterli gestire prima dell’addestramento del modello ed evitare che influenzino le previsioni.
I valori mancanti o palesemente errati sono stati sostituiti con la mediana, poiché il loro numero è ridotto e questa misura è robusta rispetto ai valori estremi.
stampa_tabella(
head(dati_neonati),
caption = "Prime sei osservazioni del dataset"
)
| Anni.madre | N.gravidanze | Fumatrici | Gestazione | Peso | Lunghezza | Cranio | Tipo.parto | Ospedale | Sesso |
|---|---|---|---|---|---|---|---|---|---|
| 26 | 0 | 0 | 42 | 3380 | 490 | 325 | Nat | osp3 | M |
| 21 | 2 | 0 | 39 | 3150 | 490 | 345 | Nat | osp1 | F |
| 34 | 3 | 0 | 38 | 3640 | 500 | 375 | Nat | osp2 | M |
| 28 | 1 | 0 | 41 | 3690 | 515 | 365 | Nat | osp2 | M |
| 20 | 0 | 0 | 38 | 3700 | 480 | 335 | Nat | osp3 | F |
| 32 | 0 | 0 | 40 | 3200 | 495 | 340 | Nat | osp2 | F |
statistiche_descrittive(dati_neonati)
| Variabile | Min | X1..Qu..25. | Mediana | Media | X3..Qu..75. | Max |
|---|---|---|---|---|---|---|
| Anni.madre | 0 | 25 | 28 | 28.16 | 32 | 46 |
| N.gravidanze | 0 | 0 | 1 | 0.98 | 1 | 12 |
| Fumatrici | 0 | 0 | 0 | 0.04 | 0 | 1 |
| Gestazione | 25 | 38 | 39 | 38.98 | 40 | 43 |
| Peso | 830 | 2990 | 3300 | 3284.08 | 3620 | 4930 |
| Lunghezza | 310 | 480 | 500 | 494.69 | 510 | 565 |
| Cranio | 235 | 330 | 340 | 340.03 | 350 | 390 |
stampa_tabella(
names(dati_neonati),
caption = "Nomi colonne dataset"
)
| V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 |
|---|---|---|---|---|---|---|---|---|---|
| Anni.madre | N.gravidanze | Fumatrici | Gestazione | Peso | Lunghezza | Cranio | Tipo.parto | Ospedale | Sesso |
stampa_tabella(
colSums(is.na(dati_neonati)),
caption = "Somma valori nulli per colonna"
)
| Anni.madre | N.gravidanze | Fumatrici | Gestazione | Peso | Lunghezza | Cranio | Tipo.parto | Ospedale | Sesso |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
tabella_eta <- as.data.frame.matrix(
t(table(
dati_neonati$Anni.madre[
dati_neonati$Anni.madre <= MIN_ANNI_MADRE - 1
],
useNA = "ifany"
))
)
stampa_tabella(
tabella_eta,
caption = "Frequenza delle età materne inferiori a 11 anni"
)
| 0 | 1 |
|---|---|
| 1 | 1 |
mediana_anni_madre <- median(
dati_neonati$Anni.madre[
dati_neonati$Anni.madre >= MIN_ANNI_MADRE
],
na.rm = TRUE
)
dati_neonati$Anni.madre[
is.na(dati_neonati$Anni.madre) |
(dati_neonati$Anni.madre >= 0 &
dati_neonati$Anni.madre <= MIN_ANNI_MADRE - 1)
] <- mediana_anni_madre
stampa_tabella(
summary(dati_neonati$Anni.madre),
caption = "Statistiche descrittive per gli Anni.madre"
)
| Var1 | Var2 | Freq |
|---|---|---|
| A | Min. | 13.000 |
| A | 1st Qu. | 25.000 |
| A | Median | 28.000 |
| A | Mean | 28.186 |
| A | 3rd Qu. | 32.000 |
| A | Max. | 46.000 |
dati_neonati <- crea_categoria(
dati_neonati,
"Anni.madre",
c(-Inf, 19, 24, 29, 34, Inf),
c(
"Adolescente",
"Giovane adulta (20-24)",
"Giovane adulta (25-29)",
"Giovane adulta (30-34)",
"Età materna avanzata"
),
"Categorie_Anni_Madre"
)
stampa_tabella(
tabella_frequenze(dati_neonati, "Categorie_Anni_Madre"),
"Frequenze assolute e relative delle categorie anni madre"
)
| Categorie_Anni_Madre | n | Percentuale |
|---|---|---|
| Adolescente | 109 | 4.36% |
| Giovane adulta (20-24) | 486 | 19.44% |
| Giovane adulta (25-29) | 909 | 36.36% |
| Giovane adulta (30-34) | 712 | 28.48% |
| Età materna avanzata | 284 | 11.36% |
ggplot(dati_neonati, aes(x = Anni.madre)) +
geom_histogram(binwidth = 2,
fill = "steelblue",
color = "black") +
labs(
title = "Distribuzione dell'età della madre",
x = "Età della madre (anni)",
y = "Frequenza"
) +
theme_minimal()
# Relazione anni.madre-peso
levels(dati_neonati$Categorie_Anni_Madre) <- c(
"1 - Adolescente (<20 anni)",
"2 - Giovane adulta (20-24 anni)",
"3 - Giovane adulta (25-29 anni)",
"4 - Giovane adulta (30-34 anni)",
"5 - Età materna avanzata (>=35 anni)"
)
dati_neonati$Codice_anni_madre <- as.numeric(
dati_neonati$Categorie_Anni_Madre
)
ggplot(
dati_neonati,
aes(
x = Codice_anni_madre,
y = Peso,
fill = Categorie_Anni_Madre
)
) +
geom_boxplot() +
scale_x_continuous(
breaks = 1:5,
labels = 1:5
) +
labs(
title = "Distribuzione del peso per categoria di età materna",
x = "Categoria età madre (codice)",
y = "Peso alla nascita (grammi)",
fill = "Categoria età madre"
) +
theme_minimal()
Anni.madre:
NA sono stati sostituiti con la
stessa mediana.dati_neonati <- crea_categoria(
dati_neonati,
"N.gravidanze",
c(-Inf, 0, 1, 2, Inf),
c(
"0 gravidanze precedenti",
"1 gravidanza precedente",
"2 gravidanze precedenti",
"3 gravidanze o più"
),
"Categorie_gravidanze"
)
stampa_tabella(
tabella_frequenze(dati_neonati, "Categorie_gravidanze"),
"Frequenze assolute e relative delle categorie gravidanze"
)
| Categorie_gravidanze | n | Percentuale |
|---|---|---|
| 0 gravidanze precedenti | 1096 | 43.84% |
| 1 gravidanza precedente | 818 | 32.72% |
| 2 gravidanze precedenti | 340 | 13.6% |
| 3 gravidanze o più | 246 | 9.84% |
ggplot(dati_neonati, aes(x = N.gravidanze)) +
geom_bar(fill = "steelblue")
N.gravidanze:
dati_neonati <- crea_categoria(
dati_neonati,
"Peso",
c(-Inf, 1000, 1500, 2500, 4500, Inf),
c(
"Estremamente Basso (<1000 g)",
"Molto Basso (1000-1499 g)",
"Basso (1500-2499 g)",
"Normopeso (2500-4499 g)",
"Macrosomia fetale (>=4500 g)"
),
"Categoria_peso"
)
stampa_tabella(
tabella_frequenze(dati_neonati, "Categoria_peso"),
"Frequenze assolute e relative delle categorie peso"
)
| Categoria_peso | n | Percentuale |
|---|---|---|
| Estremamente Basso (<1000 g) | 6 | 0.24% |
| Molto Basso (1000-1499 g) | 18 | 0.72% |
| Basso (1500-2499 g) | 123 | 4.92% |
| Normopeso (2500-4499 g) | 2335 | 93.4% |
| Macrosomia fetale (>=4500 g) | 18 | 0.72% |
ggplot(dati_neonati, aes(x = Peso)) +
geom_histogram(
binwidth = 200,
fill = "steelblue",
color = "black"
) +
labs(
title = "Distribuzione del peso alla nascita",
x = "Peso (grammi)",
y = "Frequenza"
) +
theme_minimal()
Peso:
dati_neonati <- crea_categoria(
dati_neonati,
"Gestazione",
c(-Inf, 28, 32, 39, 41, 42, Inf),
c(
"Estremamente pretermine (<28 settimane)",
"Molto pretermine (28-31 settimane)",
"Pretermine moderato (32-38 settimane)",
"Pieno termine (39-40 settimane)",
"Termine tardivo (41 settimane)",
"Post-termine (>=42 settimane)"
),
"Categoria_gestazione"
)
stampa_tabella(
tabella_frequenze(dati_neonati, "Categoria_gestazione"),
"Frequenze assolute e relative delle categorie gestazione"
)
| Categoria_gestazione | n | Percentuale |
|---|---|---|
| Estremamente pretermine (<28 settimane) | 8 | 0.32% |
| Molto pretermine (28-31 settimane) | 25 | 1% |
| Pretermine moderato (32-38 settimane) | 1339 | 53.56% |
| Pieno termine (39-40 settimane) | 1070 | 42.8% |
| Termine tardivo (41 settimane) | 56 | 2.24% |
| Post-termine (>=42 settimane) | 2 | 0.08% |
ggplot(dati_neonati, aes(x = Gestazione)) +
geom_bar(
fill = "darkgreen",
color = "black"
) +
labs(
title = "Distribuzione delle settimane di gestazione",
x = "Settimane di gestazione",
y = "Frequenza"
) +
theme_minimal()
#relazione gestazione-peso
ggplot(dati_neonati, aes(x = Gestazione, y = Peso)) +
geom_point() +
geom_smooth(method = "lm") +
labs(
title = "Relazione tra settimane di gestazione e peso alla nascita",
x = "Settimane di gestazione",
y = "Peso (grammi)"
) +
theme_minimal()
#gestazione-peso distribuzione
levels(dati_neonati$Categoria_gestazione) <- c(
"1 - Estremamente pretermine (<28 settimane)",
"2 - Molto pretermine (28-31 settimane)",
"3 - Pretermine moderato(32-38 settimane)",
"4 - Pieno-termine(39-40 settimane)",
"5 - Termine-tardivo(41 settimane)",
"6 - Post-termine(>=42 settimane)"
)
dati_neonati$Codice_gestazione <- as.numeric(dati_neonati$Categoria_gestazione)
ggplot(
dati_neonati,
aes(
x = Codice_gestazione,
y = Peso,
fill = Categoria_gestazione
)
) +
geom_boxplot() +
scale_x_continuous(
breaks = 1:6,
labels = 1:6
) +
labs(
title = "Distribuzione del peso per categoria di gestazione",
x = "Categoria gestazionale (codice)",
y = "Peso (grammi)",
fill = "Categoria"
) +
theme_minimal()
Gestazione:
Gestazione - Peso:
p10_lunghezza <- quantile(dati_neonati$Lunghezza, 0.10, na.rm = TRUE)
p90_lunghezza <- quantile(dati_neonati$Lunghezza, 0.90, na.rm = TRUE)
lunghezza_breaks <- c(-Inf, p10_lunghezza, p90_lunghezza, Inf)
lunghezza_labels <- c(
"Lunghezza bassa (≤ P10)",
"Lunghezza nella norma (P10-P90)",
"Lunghezza elevata (> P90)"
)
dati_neonati <- crea_categoria(
dati_neonati,
"Lunghezza",
lunghezza_breaks,
lunghezza_labels,
"Categoria_lunghezza"
)
tabella_percentili <- data.frame(
Statistica = c("P10 Lunghezza [mm]", "P90 Lunghezza [mm]"),
Valore = c(p10_lunghezza, p90_lunghezza)
)
stampa_tabella(
tabella_percentili,
caption = "Percentili della lunghezza"
)
| Statistica | Valore | |
|---|---|---|
| 10% | P10 Lunghezza [mm] | 465 |
| 90% | P90 Lunghezza [mm] | 520 |
stampa_tabella(
tabella_frequenze(dati_neonati, "Categoria_lunghezza"),
"Frequenze assolute e relative delle categorie lunghezza"
)
| Categoria_lunghezza | n | Percentuale |
|---|---|---|
| Lunghezza bassa (≤ P10) | 265 | 10.6% |
| Lunghezza nella norma (P10-P90) | 1991 | 79.64% |
| Lunghezza elevata (> P90) | 244 | 9.76% |
p10_cranio <- quantile(dati_neonati$Cranio, 0.10, na.rm = TRUE)
p90_cranio <- quantile(dati_neonati$Cranio, 0.90, na.rm = TRUE)
cranio_breaks <- c(-Inf, p10_cranio, p90_cranio, Inf)
cranio_labels <- c(
"Circonferenza cranica bassa (≤ P10)",
"Circonferenza cranica nella norma (P10-P90)",
"Circonferenza cranica elevata (> P90)"
)
dati_neonati <- crea_categoria(
dati_neonati,
"Cranio",
cranio_breaks,
cranio_labels,
"Categoria_cranio"
)
tabella_percentili <- data.frame(
Statistica = c("P10 Cranio [mm]", "P90 Cranio [mm]"),
Valore = c(p10_cranio, p90_cranio)
)
stampa_tabella(
tabella_percentili,
caption = "Percentili della lunghezza"
)
| Statistica | Valore | |
|---|---|---|
| 10% | P10 Cranio [mm] | 320 |
| 90% | P90 Cranio [mm] | 360 |
stampa_tabella(
tabella_frequenze(dati_neonati, "Categoria_cranio"),
"Frequenze assolute e relative delle categorie cranio"
)
| Categoria_cranio | n | Percentuale |
|---|---|---|
| Circonferenza cranica bassa (≤ P10) | 252 | 10.08% |
| Circonferenza cranica nella norma (P10-P90) | 2063 | 82.52% |
| Circonferenza cranica elevata (> P90) | 185 | 7.4% |
Lunghezza e Cranio:
stampa_tabella(
controlla_categorie(
dati_neonati,
"Fumatrici",
c(0, 1)
),
caption = "Controllo della variabile Fumatrici"
)
| Variabile | Valori osservati | Valori mancanti | Valori non validi |
|---|---|---|---|
| Fumatrici | 0, 1 | 0 | Nessuno |
dati_neonati$Fumatrici <- factor(
dati_neonati$Fumatrici,
levels = c(0, 1),
labels = c("Non fumatrice", "Fumatrice")
)
stampa_tabella(
tabella_frequenze(dati_neonati, "Fumatrici"),
"Frequenze assolute e relative delle donne Fumatrici/Non Fumatrici"
)
| Fumatrici | n | Percentuale |
|---|---|---|
| Non fumatrice | 2396 | 95.84% |
| Fumatrice | 104 | 4.16% |
#fumatrici
ggplot(dati_neonati, aes(x = Fumatrici, fill = Fumatrici)) +
geom_bar() +
labs(
title = "Distribuzione delle madri fumatrici",
x = "",
y = "Frequenza"
) +
theme_minimal()
# Fumatrici - peso
ggplot(dati_neonati,
aes(Fumatrici, Peso, fill = Fumatrici)) +
geom_boxplot()
Fumatrici:
stampa_tabella(
controlla_categorie(
dati_neonati,
"Tipo.parto",
c("Nat", "Ces")
),
caption = "Controllo della variabile Tipo.parto"
)
| Variabile | Valori osservati | Valori mancanti | Valori non validi |
|---|---|---|---|
| Tipo.parto | Ces, Nat | 0 | Nessuno |
dati_neonati$Tipo.parto <- factor(
dati_neonati$Tipo.parto,
levels = c("Nat", "Ces"),
labels = c("Parto naturale", "Taglio cesareo")
)
stampa_tabella(
tabella_frequenze(dati_neonati, "Tipo.parto"),
"Frequenze assolute e relative del tipo parto"
)
| Tipo.parto | n | Percentuale |
|---|---|---|
| Parto naturale | 1772 | 70.88% |
| Taglio cesareo | 728 | 29.12% |
# Tipo parto-Peso
ggplot(dati_neonati,
aes(Tipo.parto, Peso, fill = Tipo.parto)) +
geom_boxplot()
Tipo.parto:
stampa_tabella(
controlla_categorie(
dati_neonati,
"Ospedale",
c("osp1", "osp2", "osp3")
),
caption = "Controllo della variabile Ospedale"
)
| Variabile | Valori osservati | Valori mancanti | Valori non validi |
|---|---|---|---|
| Ospedale | osp1, osp2, osp3 | 0 | Nessuno |
dati_neonati$Ospedale <- factor(
dati_neonati$Ospedale,
levels = c("osp1", "osp2", "osp3"),
labels = c(
"Ospedale 1",
"Ospedale 2",
"Ospedale 3"
)
)
stampa_tabella(
tabella_frequenze(dati_neonati, "Ospedale"),
"Frequenze assolute e relative del tipo parto"
)
| Ospedale | n | Percentuale |
|---|---|---|
| Ospedale 1 | 816 | 32.64% |
| Ospedale 2 | 849 | 33.96% |
| Ospedale 3 | 835 | 33.4% |
#Ospedale-Peso
ggplot(dati_neonati,
aes(Ospedale, Peso, fill = Ospedale)) +
geom_boxplot()
Ospedale:
stampa_tabella(
controlla_categorie(
dati_neonati,
"Sesso",
c("M", "F")
),
caption = "Controllo della variabile Sesso"
)
| Variabile | Valori osservati | Valori mancanti | Valori non validi |
|---|---|---|---|
| Sesso | F, M | 0 | Nessuno |
dati_neonati$Sesso <- factor(
dati_neonati$Sesso,
levels = c("M", "F"),
labels = c("Maschio", "Femmina")
)
stampa_tabella(
tabella_frequenze(dati_neonati, "Sesso"),
"Frequenze assolute e relative del Sesso"
)
| Sesso | n | Percentuale |
|---|---|---|
| Maschio | 1244 | 49.76% |
| Femmina | 1256 | 50.24% |
# Sesso-Peso
ggplot(dati_neonati,
aes(Sesso, Peso, fill = Sesso)) +
geom_boxplot()
Sesso:
Dopo l’EDA verranno effettuati opportuni test statistici per verificare se le relazioni osservate durante l’analisi esplorativa risultano statisticamente significative e per individuare le variabili maggiormente associate al peso del neonato. In particolare saranno analizzate le seguenti ipotesi:
Infine, le variabili che risulteranno statisticamente significative saranno considerate come possibili predittori nella costruzione del modello di regressione per la previsione del peso del neonato.
N.B. È opportuno considerare che i test parametrici risultano generalmente robusti a moderate violazioni dell’ipotesi di normalità grazie al Teorema del Limite Centrale.
N.B. Per tutti i test t vale:
Equivalentemente:
Pertanto, nei test viene confrontata la differenza tra la media osservata e quella ipotizzata.
\[ F=\frac{\text{variabilità tra i gruppi}}{\text{variabilità all'interno dei gruppi}} \]
Fonti
Variabili
Entrambe le variabili sono qualitative; pertanto il test corretto è il test χ² di indipendenza.
Ipotesi
tabella <- table(
dati_neonati$Ospedale,
dati_neonati$Tipo.parto
)
stampa_tabella(
cbind(
Ospedale = rownames(tabella),
as.data.frame.matrix(tabella)
),
caption = "Tabella di contingenza tra ospedale e tipo di parto"
)
| Ospedale | Parto naturale | Taglio cesareo | |
|---|---|---|---|
| Ospedale 1 | Ospedale 1 | 574 | 242 |
| Ospedale 2 | Ospedale 2 | 595 | 254 |
| Ospedale 3 | Ospedale 3 | 603 | 232 |
stampa_tabella(
cbind(
Ospedale = rownames(tabella),
as.data.frame.matrix(round(prop.table(tabella, margin = 1) * 100, 2))
),
caption = "Distribuzione percentuale del tipo di parto per ospedale"
)
| Ospedale | Parto naturale | Taglio cesareo | |
|---|---|---|---|
| Ospedale 1 | Ospedale 1 | 70.34 | 29.66 |
| Ospedale 2 | Ospedale 2 | 70.08 | 29.92 |
| Ospedale 3 | Ospedale 3 | 72.22 | 27.78 |
test <- chisq.test(tabella)
stampa_tabella(
cbind(
Ospedale = rownames(test$expected),
as.data.frame.matrix(round(test$expected, 2))
),
caption = "Frequenze attese del test χ²"
)
| Ospedale | Parto naturale | Taglio cesareo | |
|---|---|---|---|
| Ospedale 1 | Ospedale 1 | 578.38 | 237.62 |
| Ospedale 2 | Ospedale 2 | 601.77 | 247.23 |
| Ospedale 3 | Ospedale 3 | 591.85 | 243.15 |
stampa_tabella(
data.frame(
`Statistica χ²` = round(unname(test$statistic), 2),
`Gradi di libertà` = unname(test$parameter),
`p-value` = signif(test$p.value, 4)
),
caption = "Risultato del test χ²"
)
| Statistica.χ. | Gradi.di.libertà | p.value |
|---|---|---|
| 1.1 | 2 | 0.5778 |
Esito del test
Poiché il p-value (0.5778) è maggiore del livello di significatività (\(\alpha=0.05\)), non si rifiuta l’ipotesi nulla di indipendenza. Pertanto, nel campione analizzato, non vi sono evidenze statisticamente significative di un’associazione tra l’ospedale e il tipo di parto. In particolare, le differenze osservate nelle percentuali di parti cesarei tra i tre ospedali non risultano statisticamente significative e possono essere attribuite alla variabilità casuale del campione.
Variabili
È opportuno utilizzare un One Sample t-test.
Ipotesi
Peso:
Lunghezza:
Si considerano un peso medio pari a 3300 g e una lunghezza media pari a 500 mm, come valori di riferimento per la popolazione.
Fonte
https://www.ospedalebambinogesu.it/da-0-a-30-giorni-come-si-presenta-e-come-cresce-80012/
test_media(
dati_neonati$Peso,
"Peso",
mu = 3300
)
| Variabile | Media campionaria | Media ipotizzata | Statistica t | Gradi liberta | p-value | IC 95% inferiore | IC 95% superiore |
|---|---|---|---|---|---|---|---|
| Peso | 3284.08 | 3300 | -1.52 | 2499 | 0.13 | 3263.49 | 3304.67 |
test_media(
dati_neonati$Lunghezza,
"Lunghezza",
mu = 500
)
| Variabile | Media campionaria | Media ipotizzata | Statistica t | Gradi liberta | p-value | IC 95% inferiore | IC 95% superiore |
|---|---|---|---|---|---|---|---|
| Lunghezza | 494.69 | 500 | -10.08 | 2499 | <2e-16 | 493.66 | 495.72 |
Esito del test
Il One Sample t-test, considerando il peso, non ha evidenziato differenze statisticamente significative tra la media del campione (3284 g) e quella ipotizzata per la popolazione (3300 g) (\(t=-1.52\); \(p=0.130\)). Pertanto non si rifiuta l’ipotesi nulla.
Per quanto riguarda la lunghezza, la media campionaria risulta significativamente diversa da quella ipotizzata. Ciò è confermato anche dall’intervallo di confidenza, che non contiene il valore di riferimento pari a 500 mm. Tale conclusione è supportata dal p-value, ampiamente inferiore al livello di significatività.
Variabili
È opportuno utilizzare un t-test per campioni indipendenti (Welch).
Ipotesi
test_confronto_gruppi(
Peso ~ Sesso,
dati_neonati,
"Peso"
)
| Variabile | Gruppi | Media gruppo 1 | Media gruppo 2 | Differenza medie | Statistica t | Gradi liberta | p-value | IC 95% inferiore | IC 95% superiore |
|---|---|---|---|---|---|---|---|---|---|
| Peso | Maschio vs Femmina | 3408.22 | 3161.13 | -247.08 | 12.11 | 2490.72 | <2e-16 | 207.06 | 287.11 |
test_confronto_gruppi(
Lunghezza ~ Sesso,
dati_neonati,
"Lunghezza"
)
| Variabile | Gruppi | Media gruppo 1 | Media gruppo 2 | Differenza medie | Statistica t | Gradi liberta | p-value | IC 95% inferiore | IC 95% superiore |
|---|---|---|---|---|---|---|---|---|---|
| Lunghezza | Maschio vs Femmina | 499.67 | 489.76 | -9.9 | 9.58 | 2459.3 | <2e-16 | 7.88 | 11.93 |
test_confronto_gruppi(
Cranio ~ Sesso,
dati_neonati,
"Cranio"
)
| Variabile | Gruppi | Media gruppo 1 | Media gruppo 2 | Differenza medie | Statistica t | Gradi liberta | p-value | IC 95% inferiore | IC 95% superiore |
|---|---|---|---|---|---|---|---|---|---|
| Cranio | Maschio vs Femmina | 342.45 | 337.63 | -4.82 | 7.41 | 2491.39 | 1.7e-13 | 3.54 | 6.09 |
Esito del test
Peso
Il test t di Welch evidenzia una differenza statisticamente significativa tra il peso medio dei neonati maschi e quello delle femmine (\(t=12.11\); \(p<0.001\)). Si rifiuta quindi l’ipotesi nulla. In media, i neonati maschi pesano circa 247 g in più delle femmine (3408 g contro 3161 g). L’intervallo di confidenza al 95% della differenza è compreso tra 207 g e 287 g.
Lunghezza
Anche la lunghezza media differisce significativamente tra i due sessi (\(t=9.58\); \(p<0.001\)). Si rifiuta l’ipotesi nulla. I neonati maschi risultano mediamente più lunghi di circa 10 mm rispetto alle femmine.
Cranio
Il diametro medio del cranio è significativamente maggiore nei maschi rispetto alle femmine (\(t=7.41\); \(p<0.001\)). Anche in questo caso si rifiuta l’ipotesi nulla.
Conclusione
Le misure antropometriche considerate (peso, lunghezza e circonferenza cranica) risultano significativamente maggiori nei neonati di sesso maschile rispetto a quelli di sesso femminile.
Variabili
È opportuno utilizzare un t-test per campioni indipendenti.
Ipotesi
test_confronto_gruppi(
Peso ~ Fumatrici,
dati_neonati,
"Fumatrici"
)
| Variabile | Gruppi | Media gruppo 1 | Media gruppo 2 | Differenza medie | Statistica t | Gradi liberta | p-value | IC 95% inferiore | IC 95% superiore |
|---|---|---|---|---|---|---|---|---|---|
| Fumatrici | Non fumatrice vs Fumatrice | 3286.15 | 3236.35 | -49.81 | 1.03 | 114.1 | 0.3 | -45.61 | 145.23 |
Esito del test
Il test t di Welch non evidenzia una differenza statisticamente significativa tra il peso medio dei neonati di madri fumatrici e quello dei neonati di madri non fumatrici (\(t=1.03\); \(p=0.303\)). Pertanto non si rifiuta l’ipotesi nulla. Sebbene il peso medio dei figli di madri non fumatrici sia leggermente superiore (3286 g contro 3236 g), tale differenza non risulta statisticamente significativa.
Variabili
È opportuno utilizzare un t-test per campioni indipendenti.
Ipotesi
test_confronto_gruppi(
Peso ~ Tipo.parto,
dati_neonati,
"Tipo.parto"
)
| Variabile | Gruppi | Media gruppo 1 | Media gruppo 2 | Differenza medie | Statistica t | Gradi liberta | p-value | IC 95% inferiore | IC 95% superiore |
|---|---|---|---|---|---|---|---|---|---|
| Tipo.parto | Parto naturale vs Taglio cesareo | 3284.92 | 3282.05 | -2.87 | 0.13 | 1492.96 | 0.9 | -40.54 | 46.28 |
Esito del test
Il test t di Welch non evidenzia differenze statisticamente significative tra il peso medio dei neonati nati mediante parto naturale e quello dei neonati nati mediante taglio cesareo (\(t=0.13\); \(p=0.897\)). Pertanto non si rifiuta l’ipotesi nulla e non vi sono evidenze che il tipo di parto influenzi il peso alla nascita.
Variabili
È opportuno utilizzare un One-Way ANOVA.
Ipotesi
test_anova(
Peso ~ Categorie_Anni_Madre,
dati_neonati,
"Peso rispetto alle categorie di età materna"
)
| Fonte | Gradi liberta | Somma quadrati | Media quadratica | Statistica F | p-value |
|---|---|---|---|---|---|
| Categorie_Anni_Madre | 4 | 1877665 | 469416.2 | 1.7 | 0.1461 |
| Residuals | 2495 | 687010877 | 275355.1 | NA | NA |
Esito del test
L’ANOVA non evidenzia differenze statisticamente significative del peso medio tra le diverse classi di età materna (\(F=1.705\); \(p=0.146\)). Pertanto non si rifiuta l’ipotesi nulla e non vi sono evidenze che il peso medio del neonato vari significativamente in funzione della fascia di età della madre. Ciò è coerente con il fatto che la variabilità all’interno dei gruppi risulta maggiore della variabilità tra i gruppi e con il p-value superiore al livello di significatività.
Variabili
È opportuno utilizzare un One-Way ANOVA.
Ipotesi
test_anova(
Peso ~ Ospedale,
dati_neonati,
"Peso rispetto agli Ospedali di nascita"
)
| Fonte | Gradi liberta | Somma quadrati | Media quadratica | Statistica F | p-value |
|---|---|---|---|---|---|
| Ospedale | 2 | 936236.8 | 468118.4 | 1.7 | 0.1831 |
| Residuals | 2497 | 687952304.9 | 275511.5 | NA | NA |
Esito del test
L’ANOVA è stata applicata per confrontare il peso medio dei neonati nei tre ospedali. Il test non è risultato statisticamente significativo (\(F=1.699\); \(p=0.183\)). Pertanto non si rifiuta l’ipotesi nulla e non emergono differenze significative tra gli ospedali.
Variabili
È opportuno utilizzare il test di correlazione di Pearson, che restituisce un coefficiente compreso tra:
Ipotesi
test_correlazione(
dati_neonati$Peso,
dati_neonati$Gestazione,
"Peso",
"Gestazione"
)
| Variabile_1 | Variabile_2 | Coefficiente Pearson (r) | Statistica t | Gradi liberta | p-value | IC 95% inferiore | IC 95% superiore |
|---|---|---|---|---|---|---|---|
| Peso | Gestazione | 0.59 | 36.69 | 2498 | <2e-16 | 0.57 | 0.62 |
Esito del test
Il test di correlazione di Pearson evidenzia una correlazione positiva moderata e statisticamente significativa tra la durata della gestazione e il peso alla nascita (\(r=0.592\); \(p<0.001\)). Pertanto si rifiuta l’ipotesi nulla di assenza di correlazione. All’aumentare delle settimane di gestazione tende ad aumentare anche il peso del neonato.
Nel complesso, i test statistici univariati evidenziano che le variabili Gestazione e Sesso sono quelle maggiormente associate al peso alla nascita, mostrando un’associazione statisticamente significativa con la variabile risposta.
Al contrario, le variabili Anni della madre, Fumatrici, Tipo di parto e Ospedale non risultano statisticamente significative nelle analisi univariate. Tuttavia, tale risultato non implica necessariamente che queste variabili debbano essere escluse dal modello di regressione multipla. Infatti, una variabile può non mostrare un effetto significativo se considerata singolarmente, ma contribuire in modo rilevante quando viene analizzata congiuntamente alle altre variabili esplicative, oppure migliorare la capacità predittiva complessiva del modello.
Per questo motivo, la selezione finale delle variabili è stata effettuata mediante regressione lineare multipla.
Dopo aver ottenuto il modello finale mediante selezione automatica delle variabili, la sua capacità predittiva è stata valutata attraverso il coefficiente di determinazione R^2, il coefficiente di determinazione aggiustato e il Root Mean Squared Error (RMSE), che misura l’errore medio di previsione espresso in grammi. Successivamente sono state verificate le principali ipotesi della regressione lineare mediante l’analisi grafica dei residui (residui vs valori predetti, Q-Q Plot e Scale-Location Plot). Infine, sono stati individuati eventuali valori influenti tramite la distanza di Cook, il leverage e i residui standardizzati, valutando se alcune osservazioni potessero esercitare un’influenza eccessiva sulla stima dei coefficienti del modello. Inoltre, la presenza di multicollinearità tra le variabili esplicative è stata verificata mediante il Variance Inflation Factor (VIF).
Fonti:
È stato inizialmente costruito un modello di regressione lineare
multipla (modello_baseline) considerando tutte le variabili
disponibili per spiegare il peso neonatale:
\[ Peso \sim Anni.madre + N.gravidanze + Fumatrici + Gestazione + Lunghezza + Cranio + Tipo.parto + Ospedale + Sesso \]
Il modello completo ha ottenuto:
Il coefficiente di determinazione indica che circa il 72.9% della variabilità del peso alla nascita è spiegata dalle variabili considerate, mentre il restante 27% è attribuibile ad altri fattori non presenti nel dataset o alla variabilità naturale del fenomeno biologico.
L’errore medio di previsione, espresso tramite RMSE, è pari a circa 273 grammi, valore contenuto considerando la variabilità fisiologica del peso neonatale.
| Variabile | Estimate | Std. Error | t value | Pr(>|t|) |
|---|---|---|---|---|
| (Intercept) | -6628.12 | 142.92 | -46.38 | 0.00 |
| Anni.madre | 0.80 | 1.15 | 0.70 | 0.49 |
| N.gravidanze | 11.41 | 4.67 | 2.45 | 0.01 |
| FumatriciFumatrice | -30.16 | 27.54 | -1.10 | 0.27 |
| Gestazione | 32.53 | 3.82 | 8.52 | 0.00 |
| Lunghezza | 10.30 | 0.30 | 34.24 | 0.00 |
| Cranio | 10.47 | 0.43 | 24.58 | 0.00 |
| Tipo.partoTaglio cesareo | -29.50 | 12.08 | -2.44 | 0.01 |
| OspedaleOspedale 2 | -11.22 | 13.44 | -0.84 | 0.40 |
| OspedaleOspedale 3 | 28.10 | 13.50 | 2.08 | 0.04 |
| SessoFemmina | -77.55 | 11.18 | -6.94 | 0.00 |
| Statistica | Valore |
|---|---|
| R quadro | 0.73 |
| R quadro corretto | 0.73 |
| F statistic | 669.14 |
| p-value globale | < 2.2e-16 |
Dall’analisi dei coefficienti del modello completo emergono alcune variabili con un effetto statisticamente significativo sul peso.
Le variabili che mostrano un’associazione positiva con il peso sono:
Gestazione: ogni settimana aggiuntiva di gestazione determina un incremento medio stimato del peso di circa 32 g, mantenendo costanti le altre variabili.
Lunghezza: rappresenta uno dei principali predittori del peso; un aumento della lunghezza neonatale è associato ad un incremento del peso stimato.
Cranio: anche la circonferenza cranica mostra un effetto positivo significativo, indicando una relazione tra sviluppo corporeo e peso alla nascita.
Numero di gravidanze precedenti: presenta un effetto positivo ma più contenuto.
Per quanto riguarda le variabili categoriche:
Il parto cesareo presenta un coefficiente negativo rispetto al parto naturale, con una riduzione stimata del peso di circa 29 g.
Il sesso femminile mostra un coefficiente negativo significativo, con un peso medio stimato inferiore di circa 77 g rispetto al sesso maschile.
La variabile Ospedale mostra differenze significative solamente per l’Ospedale 3, mentre l’Ospedale 2 non risulta statisticamente diverso rispetto alla categoria di riferimento.
Al contrario, l’età della madre e il fumo durante la gravidanza non risultano statisticamente significativi nel modello completo.
E’ stata applicata una procedura di selezione automatica basata
sull’AIC (stepAIC), ottenendo un modello più
parsimonioso:
[ Peso N.gravidanze + Gestazione + Lunghezza + Cranio + Tipo.parto + Ospedale + Sesso]
Sono state quindi eliminate:
poiché il loro contributo non risultava sufficiente a migliorare il compromesso tra complessità e capacità esplicativa del modello.
Il modello finale mantiene praticamente le stesse prestazioni:
| Modello | R² | R² corretto |
|---|---|---|
| Completo | 0.7289 | 0.7278 |
| AIC | 0.7287 | 0.7278 |
La perdita di capacità predittiva è trascurabile, mentre il modello risulta più semplice e maggiormente interpretabile.
| Peso | N.gravidanze | Gestazione | Lunghezza | Cranio | |
|---|---|---|---|---|---|
| Peso | 1.00 | 0.00 | 0.59 | 0.80 | 0.70 |
| N.gravidanze | 0.00 | 1.00 | -0.10 | -0.06 | 0.04 |
| Gestazione | 0.59 | -0.10 | 1.00 | 0.62 | 0.46 |
| Lunghezza | 0.80 | -0.06 | 0.62 | 1.00 | 0.60 |
| Cranio | 0.70 | 0.04 | 0.46 | 0.60 | 1.00 |
| Variabile | Estimate | Std. Error | t value | Pr(>|t|) |
|---|---|---|---|---|
| (Intercept) | -6600.71 | 137.49 | -48.01 | 0.00 |
| N.gravidanze | 12.36 | 4.33 | 2.85 | 0.00 |
| Gestazione | 31.99 | 3.79 | 8.44 | 0.00 |
| Lunghezza | 10.31 | 0.30 | 34.32 | 0.00 |
| Cranio | 10.49 | 0.43 | 24.66 | 0.00 |
| Tipo.partoTaglio cesareo | -29.28 | 12.08 | -2.42 | 0.02 |
| OspedaleOspedale 2 | -11.02 | 13.44 | -0.82 | 0.41 |
| OspedaleOspedale 3 | 28.64 | 13.49 | 2.12 | 0.03 |
| SessoFemmina | -77.44 | 11.18 | -6.93 | 0.00 |
| Statistica | Valore |
|---|---|
| R quadro | 0.73 |
| R quadro corretto | 0.73 |
| AIC | 35169.79 |
| RMSE | 273.42 |
La maggior parte dei residui è distribuita attorno allo zero senza una struttura evidente. La linea di smoothing rimane vicina alla linea orizzontale, suggerendo una relazione prevalentemente lineare tra variabili esplicative e peso.
Sono tuttavia presenti alcuni valori estremi, in particolare l’osservazione 1551, caratterizzata da un residuo molto elevato.
Il grafico Q-Q mostra una buona aderenza dei residui alla distribuzione normale nella parte centrale.
Si osservano però deviazioni nelle code, soprattutto nella parte superiore, dovute alla presenza di alcuni neonati con peso molto superiore rispetto alla previsione del modello.
Questi punti rappresentano possibili outlier biologici e non necessariamente errori nei dati.
Il grafico dei residui standardizzati rispetto all’indice mostra una distribuzione casuale dei residui attorno allo zero, senza evidenti pattern sistematici. La quasi totalità delle osservazioni rientra nell’intervallo ±3, sebbene siano presenti pochi outlier con residui standardizzati elevati. Dunque, non emerge una marcata eteroschedasticità, anche se per valori estremi del peso si osserva una maggiore variabilità.
Ho applicato la radice quadrata ai residui perchè questa trasformazione rende più facile valutare la variabilità dei residui. Il grafico Scale-Location evidenzia una dispersione dei residui sostanzialmente costante lungo l’intervallo dei valori predetti. La linea di smoothing risulta pressoché orizzontale, suggerendo che l’ipotesi di omoschedasticità sia ragionevolmente soddisfatta, pur in presenza di una lieve crescita della variabilità per valori predetti più elevati e di alcune osservazioni anomale
| Indice osservazione | |
|---|---|
| 13 | 13 |
| 34 | 34 |
| 119 | 119 |
| 130 | 130 |
| 134 | 134 |
| 140 | 140 |
| 146 | 146 |
| 155 | 155 |
| 161 | 161 |
| 220 | 220 |
| 274 | 274 |
| 295 | 295 |
| 310 | 310 |
| 329 | 329 |
| 375 | 375 |
| 377 | 377 |
| 390 | 390 |
| 455 | 455 |
| 472 | 472 |
| 478 | 478 |
| 516 | 516 |
| 582 | 582 |
| 615 | 615 |
| 616 | 616 |
| 632 | 632 |
| 633 | 633 |
| 648 | 648 |
| 656 | 656 |
| 657 | 657 |
| 684 | 684 |
| 791 | 791 |
| 805 | 805 |
| 828 | 828 |
| 890 | 890 |
| 908 | 908 |
| 928 | 928 |
| 950 | 950 |
| 1008 | 1008 |
| 1014 | 1014 |
| 1036 | 1036 |
| 1130 | 1130 |
| 1132 | 1132 |
| 1137 | 1137 |
| 1181 | 1181 |
| 1188 | 1188 |
| 1192 | 1192 |
| 1194 | 1194 |
| 1212 | 1212 |
| 1230 | 1230 |
| 1253 | 1253 |
| 1267 | 1267 |
| 1268 | 1268 |
| 1273 | 1273 |
| 1287 | 1287 |
| 1293 | 1293 |
| 1306 | 1306 |
| 1317 | 1317 |
| 1341 | 1341 |
| 1395 | 1395 |
| 1399 | 1399 |
| 1402 | 1402 |
| 1426 | 1426 |
| 1429 | 1429 |
| 1433 | 1433 |
| 1450 | 1450 |
| 1472 | 1472 |
| 1499 | 1499 |
| 1505 | 1505 |
| 1541 | 1541 |
| 1551 | 1551 |
| 1553 | 1553 |
| 1556 | 1556 |
| 1588 | 1588 |
| 1593 | 1593 |
| 1619 | 1619 |
| 1635 | 1635 |
| 1639 | 1639 |
| 1694 | 1694 |
| 1702 | 1702 |
| 1712 | 1712 |
| 1718 | 1718 |
| 1780 | 1780 |
| 1838 | 1838 |
| 1856 | 1856 |
| 1868 | 1868 |
| 1893 | 1893 |
| 1915 | 1915 |
| 1920 | 1920 |
| 1926 | 1926 |
| 1937 | 1937 |
| 1962 | 1962 |
| 1963 | 1963 |
| 2023 | 2023 |
| 2040 | 2040 |
| 2076 | 2076 |
| 2086 | 2086 |
| 2114 | 2114 |
| 2115 | 2115 |
| 2120 | 2120 |
| 2123 | 2123 |
| 2135 | 2135 |
| 2175 | 2175 |
| 2195 | 2195 |
| 2204 | 2204 |
| 2219 | 2219 |
| 2221 | 2221 |
| 2225 | 2225 |
| 2287 | 2287 |
| 2315 | 2315 |
| 2317 | 2317 |
| 2392 | 2392 |
| 2421 | 2421 |
| 2422 | 2422 |
| 2437 | 2437 |
| 2452 | 2452 |
| 2471 | 2471 |
Il grafico evidenzia alcune osservazioni influenti:
In particolare l’osservazione 1551 presenta un’elevata distanza di Cook, indicando una possibile influenza sul modello.
Tuttavia, considerando la dimensione del campione (2500 osservazioni), tali punti non sembrano compromettere significativamente la validità complessiva del modello.
| Anni.madre | N.gravidanze | Fumatrici | Gestazione | Peso | Lunghezza | Cranio | Tipo.parto | Ospedale | Sesso | |
|---|---|---|---|---|---|---|---|---|---|---|
| 1551 | 35 | 1 | Non fumatrice | 38 | 4370 | 315 | 374 | Parto naturale | Ospedale 3 | Femmina |
| Modello | R2 | R2_corretto | AIC | RMSE |
|---|---|---|---|---|
| Modello completo | 0.73 | 0.73 | 35169.79 | 273.42 |
| Senza osservazione 1551 | 0.74 | 0.74 | 35058.25 | 268.14 |
| Coefficiente | Completo | Senza_1551 | |
|---|---|---|---|
| (Intercept) | (Intercept) | -6600.71 | -6602.01 |
| N.gravidanze | N.gravidanze | 12.36 | 13.07 |
| Gestazione | Gestazione | 31.99 | 29.29 |
| Lunghezza | Lunghezza | 10.31 | 10.95 |
| Cranio | Cranio | 10.49 | 9.88 |
| Tipo.partoTaglio cesareo | Tipo.partoTaglio cesareo | -29.28 | -29.19 |
| OspedaleOspedale 2 | OspedaleOspedale 2 | -11.02 | -11.69 |
| OspedaleOspedale 3 | OspedaleOspedale 3 | 28.64 | 25.43 |
| SessoFemmina | SessoFemmina | -77.44 | -77.61 |
L’osservazione 1551 è stata ulteriormente analizzata in quanto presenta la maggiore distanza di Cook. L’analisi delle caratteristiche del neonato non suggerisce la presenza di errori di inserimento dei dati. Inoltre, il ricalcolo del modello dopo l’esclusione dell’osservazione non produce variazioni sostanziali nei coefficienti stimati né nelle principali misure di bontà di adattamento. Pertanto, l’osservazione è stata mantenuta nell’analisi, in quanto rappresenta un caso influente ma plausibile dal punto di vista biologico.
| Variabile | GVIF | Df | GVIF^(1/(2*Df)) |
|---|---|---|---|
| N.gravidanze | 1.03 | 1 | 1.01 |
| Gestazione | 1.67 | 1 | 1.29 |
| Lunghezza | 2.08 | 1 | 1.44 |
| Cranio | 1.63 | 1 | 1.28 |
| Tipo.parto | 1.00 | 1 | 1.00 |
| Ospedale | 1.00 | 2 | 1.00 |
| Sesso | 1.04 | 1 | 1.02 |
Per verificare la presenza di ridondanza tra i predittori è stata analizzata la matrice di correlazione e successivamente calcolato il VIF.
La matrice di correlazione mostra:
Queste correlazioni sono coerenti dal punto di vista biologico, poiché neonati con maggiore sviluppo fetale tendono ad avere peso maggiore.
Le correlazioni tra variabili esplicative risultano invece moderate:
L’analisi VIF ha confermato l’assenza di multicollinearità:
Pertanto non è stato necessario eliminare variabili antropometriche come Lunghezza o Cranio, poiché entrambe forniscono informazioni indipendenti utili alla previsione del peso.
Sono stati valutati alcuni modelli alternativi con l’obiettivo di migliorare le prestazioni predittive. In particolare, è stata introdotta una spline naturale per modellare un possibile effetto non lineare della durata della gestazione. Per modellare eventuali relazioni non lineari tra la durata della gestazione e il peso neonatale è stata utilizzata una natural cubic spline, implementata tramite la funzione ns() del package splines di R. Tale funzione costruisce automaticamente una base di spline cubiche naturali, ossia polinomi cubici a tratti raccordati nei nodi con continuità della funzione e delle sue prime due derivate, imponendo inoltre linearità oltre i nodi estremi.
L’introduzione di una spline naturale non ha evidenziato un miglioramento significativo delle prestazioni del modello, suggerendo che la relazione tra durata della gestazione e peso neonatale risulta approssimativamente lineare nell’intervallo osservato.
Sono stati testati due modelli comprendenti termini di interazione tra le variabili:
Gestazione × Lunghezza, per verificare se l’effetto della lunghezza sul peso variasse in funzione della durata della gravidanza;
Gestazione × Sesso, per valutare eventuali differenze nello sviluppo fetale tra maschi e femmine.
Nessuno di questi modelli ha prodotto un miglioramento significativo delle prestazioni in termini di capacità esplicativa e accuratezza predittiva rispetto al modello lineare. Per tale motivo si è preferito adottare un modello di regressione lineare più semplice e interpretabile, successivamente ottimizzato mediante il criterio AIC, che ha consentito di eliminare le variabili meno significative mantenendo pressoché inalterate le prestazioni del modello.
| Modello | R2 | R2_corretto | AIC | RMSE |
|---|---|---|---|---|
| Baseline | 0.73 | 0.73 | 35172.09 | 273.33 |
| Spline | 0.73 | 0.73 | 35164.97 | 272.72 |
| Interazione Gestazione:Lunghezza | 0.73 | 0.73 | 35148.38 | 271.93 |
| Interazione Gestazione:Sesso | 0.73 | 0.73 | 35172.44 | 273.24 |
Nessuno di questi modelli ha prodotto un miglioramento significativo delle prestazioni in termini di capacità esplicativa e accuratezza predittiva rispetto al modello lineare. Per tale motivo si è preferito adottare un modello di regressione lineare più semplice e interpretabile, successivamente ottimizzato mediante il criterio AIC, che ha consentito di eliminare le variabili meno significative mantenendo pressoché inalterate le prestazioni del modello.
| Anni.madre | N.gravidanze | Fumatrici | Gestazione | Lunghezza | Cranio | Tipo.parto | Ospedale | Sesso |
|---|---|---|---|---|---|---|---|---|
| 30 | 2 | Non fumatrice | 39 | 500 | 340 | Parto naturale | Ospedale 1 | Femmina |
## Peso previsto per il nuovo neonato: 3316 grammi
| fit | lwr | upr |
|---|---|---|
| 3315.88 | 2778.17 | 3853.6 |
Le variabili che influenzano maggiormente il peso alla nascita sono:
Sebbene il modello lineare abbia ottenuto buone prestazioni (R² ≈ 0.73 e RMSE ≈ 273 g), il restante errore di previsione suggerisce la presenza di relazioni più complesse non completamente catturate dalla regressione lineare.
Possibili miglioramenti futuri potrebbero includere:
È stata valutata la possibilità di modellare relazioni non lineari tra la variabile risposta e i predittori mediante l’impiego di spline naturali. Tuttavia, tale approccio non ha evidenziato miglioramenti significativi nelle prestazioni del modello rispetto alla regressione lineare.
Poiché le spline rappresentano una classe di modelli sufficientemente flessibile per descrivere eventuali effetti non lineari, ulteriori trasformazioni della stessa natura (ad esempio termini quadratici) difficilmente apporterebbero benefici rilevanti.
Per migliorare esclusivamente la capacità predittiva potrebbero essere confrontati modelli non lineari come:
Tuttavia, la regressione lineare rimane preferibile perchè è meglio garantire una migliore interpretazione dei risultati del modello.
Il modello finale rappresenta un buon compromesso tra interpretabilità e capacità predittiva. La selezione tramite AIC ha permesso di ottenere un modello più semplice senza perdita significativa di performance. Le variabili antropometriche del neonato e la durata della gestazione risultano i principali fattori associati al peso alla nascita. Il modello, in presenza di nuovi dati, predice con una buona accuratezza il peso di un neonato. Questo viene evidenziato dal grafico “Peso Reale dei neonati e previsione del modello”.
Eventuali miglioramenti delle prestazioni del modello saranno ricercati mediante l’impiego di modelli non lineari, in grado di catturare meglio le relazioni e le interazioni tra le variabili.