Il progetto mira a sviluppare un modello statistico per prevedere il peso dei neonati alla nascita utilizzando variabili cliniche raccolte da tre ospedali. Questo modello aiuterà Neonatal Health Solutions a migliorare le previsioni cliniche, ottimizzare le risorse ospedaliere e identificare fattori di rischio critici come il fumo materno e le nascite premature.
# Caricamento delle librerie necessarie
library(tidyverse)
library(ggplot2)
library(gghalves)
library(dplyr)
library(ineq)
library(knitr)
library(moments)
library(kableExtra)
library(car)
library(caret)
library(corrplot)
# Caricamento del dataset
data <- read.csv("C:/Users/eapol/OneDrive/Desktop/PROFESSION AI CORSO/R STATISTICA INFERENZIALE/PROGETTO/neonati.csv", stringsAsFactors = FALSE)
head(data)
## Anni.madre N.gravidanze Fumatrici Gestazione Peso Lunghezza Cranio Tipo.parto
## 1 26 0 0 42 3380 490 325 Nat
## 2 21 2 0 39 3150 490 345 Nat
## 3 34 3 0 38 3640 500 375 Nat
## 4 28 1 0 41 3690 515 365 Nat
## 5 20 0 0 38 3700 480 335 Nat
## 6 32 0 0 40 3200 495 340 Nat
## Ospedale Sesso
## 1 osp3 M
## 2 osp1 F
## 3 osp2 M
## 4 osp2 M
## 5 osp3 F
## 6 osp2 F
str(data)
## 'data.frame': 2500 obs. of 10 variables:
## $ Anni.madre : int 26 21 34 28 20 32 26 25 22 23 ...
## $ N.gravidanze: int 0 2 3 1 0 0 1 0 1 0 ...
## $ Fumatrici : int 0 0 0 0 0 0 0 0 0 0 ...
## $ Gestazione : int 42 39 38 41 38 40 39 40 40 41 ...
## $ Peso : int 3380 3150 3640 3690 3700 3200 3100 3580 3670 3700 ...
## $ Lunghezza : int 490 490 500 515 480 495 480 510 500 510 ...
## $ Cranio : int 325 345 375 365 335 340 345 349 335 362 ...
## $ Tipo.parto : chr "Nat" "Nat" "Nat" "Nat" ...
## $ Ospedale : chr "osp3" "osp1" "osp2" "osp2" ...
## $ Sesso : chr "M" "F" "M" "M" ...
summary(data)
## Anni.madre N.gravidanze Fumatrici Gestazione
## Min. : 0.00 Min. : 0.0000 Min. :0.0000 Min. :25.00
## 1st Qu.:25.00 1st Qu.: 0.0000 1st Qu.:0.0000 1st Qu.:38.00
## Median :28.00 Median : 1.0000 Median :0.0000 Median :39.00
## Mean :28.16 Mean : 0.9812 Mean :0.0416 Mean :38.98
## 3rd Qu.:32.00 3rd Qu.: 1.0000 3rd Qu.:0.0000 3rd Qu.:40.00
## Max. :46.00 Max. :12.0000 Max. :1.0000 Max. :43.00
## Peso Lunghezza Cranio Tipo.parto
## Min. : 830 Min. :310.0 Min. :235 Length:2500
## 1st Qu.:2990 1st Qu.:480.0 1st Qu.:330 Class :character
## Median :3300 Median :500.0 Median :340 Mode :character
## Mean :3284 Mean :494.7 Mean :340
## 3rd Qu.:3620 3rd Qu.:510.0 3rd Qu.:350
## Max. :4930 Max. :565.0 Max. :390
## Ospedale Sesso
## Length:2500 Length:2500
## Class :character Class :character
## Mode :character Mode :character
##
##
##
data$Tipo.parto <- as.factor(data$Tipo.parto)
data$Sesso <- as.factor(data$Sesso)
data$Ospedale <- as.factor(data$Ospedale)
Si aggiunge una variabile per idetificare i neonati prematuri (settimane di gestazione < 37)
data$Prematuro <- ifelse(data$Gestazione < 37, 1, 0)
data$Prematuro <- as.factor(data$Prematuro)
ggplot(data, aes(x = Peso)) +
geom_histogram(binwidth = 100, fill = "blue", color = "black", alpha = 0.7) +
labs(title = "Distribuzione del Peso Neonatale", x = "Peso (grammi)", y = "Frequenza")
L’istogramma mostra che la distribuzione del peso alla nascita è grossomodo simile a una normale, con una leggera asimmetria verso valori leggermente più bassi della media. La maggior parte dei neonati ha un peso compreso tra 3000 e 3500 grammi, con una concentrazione intorno a 3200-3300 g. I valori molto bassi o molto elevati sono rari, indicando che la variabilità più comune si concentra intorno a una media superiore ai 3000 g.
Abbiamo calcolato e visualizzato la matrice di correlazione per identificare le relazioni tra le variabili numeriche.
variabili_numeriche <- data[, c("Anni.madre", "N.gravidanze", "Gestazione", "Peso", "Lunghezza", "Cranio")]
# Matrice di scatterplot
pairs(variabili_numeriche,
main = "Matrice di Scatterplot delle Variabili Numeriche")
#3.3 Calcolo della matrice di correlazione
# Calcolo della matrice di correlazione
matrice_correlazione <- cor(variabili_numeriche)
# Visualizzazione della matrice di correlazione
print(matrice_correlazione)
## Anni.madre N.gravidanze Gestazione Peso Lunghezza
## Anni.madre 1.00000000 0.38063184 -0.1356671 -0.02247017 -0.06349157
## N.gravidanze 0.38063184 1.00000000 -0.1014919 0.00240730 -0.06040371
## Gestazione -0.13566714 -0.10149194 1.0000000 0.59176872 0.61892045
## Peso -0.02247017 0.00240730 0.5917687 1.00000000 0.79603676
## Lunghezza -0.06349157 -0.06040371 0.6189204 0.79603676 1.00000000
## Cranio 0.01607670 0.03900707 0.4608289 0.70480151 0.60334097
## Cranio
## Anni.madre 0.01607670
## N.gravidanze 0.03900707
## Gestazione 0.46082894
## Peso 0.70480151
## Lunghezza 0.60334097
## Cranio 1.00000000
# Visualizzazione della matrice di correlazione
corrplot(matrice_correlazione, method = "circle")
La matrice di scatterplot permette di osservare le relazioni bivariate
tra tutte le variabili numeriche. È evidente una forte correlazione
positiva tra Peso e le misure antropometriche (Lunghezza, Cranio) e tra
Peso e Gestazione. Man mano che aumentano le settimane di gravidanza, la
Lunghezza e il diametro del Cranio del neonato, il Peso tende ad
aumentare. Al contrario, l’età materna e il numero di gravidanze
precedenti non mostrano pattern chiari con il Peso, suggerendo un
impatto meno significativo di questi fattori. Inoltre, la densità dei
punti e l’assenza di pattern fortemente non lineari confermano, come
vedremo successivamente, l’utilità di un modello lineare come punto di
partenza.
# Tabella di contingenza tra Ospedale e Tipo.parto
t_parti <- table(data$Ospedale, data$Tipo.parto)
# Test chi-quadrato
test_chi <- chisq.test(t_parti)
# Output dei risultati
test_chi
##
## Pearson's Chi-squared test
##
## data: t_parti
## X-squared = 1.0972, df = 2, p-value = 0.5778
# Ipotesi: la media del peso del campione è 3200 g (valore noto/population mean)
# One-sample t-test per il peso
t_test_peso <- t.test(data$Peso, mu = 3200)
t_test_peso
##
## One Sample t-test
##
## data: data$Peso
## t = 8.0071, df = 2499, p-value = 1.782e-15
## alternative hypothesis: true mean is not equal to 3200
## 95 percent confidence interval:
## 3263.490 3304.672
## sample estimates:
## mean of x
## 3284.081
# Ipotesi: la media della lunghezza del campione è 500 mm
# One-sample t-test per la lunghezza
t_test_lunghezza <- t.test(data$Lunghezza, mu = 500)
t_test_lunghezza
##
## One Sample t-test
##
## data: data$Lunghezza
## t = -10.084, df = 2499, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 500
## 95 percent confidence interval:
## 493.6598 495.7242
## sample estimates:
## mean of x
## 494.692
Abbiamo eseguito un one-sample t-test confrontando la media del peso del campione con un valore di riferimento di 3200 g (indicativo). Il test risulta significativo (p < 0.001), indicando che il peso medio del nostro campione (3284 g) è significativamente diverso (e maggiore) rispetto allo standard considerato. Allo stesso modo, confrontando la media della lunghezza (494.7 mm) con una lunghezza di riferimento di 500 mm, il test mostra una differenza significativa (p < 0.001). Se non disponiamo di valori di riferimento ufficiali, questi test vanno interpretati con cautela, in quanto l’ipotesi nulla è basata su dati non comprovati da fonti esterne.
# Test t per Peso tra Maschi (M) e Femmine (F)
t_test_peso_sesso <- t.test(Peso ~ Sesso, data = data)
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 Lunghezza tra Maschi (M) e Femmine (F)
t_test_lunghezza_sesso <- t.test(Lunghezza ~ Sesso, data = data)
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 Cranio tra Maschi (M) e Femmine (F)
t_test_cranio_sesso <- t.test(Cranio ~ Sesso, data = data)
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
Il boxplot confronta il Peso neonatale tra madri fumatrici e non. Visivamente, i neonati di madri non fumatrici sembrano pesare mediamente di più. Tuttavia, il test t non mostra una differenza statisticamente significativa (p > 0.05). Ciò può significare che l’effetto del fumo, se presente, è troppo piccolo per essere rilevato nel campione, oppure che altri fattori confondenti riducono il suo impatto osservato sul Peso.
boxplot(Peso ~ Fumatrici, data = data,
main = "Peso Neonatale vs Fumo Materno",
xlab = "Fumatrici",
ylab = "Peso (grammi)",
col = c("lightgreen", "lightpink"))
# Test t per campioni indipendenti
test_t <- t.test(Peso ~ Fumatrici, data = data)
# Visualizzazione dei risultati del test
print(test_t)
##
## Welch Two Sample t-test
##
## data: Peso by Fumatrici
## t = 1.034, df = 114.1, p-value = 0.3033
## alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
## 95 percent confidence interval:
## -45.61354 145.22674
## sample estimates:
## mean in group 0 mean in group 1
## 3286.153 3236.346
Risultati del test t:
Media gruppo non fumatrici: 3286 g
Media gruppo fumatrici: 3236 g
Valore p: 0.303 (non significativo)
# Relazione tra età materna e peso neonatale
ggplot(data, aes(x = Anni.madre, y = Peso)) +
geom_point(alpha = 0.5) +
geom_smooth(method = "lm", se = FALSE, color = "red") +
labs(title = "Relazione tra Età Materna e Peso Neonatale",
x = "Età della Madre (anni)",
y = "Peso del Neonato (grammi)")
Il grafico della relazione tra l’Età materna e il Peso neonatale non mostra un trend chiaro: la linea di regressione è quasi orizzontale, indicando un effetto minimo o nullo dell’età della madre sul peso alla nascita. I punti sono distribuiti in modo abbastanza uniforme lungo l’asse dell’età, suggerendo che l’impatto di questo fattore è trascurabile rispetto ad altri predittori più fortemente correlati al peso.
# Analisi del numero di gravidanze precedenti
ggplot(data, aes(x = as.factor(N.gravidanze), y = Peso)) +
geom_boxplot() +
labs(title = "Peso Neonatale rispetto al Numero di Gravidanze Precedenti",
x = "Numero di Gravidanze Precedenti",
y = "Peso del Neonato (grammi)")
Questo boxplot illustra come varia la distribuzione del Peso neonatale al variare del numero di gravidanze precedenti della madre. Si nota una certa variabilità, ma non si osserva un pattern lineare o costante: aumenti o diminuzioni nella mediana del Peso all’aumentare del numero di gravidanze non sono chiaramente definiti. Potrebbe esserci un leggero incremento del Peso con gravidanze multiple, ma la presenza di pochi casi estremi in classi elevate di N.gravidanze rende difficile una conclusione chiara.
Costruiamo un modello di regressione lineare che include tutte le variabili disponibili. I risultati principali mostrano che: - Variabili significative includono Gestazione, Lunghezza, Cranio e Sesso. - Variabili non significative, come Anni della madre, vengono rimosse nel modello raffinato.
modello <- lm(Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione + Lunghezza + Cranio + Tipo.parto + Ospedale + Sesso, data = data)
summary(modello)
##
## Call:
## lm(formula = Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione +
## Lunghezza + Cranio + Tipo.parto + Ospedale + Sesso, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1124.40 -181.66 -14.42 160.91 2611.89
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6738.4762 141.3087 -47.686 < 2e-16 ***
## Anni.madre 0.8921 1.1323 0.788 0.4308
## N.gravidanze 11.2665 4.6608 2.417 0.0157 *
## Fumatrici -30.1631 27.5386 -1.095 0.2735
## Gestazione 32.5696 3.8187 8.529 < 2e-16 ***
## Lunghezza 10.2945 0.3007 34.236 < 2e-16 ***
## Cranio 10.4707 0.4260 24.578 < 2e-16 ***
## Tipo.partoNat 29.5254 12.0844 2.443 0.0146 *
## Ospedaleosp2 -11.2095 13.4379 -0.834 0.4043
## Ospedaleosp3 28.0958 13.4957 2.082 0.0375 *
## SessoM 77.5409 11.1776 6.937 5.08e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 273.9 on 2489 degrees of freedom
## Multiple R-squared: 0.7289, Adjusted R-squared: 0.7278
## F-statistic: 669.2 on 10 and 2489 DF, p-value: < 2.2e-16
Gestazione (p < 0.001): Un aumento di una settimana di gestazione porta a un incremento medio di 32.6 g nel peso.
Lunghezza (p < 0.001): Ogni millimetro in più di lunghezza aumenta il peso di 10.3 g.
Cranio (p < 0.001): Ogni millimetro in più nel diametro craniale aumenta il peso di 10.4 g.
Sesso (M) (p < 0.001): I maschi pesano in media 77.5 g in più rispetto alle femmine.
Qualità del Modello R²: 0.7289 (72.9% della varianza del peso spiegata dal modello).
Errore standard dei residui: 273.9 g.
# Aggiungiamo un termine di interazione tra Gestazione e Fumatrici
modello_interazione <- lm(Peso ~ Gestazione * Fumatrici + Lunghezza + Cranio, data = data)
summary(modello_interazione)
##
## Call:
## lm(formula = Peso ~ Gestazione * Fumatrici + Lunghezza + Cranio,
## data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1105.74 -184.29 -13.72 167.14 2620.98
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6789.3469 136.7107 -49.662 <2e-16 ***
## Gestazione 32.2388 3.8632 8.345 <2e-16 ***
## Fumatrici 521.3624 765.0499 0.681 0.496
## Lunghezza 10.4112 0.3024 34.433 <2e-16 ***
## Cranio 10.7854 0.4283 25.180 <2e-16 ***
## Gestazione:Fumatrici -13.8705 19.4735 -0.712 0.476
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 277.7 on 2494 degrees of freedom
## Multiple R-squared: 0.7208, Adjusted R-squared: 0.7202
## F-statistic: 1288 on 5 and 2494 DF, p-value: < 2.2e-16
# Valutiamo se l'interazione è significativa
Questo grafico mostra come l’andamento del Peso in funzione della Gestazione differisca tra madri fumatrici e non. Sebbene le linee di regressione sembrino leggermente divergere, l’analisi statistica non ha evidenziato un’interazione significativa. In altre parole, l’effetto del fumo non modifica sostanzialmente la relazione tra settimane di gestazione e peso neonatale, almeno nei limiti di questo dataset.
# Grafici diagnostici del modello
par(mfrow = c(2, 2))
plot(modello)
I grafici diagnostici dei residui permettono di valutare l’adeguatezza del modello lineare. Il Q-Q plot mostra che la distribuzione dei residui non segue perfettamente la normalità (come confermato dallo Shapiro-Wilk test), con code leggermente più pesanti del previsto. Tuttavia, l’assenza di pattern marcati nel grafico Residui vs Fitted indica che la relazione lineare è ragionevolmente appropriata. Il plot Scale-Location non evidenzia gravi problemi di eterogeneità della varianza, e il grafico Residui vs Leverage non mostra un numero preoccupante di punti altamente influenti. Complessivamente, il modello sembra stabile, anche se non perfetto.
# Test di Shapiro-Wilk per i residui
shapiro.test(residuals(modello))
##
## Shapiro-Wilk normality test
##
## data: residuals(modello)
## W = 0.97415, p-value < 2.2e-16
I risultati del test di Shapiro-Wilk indicano che i residui del modello non seguono una distribuzione normale. Questa violazione dell’assunzione di normalità potrebbe rendere meno affidabili alcune inferenze, specialmente per quanto riguarda gli intervalli di confidenza e i test di significatività dei coefficienti. Tuttavia, data l’elevata numerosità campionaria (2500 osservazioni), l’approssimazione asintotica fornita dal Teorema del Limite Centrale attenua parzialmente questo problema. In altre parole, con un campione così ampio, la regressione lineare rimane comunque abbastanza robusta anche in presenza di residui non perfettamente normali.
Poiché i residui non sono normali, e se questa problematica si volesse affrontare in maniera più rigorosa, si potrebbero adottare diverse strategie. Ad esempio, si potrebbero applicare trasformazioni (logaritmica, radice quadrata) sui dati per migliorare la simmetria della distribuzione dei residui. In alternativa, si possono utilizzare metodi robusti alla violazione delle assunzioni classiche della regressione lineare (quali regressioni quantiliche o modelli non parametrici) per valutare la stabilità dei risultati. Con 2500 osservazioni, l’approssimazione asintotica rende comunque accettabile l’uso dei metodi standard, ma in un contesto di ricerca clinica di alta precisione, considerare questi approcci alternativi potrebbe fornire inferenze più affidabili e meno sensibili a deviazioni dalla normalità.
# Calcolo del Variance Inflation Factor (VIF)
vif(modello)
## GVIF Df GVIF^(1/(2*Df))
## Anni.madre 1.187454 1 1.089704
## N.gravidanze 1.186428 1 1.089233
## Fumatrici 1.007392 1 1.003689
## Gestazione 1.695810 1 1.302233
## Lunghezza 2.085755 1 1.444214
## Cranio 1.630796 1 1.277026
## Tipo.parto 1.004242 1 1.002119
## Ospedale 1.004071 2 1.001016
## Sesso 1.040643 1 1.020119
Creiamo un modello raffinato rimuovendo le variabili non significative. Confrontiamo i modelli utilizzando AIC e BIC, metriche che valutano il compromesso tra accuratezza e complessità. ### Rimozione della variabili non significative Rimuoviamo le variabili non significative nel modello iniziale, anche se non statisticamente significativa (p=0.273), la variabile Fumatrici è clinicamente importante per analizzare l’effetto del fumo sul peso neonatale, pertanto non viene eliminata (noto fattore di rischio).
# Creazione di un modello raffinato rimuovendo variabili non significative
modello_raffinato <- lm(Peso ~ Gestazione + Lunghezza + Cranio + Fumatrici, data = data)
# Sommario del modello raffinato
summary(modello_raffinato)
##
## Call:
## lm(formula = Peso ~ Gestazione + Lunghezza + Cranio + Fumatrici,
## data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1106.20 -183.72 -13.46 167.10 2621.03
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6777.3182 135.6503 -49.962 <2e-16 ***
## Gestazione 31.8727 3.8284 8.325 <2e-16 ***
## Lunghezza 10.4140 0.3023 34.449 <2e-16 ***
## Cranio 10.7880 0.4283 25.190 <2e-16 ***
## Fumatrici -23.2035 27.8670 -0.833 0.405
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 277.7 on 2495 degrees of freedom
## Multiple R-squared: 0.7207, Adjusted R-squared: 0.7203
## F-statistic: 1610 on 4 and 2495 DF, p-value: < 2.2e-16
AIC() e BIC() calcolano rispettivamente l’Akaike Information Criterion e il Bayesian Information Criterion.
Un valore AIC o BIC più basso indica un modello migliore in termini di compromesso tra accuratezza e complessità.
# Confronto dei modelli usando AIC e BIC
AIC(modello, modello_raffinato)
## df AIC
## modello 12 35171.95
## modello_raffinato 6 35234.30
BIC(modello, modello_raffinato)
## df BIC
## modello 12 35241.84
## modello_raffinato 6 35269.24
summary(cars)
## speed dist
## Min. : 4.0 Min. : 2.00
## 1st Qu.:12.0 1st Qu.: 26.00
## Median :15.0 Median : 36.00
## Mean :15.4 Mean : 42.98
## 3rd Qu.:19.0 3rd Qu.: 56.00
## Max. :25.0 Max. :120.00
### Selezione Stepwise del Modello
# Utilizzo della selezione stepwise basata sull'AIC
modello_stepwise <- step(modello, direction = "both", trace = FALSE)
summary(modello_stepwise)
##
## Call:
## lm(formula = Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio +
## Tipo.parto + Ospedale + Sesso, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1113.18 -181.16 -16.58 161.01 2620.19
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6707.4293 135.9438 -49.340 < 2e-16 ***
## N.gravidanze 12.3619 4.3325 2.853 0.00436 **
## Gestazione 31.9909 3.7896 8.442 < 2e-16 ***
## Lunghezza 10.3086 0.3004 34.316 < 2e-16 ***
## Cranio 10.4922 0.4254 24.661 < 2e-16 ***
## Tipo.partoNat 29.2803 12.0817 2.424 0.01544 *
## Ospedaleosp2 -11.0227 13.4363 -0.820 0.41209
## Ospedaleosp3 28.6408 13.4886 2.123 0.03382 *
## SessoM 77.4412 11.1756 6.930 5.36e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 273.9 on 2491 degrees of freedom
## Multiple R-squared: 0.7287, Adjusted R-squared: 0.7278
## F-statistic: 836.3 on 8 and 2491 DF, p-value: < 2.2e-16
# Confronto del modello stepwise con il modello precedente
AIC(modello, modello_stepwise)
## df AIC
## modello 12 35171.95
## modello_stepwise 10 35169.79
BIC(modello, modello_stepwise)
## df BIC
## modello 12 35241.84
## modello_stepwise 10 35228.03
Per valutare le performance del modello, il dataset viene suddiviso in un set di training (80%) e un set di test (20%). Questa tecnica permette di addestrare il modello su una porzione dei dati e verificarne la capacità predittiva su dati non utilizzati durante l’addestramento. ### Divisione del dataset
# Impostazione del seed per la riproducibilità
set.seed(123)
# Creazione dell'indice per il training set (80% dei dati)
indice_train <- createDataPartition(data$Peso, p = 0.8, list = FALSE)
# Creazione dei dataset di training e di test
dati_train <- data[indice_train, ]
dati_test <- data[-indice_train, ]
Il modello di regressione viene addestrato utilizzando solo il set di training. In questo modello, abbiamo incluso le variabili più significative identificate nella fase precedente: Gestazione, Lunghezza, Cranio e Fumatrici.
I risultati mostrano che:
Gestazione: Ogni settimana aggiuntiva di gestazione aumenta il peso neonatale di circa 33.8 g (p < 0.001).
Lunghezza: Ogni millimetro in più di lunghezza contribuisce con 10.1 g (p < 0.001).
Cranio: Il diametro craniale aggiunge 10.9 g per ogni millimetro (p < 0.001).
Fumatrici: Sebbene non significativa (p ≈ 0.146), è inclusa per la sua rilevanza clinica.
# Modello addestrato sul training set
modello_train <- lm(Peso ~ Gestazione + Lunghezza + Cranio + Fumatrici, data = dati_train)
# Sommario del modello
summary(modello_train)
##
## Call:
## lm(formula = Peso ~ Gestazione + Lunghezza + Cranio + Fumatrici,
## data = dati_train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1027.07 -186.22 -13.41 170.49 2559.40
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6716.6090 151.3830 -44.368 < 2e-16 ***
## Gestazione 33.8157 4.2911 7.880 5.32e-15 ***
## Lunghezza 10.0984 0.3410 29.614 < 2e-16 ***
## Cranio 10.8589 0.4816 22.546 < 2e-16 ***
## Fumatrici -45.5756 31.3626 -1.453 0.146
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 280.8 on 1997 degrees of freedom
## Multiple R-squared: 0.7166, Adjusted R-squared: 0.716
## F-statistic: 1262 on 4 and 1997 DF, p-value: < 2.2e-16
Una volta addestrato il modello, lo validiamo utilizzando il set di test. Due metriche principali vengono calcolate:
Mean Squared Error (MSE): La media degli errori quadratici fornisce una misura della precisione predittiva del modello. Nel nostro caso, l’MSE è 70,547 g².
Coefficiente di Determinazione (R²): Indica la proporzione della varianza del peso neonatale spiegata dal modello. Con un valore di R² ≈ 0.737, il modello spiega il 73.7% della variabilità del peso.
# Previsione sul test set
previsioni <- predict(modello_train, newdata = dati_test)
# Calcolo del Mean Squared Error (MSE)
mse <- mean((dati_test$Peso - previsioni)^2)
# Calcolo dell'R-squared
ss_tot <- sum((dati_test$Peso - mean(dati_test$Peso))^2)
ss_res <- sum((dati_test$Peso - previsioni)^2)
r_squared <- 1 - (ss_res / ss_tot)
# Visualizzazione dei risultati
cat("Mean Squared Error (MSE):", mse, "\n")
## Mean Squared Error (MSE): 70546.92
cat("Coefficiente di determinazione (R²):", r_squared, "\n")
## Coefficiente di determinazione (R²): 0.7365072
Il modello validato mostra buone prestazioni, con un R² superiore al 70% sia nel training che nel test set. Questo risultato indica che il modello è generalizzabile, ovvero è in grado di fare previsioni accurate anche su dati nuovi.
Supponiamo di voler prevedere il peso di una neonata considerando:
Madre alla terza gravidanza
Non fumatrice
Parto alla 39esima settimana
Valori medi per Lunghezza e Cranio
# Calcolo dei valori medi di Lunghezza e Cranio
lunghezza_media <- mean(data$Lunghezza)
cranio_medio <- mean(data$Cranio)
# Creazione del nuovo caso
nuovo_caso <- data.frame(
Gestazione = 39,
Lunghezza = lunghezza_media,
Cranio = cranio_medio,
Fumatrici = 0
)
# Previsione del peso
peso_previsto <- predict(modello_raffinato, newdata = nuovo_caso)
# Visualizzazione del risultato
cat("Il peso previsto del neonato è:", round(peso_previsto, 2), "grammi\n")
## Il peso previsto del neonato è: 3285.67 grammi
# Grafico Predetto vs Osservato sul test set
plot(dati_test$Peso, previsioni,
xlab = "Peso Osservato (grammi)",
ylab = "Peso Predetto (grammi)",
main = "Valori Predetti vs Valori Osservati",
pch = 16, col = "blue")
abline(a = 0, b = 1, col = "red", lwd = 2)
Il grafico dei Valori Predetti vs Valori Osservati illustra la capacità del modello di riprodurre i dati reali. I punti si distribuiscono intorno alla linea y = x, indicando che le previsioni sono spesso vicine ai valori osservati. Questo conferma l’elevata proporzione di varianza spiegata (R² > 0.7) e suggerisce che il modello è in grado di fornire stime del peso neonatale relativamente accurate.
### Impatto delle Settimane di Gestazione sul Peso Neonatale
ggplot(data, aes(x = Gestazione, y = Peso)) +
geom_point(alpha = 0.3) +
geom_smooth(method = "lm", se = TRUE, color = "blue") +
labs(title = "Impatto delle Settimane di Gestazione sul Peso Neonatale",
x = "Settimane di Gestazione",
y = "Peso del Neonato (grammi)")
### Interazione tra Fumo Materno e Gestazione
ggplot(data, aes(x = Gestazione, y = Peso, color = as.factor(Fumatrici))) +
geom_point(alpha = 0.5) +
geom_smooth(method = "lm", se = FALSE) +
labs(title = "Peso Neonatale: Interazione tra Fumo Materno e Gestazione",
x = "Settimane di Gestazione",
y = "Peso del Neonato (grammi)",
color = "Fumatrici")
Il grafico evidenzia una relazione nettamente positiva tra le Settimane di Gestazione e il Peso neonatale. Aumentando le settimane di gestazione, il peso cresce in modo quasi lineare, come mostrato dalla retta di regressione. L’intervallo di confidenza attorno alla retta è relativamente stretto, indicando una stima piuttosto precisa di questo effetto.
# Estrazione dei coefficienti dal modello
coefficients <- summary(modello_raffinato)$coefficients
# Creazione di un dataframe per i coefficienti
coeff_df <- data.frame(
Variabile = rownames(coefficients),
Coefficiente = coefficients[, "Estimate"]
)
# Rimozione dell'intercetta
coeff_df <- coeff_df[-1, ]
# Grafico dei coefficienti
barplot(coeff_df$Coefficiente, names.arg = coeff_df$Variabile,
main = "Importanza delle Variabili nel Modello",
ylab = "Valore del Coefficiente",
col = "darkgreen", las = 2)
Questo barplot mostra l’influenza stimata di ciascuna variabile selezionata nel modello finale sul peso neonatale. L’asse verticale rappresenta il valore del coefficiente di regressione: valori positivi indicano che l’aumento della variabile corrisponde a un incremento nel peso previsto, mentre valori negativi suggeriscono una riduzione.
Come si vede, la Gestazione ha il coefficiente più elevato, indicando che ogni settimana aggiuntiva di gravidanza incrementa significativamente il peso del neonato. Anche Lunghezza e Cranio hanno un impatto positivo e rilevante: ad ogni millimetro in più di lunghezza o diametro craniale si associa un aumento apprezzabile del peso. Al contrario, la variabile Fumatrici mostra un coefficiente negativo, ma di entità minore e non statisticamente significativo, segnalando che, pur essendo considerata rilevante clinicamente, il fumo materno non ha un effetto evidente sul peso alla nascita all’interno di questo dataset.
In sintesi, il grafico facilita la comprensione dell’importanza relativa dei predittori chiave (Gestazione, Lunghezza, Cranio) rispetto ad altri fattori meno influenti.
# Modello con interazione tra Gestazione e Fumatrici
modello_interazione <- lm(Peso ~ Gestazione * Fumatrici + Lunghezza + Cranio, data = data)
summary(modello_interazione)
##
## Call:
## lm(formula = Peso ~ Gestazione * Fumatrici + Lunghezza + Cranio,
## data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1105.74 -184.29 -13.72 167.14 2620.98
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6789.3469 136.7107 -49.662 <2e-16 ***
## Gestazione 32.2388 3.8632 8.345 <2e-16 ***
## Fumatrici 521.3624 765.0499 0.681 0.496
## Lunghezza 10.4112 0.3024 34.433 <2e-16 ***
## Cranio 10.7854 0.4283 25.180 <2e-16 ***
## Gestazione:Fumatrici -13.8705 19.4735 -0.712 0.476
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 277.7 on 2494 degrees of freedom
## Multiple R-squared: 0.7208, Adjusted R-squared: 0.7202
## F-statistic: 1288 on 5 and 2494 DF, p-value: < 2.2e-16
# Aggiunta di un termine quadratico per Gestazione
data$Gestazione2 <- data$Gestazione^2
# Modello con termine quadratico
modello_non_lineare <- lm(Peso ~ Gestazione + Gestazione2 + Lunghezza + Cranio + Fumatrici, data = data)
summary(modello_non_lineare)
##
## Call:
## lm(formula = Peso ~ Gestazione + Gestazione2 + Lunghezza + Cranio +
## Fumatrici, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1169.91 -182.66 -14.07 166.66 2649.49
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -4258.4314 906.0448 -4.700 2.74e-06 ***
## Gestazione -108.5278 50.0806 -2.167 0.03032 *
## Gestazione2 1.8739 0.6665 2.812 0.00497 **
## Lunghezza 10.5365 0.3050 34.544 < 2e-16 ***
## Cranio 10.9041 0.4297 25.378 < 2e-16 ***
## Fumatrici -21.7566 27.8332 -0.782 0.43448
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 277.3 on 2494 degrees of freedom
## Multiple R-squared: 0.7216, Adjusted R-squared: 0.721
## F-statistic: 1293 on 5 and 2494 DF, p-value: < 2.2e-16
L’inclusione di un termine quadratico per la Gestazione (Gestazione²) nel modello evidenzia che l’effetto di questa variabile sul peso non è perfettamente lineare: il coefficiente del termine quadratico risulta significativo (p < 0.01). Ciò suggerisce che l’incremento di peso non cresce costantemente con le settimane di gestazione, ma potrebbe seguire una curva leggermente più complessa. Tuttavia, l’aumento di R² ottenuto aggiungendo il termine quadratico è minimo e non giustifica pienamente la maggiore complessità del modello. Pertanto, se l’obiettivo è mantenere un modello parsimonioso e facilmente interpretabile, si potrebbe preferire la versione lineare, a meno che non vi siano motivazioni cliniche o teoriche solide per conservare il termine quadratico.