library(knitr)
knitr::opts_chunk$set(echo = TRUE)
neonati <- read.csv("C:/Users/ce168diedifi/Desktop/Profession.AI/Corso Statistica Inferenziale/Progetto/neonati.csv", sep=",", header=TRUE, encoding="UTF-8")
attach(neonati)
kable(head(neonati))
| 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 |
options(warn = -1)
#install.packages("kableExtra")
library("knitr")
library("kableExtra")
library(dplyr)
##
## Caricamento pacchetto: 'dplyr'
## Il seguente oggetto è mascherato da 'package:kableExtra':
##
## group_rows
## I seguenti oggetti sono mascherati da 'package:stats':
##
## filter, lag
## I seguenti oggetti sono mascherati da 'package:base':
##
## intersect, setdiff, setequal, union
neonati.factor <- neonati %>%
mutate(across(where(is.character), as.factor))
#str(neonati.factor)
kable(summary(neonati.factor) , format = "html") %>%
kable_styling(font_size = 12, full_width = FALSE, position = "center",html_font = "Consolas") %>%
row_spec(0, bold = TRUE, font_size = 14, color = "white", background = "silver") %>%
column_spec(1, italic = TRUE, color = "blue") %>%
row_spec(0, bold = TRUE, font_size = 12, color = "black") %>%
row_spec(1:nrow(summary(neonati)), background = "white")
| Anni.madre | N.gravidanze | Fumatrici | Gestazione | Peso | Lunghezza | Cranio | Tipo.parto | Ospedale | Sesso | |
|---|---|---|---|---|---|---|---|---|---|---|
| Min. : 0.00 | Min. : 0.0000 | Min. :0.0000 | Min. :25.00 | Min. : 830 | Min. :310.0 | Min. :235 | Ces: 728 | osp1:816 | F:1256 | |
| 1st Qu.:25.00 | 1st Qu.: 0.0000 | 1st Qu.:0.0000 | 1st Qu.:38.00 | 1st Qu.:2990 | 1st Qu.:480.0 | 1st Qu.:330 | Nat:1772 | osp2:849 | M:1244 | |
| Median :28.00 | Median : 1.0000 | Median :0.0000 | Median :39.00 | Median :3300 | Median :500.0 | Median :340 | NA | osp3:835 | NA | |
| Mean :28.16 | Mean : 0.9812 | Mean :0.0416 | Mean :38.98 | Mean :3284 | Mean :494.7 | Mean :340 | NA | NA | NA | |
| 3rd Qu.:32.00 | 3rd Qu.: 1.0000 | 3rd Qu.:0.0000 | 3rd Qu.:40.00 | 3rd Qu.:3620 | 3rd Qu.:510.0 | 3rd Qu.:350 | NA | NA | NA | |
| Max. :46.00 | Max. :12.0000 | Max. :1.0000 | Max. :43.00 | Max. :4930 | Max. :565.0 | Max. :390 | NA | NA | NA |
Guardando il summary del dataset noto dei possibili valori anomali per la variabile “Anni.madre” che ha dei valori minimi a zero e per la variabile “N.gravidanze” dove c’è un valore massimo di 12. Lo vedremo con l’analisi di dettaglio.
Descrivo le singoli variabili presenti nel dataset:
Rappresento con uno scatterplot la relazione tra le variabili:
plot(Peso,Anni.madre,pch=20)
Dal grafico, il peso dei neonati sembra aggirarsi intorno ai 3kg / 4kg quando gli anni della madre sono tra i 20e i 40 anni al momento della gestazione. La relazione sembra essere lineare e piuttosto orizzontale. Lungo la distribuzione e fuori noto degli ouliers.
kable(cor(Peso,Anni.madre))
| x |
|---|
| -0.0224702 |
il coefficiente di correlazione di Bravais-Pearson è di poco sotto lo zero suggerisce che le due variabili non presentano una relazione lineare significativa e la variazione di una variabile non influenza apprezzabilmente l’altra.
Questa è la rappresentazione della correlazione tra Peso e il numero di gravidanze avute precedeti a quella corrente
plot(Peso,N.gravidanze,pch=20)
kable(cor(Peso,N.gravidanze))
| x |
|---|
| 0.0024073 |
Qui sia grafico che indice di correlazione indica una correlazione praticamente nulla tra le due variabili
plot(Peso,Gestazione,pch=20)
kable(cor(Peso,Gestazione))
| x |
|---|
| 0.5917687 |
Invece visualizzando e calcolando la correlazione tra Peso-Gestazione si nota una correlazione positiva moderata-forte tra le variabili. c’è una tendenza lineare evidente, ma non perfetta perchè lo scatterplot sembra assumere una tendenza leggermente curva.
n <- nrow(neonati)
neonati_numeric <- neonati[sapply(neonati, is.numeric)]
kable( round(cor(neonati_numeric), 2) )
| Anni.madre | N.gravidanze | Fumatrici | Gestazione | Peso | Lunghezza | Cranio | |
|---|---|---|---|---|---|---|---|
| Anni.madre | 1.00 | 0.38 | 0.01 | -0.14 | -0.02 | -0.06 | 0.02 |
| N.gravidanze | 0.38 | 1.00 | 0.05 | -0.10 | 0.00 | -0.06 | 0.04 |
| Fumatrici | 0.01 | 0.05 | 1.00 | 0.03 | -0.02 | -0.02 | -0.01 |
| Gestazione | -0.14 | -0.10 | 0.03 | 1.00 | 0.59 | 0.62 | 0.46 |
| Peso | -0.02 | 0.00 | -0.02 | 0.59 | 1.00 | 0.80 | 0.70 |
| Lunghezza | -0.06 | -0.06 | -0.02 | 0.62 | 0.80 | 1.00 | 0.60 |
| Cranio | 0.02 | 0.04 | -0.01 | 0.46 | 0.70 | 0.60 | 1.00 |
Qui voglio verificare se le variabili del dataset sono indipendenti, quindi testiamo se accettare o rifiutare l’ipotesi nulla che le variabili sono indipendenti,non esiste relazione tra di esse.
test.indipendenza <- chisq.test(neonati_numeric)
test.indipendenza
##
## Pearson's Chi-squared test
##
## data: neonati_numeric
## X-squared = 43525, df = 14994, p-value < 2.2e-16
il p-value è molto basso quindi si rifiuta l’ipotesi nulla e possiamo affermare che le variabili sono correlate.
Iniziamo col visulizzare la matrice di correlazione tra le variabili del dataset per avere una situazione generale delle correlazioni più probabili,cosa che comunque va verificata.
panel.cor <- function(x, y, digits = 2, prefix = "", cex.cor, ...)
{
par(usr = c(0, 1, 0, 1))
r <- abs(cor(x, y))
txt <- format(c(r, 0.123456789), digits = digits)[1]
txt <- paste0(prefix, txt)
if(missing(cex.cor)) cex.cor <- 0.8/strwidth(txt)
text(0.5, 0.5, txt, cex = cex.cor * r)
}
pairs(neonati_numeric, upper.panel = panel.smooth, lower.panel = panel.cor)
L’obiettivo è quello di identificare quali delle variabili del dataset sono più predittive del Peso alla nascita. Un focus particolare lo avremo sulle variabili “Anni.Madre”, “N.gravidanze”, “Fumatrici”, “Gestazione”.
Creo il primo modello di regressione lineare multiplo:
mod1 <- lm( data = neonati, Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione + Lunghezza + Cranio + Tipo.parto + Sesso )
summary(mod1)
##
## Call:
## lm(formula = Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione +
## Lunghezza + Cranio + Tipo.parto + Sesso, data = neonati)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1141.25 -181.75 -14.87 160.54 2629.75
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6740.6584 141.3921 -47.674 <2e-16 ***
## Anni.madre 0.9543 1.1335 0.842 0.3999
## N.gravidanze 11.5753 4.6656 2.481 0.0132 *
## Fumatrici -31.5916 27.5729 -1.146 0.2520
## Gestazione 32.8814 3.8227 8.602 <2e-16 ***
## Lunghezza 10.2718 0.3010 34.128 <2e-16 ***
## Cranio 10.4828 0.4266 24.573 <2e-16 ***
## Tipo.partoNat 30.2808 12.0990 2.503 0.0124 *
## SessoM 78.0278 11.1921 6.972 4e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 274.3 on 2491 degrees of freedom
## Multiple R-squared: 0.7279, Adjusted R-squared: 0.727
## F-statistic: 833 on 8 and 2491 DF, p-value: < 2.2e-16
Il primo modello che vado a realizzare contiene tutte le sue variabili. Questo modello ha un r quadro aggiustato molto vicino a 1, sembra essere un buon modello ma nello specifico alcune delle variabili presenti hanno una bassa significatività e che quindi vanno eliminate durante lo stepwise.
Quindi analizzando questo modello per ogni singola variabile:
Anche se alcune variabili come “Anni.Madre” e “Fumatrici” sono risultate di bassa influenza proverò a inserirle nei modelli futuri.
Inizio ad eliminare la variabile “Tipo.Parto”:
mod2 <- update(mod1,~.-Tipo.parto )
summary(mod2)
##
## Call:
## lm(formula = Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione +
## Lunghezza + Cranio + Sesso, data = neonati)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1161.56 -181.19 -15.75 163.70 2630.75
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6714.4109 141.1515 -47.569 < 2e-16 ***
## Anni.madre 0.9585 1.1347 0.845 0.3984
## N.gravidanze 11.2756 4.6690 2.415 0.0158 *
## Fumatrici -30.2959 27.5971 -1.098 0.2724
## Gestazione 32.9331 3.8267 8.606 < 2e-16 ***
## Lunghezza 10.2342 0.3009 34.009 < 2e-16 ***
## Cranio 10.5177 0.4268 24.642 < 2e-16 ***
## SessoM 78.0845 11.2039 6.969 4.06e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 274.6 on 2492 degrees of freedom
## Multiple R-squared: 0.7272, Adjusted R-squared: 0.7264
## F-statistic: 949 on 7 and 2492 DF, p-value: < 2.2e-16
il risultato è un modello pressocchè invariato.
Elimino la variabile “Anni.madre”:
mod3 <- update(mod2,~.-Anni.madre )
summary(mod3)
##
## Call:
## lm(formula = Peso ~ N.gravidanze + Fumatrici + Gestazione + Lunghezza +
## Cranio + Sesso, data = neonati)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1150.3 -181.3 -15.7 163.0 2636.3
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6681.6714 135.7178 -49.232 < 2e-16 ***
## N.gravidanze 12.7185 4.3450 2.927 0.00345 **
## Fumatrici -30.4634 27.5948 -1.104 0.26972
## Gestazione 32.5914 3.8051 8.565 < 2e-16 ***
## Lunghezza 10.2341 0.3009 34.011 < 2e-16 ***
## Cranio 10.5359 0.4262 24.718 < 2e-16 ***
## SessoM 78.1713 11.2028 6.978 3.83e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 274.6 on 2493 degrees of freedom
## Multiple R-squared: 0.7271, Adjusted R-squared: 0.7265
## F-statistic: 1107 on 6 and 2493 DF, p-value: < 2.2e-16
Il valore di r2a è leggermente cresciuto. Nonostante le credenze popolari sull’impatto del fumo, non ci sono prove sufficienti per affermare che la variabile “Fumatrici” influisce sul Peso del neonato.
Elimino la variabile “Fumatrici”:
mod4 <- update(mod3,~.-Fumatrici )
summary(mod4)
##
## Call:
## lm(formula = Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio +
## Sesso, data = neonati)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1149.44 -180.81 -15.58 163.64 2639.72
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6681.1445 135.7229 -49.226 < 2e-16 ***
## N.gravidanze 12.4750 4.3396 2.875 0.00408 **
## Gestazione 32.3321 3.7980 8.513 < 2e-16 ***
## Lunghezza 10.2486 0.3006 34.090 < 2e-16 ***
## Cranio 10.5402 0.4262 24.728 < 2e-16 ***
## SessoM 77.9927 11.2021 6.962 4.26e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 274.6 on 2494 degrees of freedom
## Multiple R-squared: 0.727, Adjusted R-squared: 0.7265
## F-statistic: 1328 on 5 and 2494 DF, p-value: < 2.2e-16
Qui abbiamo un r2a identico al precedente, ma con tutte le variabili presenti sono molto significative perchè il singolo p-value è molto sotto il 5%.
Provo l’effetto quadratico sulla variabile “Fumatrici” per verificare se effettivamente è una variabile senza effetto:
mod5 <- update(mod4, ~.+I(Fumatrici^2))
summary(mod5)
##
## Call:
## lm(formula = Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio +
## Sesso + I(Fumatrici^2), data = neonati)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1150.3 -181.3 -15.7 163.0 2636.3
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6681.6714 135.7178 -49.232 < 2e-16 ***
## N.gravidanze 12.7185 4.3450 2.927 0.00345 **
## Gestazione 32.5914 3.8051 8.565 < 2e-16 ***
## Lunghezza 10.2341 0.3009 34.011 < 2e-16 ***
## Cranio 10.5359 0.4262 24.718 < 2e-16 ***
## SessoM 78.1713 11.2028 6.978 3.83e-12 ***
## I(Fumatrici^2) -30.4634 27.5948 -1.104 0.26972
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 274.6 on 2493 degrees of freedom
## Multiple R-squared: 0.7271, Adjusted R-squared: 0.7265
## F-statistic: 1107 on 6 and 2493 DF, p-value: < 2.2e-16
Anche l’effetto quadrativo sulla variabile “Fumatrici” conferma la sua non influenza. Pertanto per adesso il modello 4 resta il migliore.
Provo con far interagire la variabile “Gestazione” con “Sesso”:
mod6 <- lm(data = neonati, Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio + Sesso + Gestazione*Sesso)
summary(mod6)
##
## Call:
## lm(formula = Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio +
## Sesso + Gestazione * Sesso, data = neonati)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1144.73 -181.02 -15.21 163.38 2638.22
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6571.7016 166.9616 -39.361 < 2e-16 ***
## N.gravidanze 12.4289 4.3396 2.864 0.00422 **
## Gestazione 29.4475 4.5818 6.427 1.55e-10 ***
## Lunghezza 10.2523 0.3006 34.102 < 2e-16 ***
## Cranio 10.5416 0.4262 24.732 < 2e-16 ***
## SessoM -185.9051 234.7635 -0.792 0.42850
## Gestazione:SessoM 6.7624 6.0090 1.125 0.26054
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 274.6 on 2493 degrees of freedom
## Multiple R-squared: 0.7271, Adjusted R-squared: 0.7265
## F-statistic: 1107 on 6 and 2493 DF, p-value: < 2.2e-16
Aggiungendo al modello l’iterazione tra Gestazione-Sesso questa non è significativa ma anche il Sesso perde di significatività.
Pertanto il modello 4 resta ancora il migliore.
BIC(mod1, mod2, mod3, mod4, mod5, mod6)
## df BIC
## mod1 10 35235.35
## mod2 9 35233.81
## mod3 8 35226.70
## mod4 7 35220.10
## mod5 8 35226.70
## mod6 8 35226.65
Il modello 4, dell’analisi sopra, sembra essere di nuovo il modello migliore.
Provo ad eseguire una procedura di selezione stepwise dei modelli in autoamatico, per verificare la mia analisi con quella automatica:
#install.packages("MASS")
library("MASS")
##
## Caricamento pacchetto: 'MASS'
## Il seguente oggetto è mascherato da 'package:dplyr':
##
## select
stepwise.mod <- MASS::stepAIC(mod2, direction = "both")
## Start: AIC=28084.7
## Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione + Lunghezza +
## Cranio + Sesso
##
## Df Sum of Sq RSS AIC
## - Anni.madre 1 53803 187973654 28083
## - Fumatrici 1 90879 188010731 28084
## <none> 187919851 28085
## - N.gravidanze 1 439797 188359648 28089
## - Sesso 1 3662833 191582684 28131
## - Gestazione 1 5585184 193505035 28156
## - Cranio 1 45791026 233710877 28628
## - Lunghezza 1 87220887 275140738 29036
##
## Step: AIC=28083.42
## Peso ~ N.gravidanze + Fumatrici + Gestazione + Lunghezza + Cranio +
## Sesso
##
## Df Sum of Sq RSS AIC
## - Fumatrici 1 91892 188065546 28083
## <none> 187973654 28083
## + Anni.madre 1 53803 187919851 28085
## - N.gravidanze 1 646039 188619694 28090
## - Sesso 1 3671289 191644943 28130
## - Gestazione 1 5531705 193505359 28154
## - Cranio 1 46066755 234040410 28629
## - Lunghezza 1 87218857 275192512 29034
##
## Step: AIC=28082.64
## Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio + Sesso
##
## Df Sum of Sq RSS AIC
## <none> 188065546 28083
## + Fumatrici 1 91892 187973654 28083
## + Anni.madre 1 54816 188010731 28084
## - N.gravidanze 1 623141 188688687 28089
## - Sesso 1 3655292 191720838 28129
## - Gestazione 1 5464853 193530399 28152
## - Cranio 1 46108583 234174130 28629
## - Lunghezza 1 87632762 275698308 29037
summary(stepwise.mod)
##
## Call:
## lm(formula = Peso ~ N.gravidanze + Gestazione + Lunghezza + Cranio +
## Sesso, data = neonati)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1149.44 -180.81 -15.58 163.64 2639.72
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6681.1445 135.7229 -49.226 < 2e-16 ***
## N.gravidanze 12.4750 4.3396 2.875 0.00408 **
## Gestazione 32.3321 3.7980 8.513 < 2e-16 ***
## Lunghezza 10.2486 0.3006 34.090 < 2e-16 ***
## Cranio 10.5402 0.4262 24.728 < 2e-16 ***
## SessoM 77.9927 11.2021 6.962 4.26e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 274.6 on 2494 degrees of freedom
## Multiple R-squared: 0.727, Adjusted R-squared: 0.7265
## F-statistic: 1328 on 5 and 2494 DF, p-value: < 2.2e-16
Il modello selezionato in automatico è identico al mio modello 4 che si conferma essere nuovamente il migliore.
#install.packages("car")
library(car)
## Caricamento del pacchetto richiesto: carData
##
## Caricamento pacchetto: 'car'
## Il seguente oggetto è mascherato da 'package:dplyr':
##
## recode
vif(mod4)
## N.gravidanze Gestazione Lunghezza Cranio Sesso
## 1.023475 1.669189 2.074689 1.624465 1.040054
Infatti calcolando i VIF delle variabili del modello 4 tutti i VIF molto < di 5.
Se confronto i due modelli, modello 3 e modello calcolato con mass, questi sono identici.
BIC(mod4, stepwise.mod)
## df BIC
## mod4 7 35220.1
## stepwise.mod 7 35220.1
Adesso verifichiamo i test di normalità della variabile “Peso”:
shapiro.test(Peso)
##
## Shapiro-Wilk normality test
##
## data: Peso
## W = 0.97066, p-value < 2.2e-16
Il test di Shapiro Wilk indica che i dati non seguono proprio una distribuzione normale, ma essendo il valore W molto vicino a 1 l’asimmetria potrebbe non essere così accentuata.
Adesso verifico la direzione dell’asimmetria:
library(moments)
skewness(Peso)
## [1] -0.6470308
Abbiamo una distribuzione asimmetrica con coda a sinistra (negativa).
Calcolando la Curtosi verifichiamo la “pesantezza delle code”:
kurtosis(Peso)
## [1] 5.031532
con un valore > 3 abbiamo una distribuzione leptocurtica.
Rappresento graficamente la distribuzione del “Peso”:
library(ggplot2)
ggplot(data = neonati, aes(x = Peso)) +
geom_histogram(aes(y = after_stat(density)), bins = 30, fill = "blue", alpha = 0.6) +
geom_density(color = "red", lwd = 1)
Rappresentanto la variabile “Peso” col bocplot evidenzio la presenza di outliers:
ggplot(data = neonati, aes(y = Peso)) +
geom_boxplot(fill = "lightblue")
Infatti il boxplot evidenzia degli outliers nella parte inferiore.
COnsidrando che stiamo analizzando la variabile “Peso” dei neonati,
questi outliers potrebbero essere dovuti a casi estremi come bambini
sottopeso, nascite premature, morte prematura del feto, altro!
Di seguito l’analisi dei residui:
par(mfrow=c(2,2))
plot(mod4)
Nel primo grafico i dati si sono raccolti intorno alla media di zero ma il pattern e’ curvato e la concentrazione dei dati e’ chiaramente verso i valori piu’ alti del peso.
Nel secondo grafico i residui seguono una distribuzione normale perchè tutti raccolti intorno alla bisettrice dove si notano dei residui sul lato sinistro e sul lato destro con un osservazione 1551 molto al di fuori della tendenza.
Nel terzo grafico abbiamo una nuvola di punti casuale e quasi orizzontale intorno ad un valore di Y che indica una varianza costante. Anche qui abbiamo una curvatura ma non è troppo eccessiva.
Nel quarto grafico si evidenziano i potenziali valori influenti, cioè quei valori outliers e/o leverage o combinazioni dei due. Qui si nota solo un valore che supera la soglia di avvertimento di 0.5 che è il 1551.
Calcolo i valori di leverage:
lev <- hatvalues(mod4)
p <- sum(lev)
n <- nrow(neonati)
soglia <- 2* p/n
plot(lev)
abline(h=soglia,col=2)
Questa visualizzazione evidenzia la presenza di parecchi leverage, tutti
quelli al di sopra della linea rossa.
Scrivo tutti i leverage individuati:
lev[lev>soglia]
## 13 15 34 67 89 96
## 0.005630918 0.007050422 0.006744143 0.005891590 0.012816470 0.005351586
## 101 106 131 134 151 155
## 0.007526751 0.014479871 0.007229339 0.007552819 0.010883937 0.007207682
## 161 189 190 204 205 206
## 0.020335483 0.004893297 0.005366557 0.014490604 0.005351634 0.009476652
## 220 294 305 310 312 315
## 0.007393997 0.005912765 0.005442061 0.028812123 0.013169272 0.005385800
## 378 440 442 445 486 492
## 0.015934061 0.005404736 0.007723662 0.007509382 0.005164446 0.008274018
## 497 516 582 587 592 614
## 0.005166306 0.013079851 0.011665555 0.008412325 0.006384116 0.005299262
## 638 656 657 684 697 702
## 0.006688287 0.005927777 0.005322685 0.008818987 0.005863826 0.005202259
## 729 748 750 757 765 805
## 0.005023115 0.008565543 0.006942097 0.008145491 0.006070298 0.014356657
## 828 893 895 913 928 946
## 0.007179817 0.005075205 0.005295896 0.005571144 0.022742332 0.006909044
## 947 956 985 1008 1014 1049
## 0.008409465 0.007784123 0.007039416 0.005343037 0.008470133 0.004956169
## 1067 1091 1106 1130 1166 1181
## 0.008465430 0.008933360 0.005967317 0.031728597 0.005513559 0.005677676
## 1188 1200 1219 1238 1248 1273
## 0.006477203 0.005492370 0.030694311 0.005908078 0.014622914 0.007085831
## 1291 1293 1311 1321 1325 1356
## 0.006117497 0.006073639 0.009625908 0.009293111 0.004857169 0.005303442
## 1357 1385 1395 1400 1402 1411
## 0.006965051 0.012636943 0.005126697 0.005925069 0.004811441 0.008048184
## 1420 1428 1429 1450 1505 1551
## 0.005155654 0.008192811 0.021757172 0.015104831 0.013330439 0.048769569
## 1553 1556 1573 1593 1606 1610
## 0.008504889 0.005919673 0.005047204 0.005623758 0.005001812 0.008722184
## 1617 1619 1628 1686 1693 1701
## 0.004866796 0.015067498 0.005069731 0.009349313 0.005077858 0.010842957
## 1712 1718 1727 1735 1780 1781
## 0.006992084 0.006958857 0.013300523 0.004884846 0.025538678 0.016832361
## 1809 1827 1868 1892 1962 1967
## 0.008707504 0.006065698 0.005205637 0.005332812 0.005540442 0.005337356
## 1977 2037 2040 2046 2086 2089
## 0.006927281 0.004889127 0.011494872 0.005471670 0.013193090 0.006293550
## 2098 2114 2115 2120 2140 2146
## 0.005094455 0.013316875 0.011772090 0.018659995 0.006244232 0.005802168
## 2148 2149 2157 2175 2200 2215
## 0.007926839 0.013583436 0.005907225 0.032527273 0.011670024 0.004892265
## 2216 2220 2221 2224 2225 2244
## 0.008117864 0.005414040 0.021628717 0.005838076 0.005591261 0.006929217
## 2257 2307 2317 2318 2337 2359
## 0.006170254 0.013965608 0.007673614 0.004831118 0.005230450 0.010067364
## 2408 2422 2436 2437 2452 2458
## 0.009696691 0.021532808 0.004986522 0.023943328 0.023838489 0.008506087
## 2471 2478
## 0.020903740 0.005775173
Queste sono le osservazioni che si trovano lontano dalla soglia dei regressori.
Vediamo gli outliers:
plot(rstudent(mod4))
abline(h=c(-2,2),col=2)
Anche qui gli outliers sono parecchi, ma andiamo a verificare con un
test t quali sono gli effettivi outliers presenti nel modello:
car::outlierTest(mod4)
## rstudent unadjusted p-value Bonferroni p
## 1551 10.051908 2.4906e-23 6.2265e-20
## 155 5.027798 5.3138e-07 1.3285e-03
## 1306 4.827238 1.4681e-06 3.6702e-03
Con questo test si evidenzia che gli effettivi outliers sono soltanto 3 perchè gli altri non sono considerati eccessivamente lontani dal resto della nuvola di punti.
Verifichiamo la distanza di cook
cook <- cooks.distance(mod4)
plot(cook, main = "Distanza di Cook", type = "h", ylab = "Distanza di Cook")
abline(h = 1, col = "red", lty = 2)
Il grafico mostra un valore massimo della distanza di 0.8
kable(max(cook))
| x |
|---|
| 0.8300965 |
Il valore max mostra un valore di 0.83 che come abbiamo visto sopra supera la soglia di allarme ma non quella di pericolo per poter essere considerato un valore influente per la bontà del modello.
Altri test:
library(lmtest)
## Caricamento del pacchetto richiesto: zoo
##
## Caricamento pacchetto: 'zoo'
## I seguenti oggetti sono mascherati da 'package:base':
##
## as.Date, as.Date.numeric
SUMMARY.RESIDUALS <- data.frame(
"Breusch-Pagan test" = sprintf("%.3e", unname(bptest(mod4)$p.value)),
"Durbin-Watson test" = sprintf("%.3e", unname(dwtest(mod4)$p.value)),
"Shapiro-Wilk normality test" = sprintf("%.3e", unname(shapiro.test(residuals(mod4))$p.value)),
check.names = FALSE
)
kable(SUMMARY.RESIDUALS)
| Breusch-Pagan test | Durbin-Watson test | Shapiro-Wilk normality test |
|---|---|---|
| 5.946e-18 | 1.224e-01 | 6.782e-21 |
I test statistici sui residui indicano:
plot(density(residuals(mod4)))
anche se i test statistici sembrano suggerire un andamento non normale
dei residui, la rappresentazione grafica si avvicina moltissimo a una
normale, quindi non mi sento di bocciare il modello 4 nell’utilizzarlo
per le previsioni.
Lunghezza.media <- mean(neonati$Lunghezza, na.rm = TRUE)
Cranio.media <- mean(neonati$Cranio, na.rm = TRUE)
predict(mod4
, newdata = data.frame(N.gravidanze = 3
, Fumatrici = 0
, Gestazione = 39
, Lunghezza = Lunghezza.media
, Cranio = Cranio.media
, Sesso = "M"
)
,interval = "confidence" )
## fit lwr upr
## 1 3349.083 3326.274 3371.892
Coi parametri forniti possiamo fare due stime, la prima è nel caso il bambino sia un maschio. In questo caso la previsione del Peso sarebbe intorno ai 3Kg e 350g.
predict(mod4
, newdata = data.frame(N.gravidanze = 3
, Fumatrici = 0
, Gestazione = 39
, Lunghezza = Lunghezza.media
, Cranio = Cranio.media
, Sesso = "F"
)
,interval = "confidence" )
## fit lwr upr
## 1 3271.09 3247.763 3294.416
Nel caso di una bambino Femmina la previsione del Peso sarebbe intorno ai 3Kg e 270g.
library(ggplot2)
ggplot(data=neonati)+
geom_point( aes( x=Gestazione, y=Peso, col=Sesso ), position = "jitter" )+
geom_smooth( aes( x=Gestazione, y=Peso, col=Sesso ), se=F, method = "lm", formula=y ~ poly(x, 2) )+
geom_smooth( aes( x=Gestazione, y=Peso, col="Aggregato" ), se=F, method = "lm", formula=y ~ poly(x, 2) )
Il numero di settimane di “Grestazione” ha un impatto positivo sul peso del neonato per entrambi i sessi.
library(ggplot2)
ggplot(data=neonati)+
geom_point( aes( x=Fumatrici, y=Peso, col=Sesso ), position = "jitter" )+
geom_smooth( aes( x=Fumatrici, y=Peso, col=Sesso ), se=F, method = "lm", formula=y ~ x )+
geom_smooth( aes( x=Fumatrici, y=Peso, col="Aggregato" ), se=F, method = "lm", formula=y ~ x )
La maggior parte delle osservazioni in questo dataset contiene informazioni di madri non fumatrici. Interpretando questo grafico mi viene da supporre che l’essere una fumatrice non ha un impatto significativo sul Peso del neonato per entrambi i sessi.
library(ggplot2)
ggplot(data=neonati)+
geom_point( aes( x=N.gravidanze, y=Peso, col=Sesso ), position = "jitter" )+
geom_smooth( aes( x=N.gravidanze, y=Peso, col=Sesso ), se=F, method = "lm", formula=y ~ x )+
geom_smooth( aes( x=N.gravidanze, y=Peso, col="Aggregato" ), se=F, method = "lm", formula=y ~ x )
Leggendo il grafico da sx a dx, la nuvola di punti sembra formare un triangolo, questo fa supporre che con l’aumentare delle gravidanze il peso del neonato non riesca ad arrivare ai 3kg. Quindi si il numero di gravidanze ha un impatto sul Peso del neonato per entrambi i sessi.