Regressione Lineare in R
La regressione lineare e uno dei metodi statistici piu importanti e utilizzati. Permette di modellare la relazione tra una variabile dipendente (risposta) e una o piu variabili indipendenti (predittori). In R, la funzione lm() (linear model) rende la costruzione e lâanalisi dei modelli di regressione estremamente semplice e potente.
La Formula in R
In R, i modelli statistici si specificano tramite una formula con la sintassi y ~ x, dove y e la variabile risposta e x il predittore. Lâoperatore ~ si legge âe modellata daâ.
# Sintassi base
# y ~ x regressione semplice
# y ~ x1 + x2 regressione multipla
# y ~ x1 * x2 con interazione (equivale a x1 + x2 + x1:x2)
# y ~ . tutte le variabili del data frame come predittori
Regressione Lineare Semplice
Iniziamo con un esempio pratico: la relazione tra ore di studio e voto allâesame.
# Dataset: ore di studio e voto ottenuto
studenti <- data.frame(
ore_studio = c(5, 8, 10, 12, 15, 18, 20, 22, 25, 30,
6, 11, 14, 17, 21, 24, 28, 9, 16, 23),
voto = c(18, 20, 22, 23, 25, 26, 27, 28, 29, 30,
19, 22, 24, 26, 27, 28, 30, 21, 25, 29)
)
# Costruire il modello di regressione lineare
modello <- lm(voto ~ ore_studio, data = studenti)
Interpretare i Risultati con summary()
La funzione summary() fornisce un riepilogo completo del modello:
summary(modello)
# Call:
# lm(formula = voto ~ ore_studio, data = studenti)
#
# Residuals:
# Min 1Q Median 3Q Max
# -1.35521 -0.54498 -0.03254 0.51858 1.55339
#
# Coefficients:
# Estimate Std. Error t value Pr(>|t|)
# (Intercept) 16.49543 0.40388 40.84 <2e-16 ***
# ore_studio 0.47244 0.02255 20.95 <2e-16 ***
# ---
# Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#
# Residual standard error: 0.7847 on 18 degrees of freedom
# Multiple R-squared: 0.9606, Adjusted R-squared: 0.9585
# F-statistic: 438.8 on 1 and 18 DF, p-value: < 2.2e-16
Come Leggere lâOutput
Ogni sezione dellâoutput contiene informazioni cruciali:
Coefficients (Coefficienti):
- Intercept (16.50): il voto atteso quando le ore di studio sono 0. E il punto in cui la retta interseca lâasse Y
- ore_studio (0.47): per ogni ora aggiuntiva di studio, il voto aumenta in media di 0.47 punti
- Pr(>|t|): il p-value di ogni coefficiente. I tre asterischi (
***) indicano significativita altissima (p < 0.001)
R-squared (R quadro):
- Multiple R-squared (0.9606): il modello spiega il 96% della variabilita nei voti. Valori vicini a 1 indicano un buon adattamento
- Adjusted R-squared (0.9585): R quadro corretto per il numero di predittori, utile per confrontare modelli con numero diverso di variabili
F-statistic: testa se il modello nel suo complesso e significativo. Un p-value < 0.05 indica che almeno un predittore ha un effetto significativo.
Estrarre Singoli Elementi
# Coefficienti
coef(modello)
# (Intercept) ore_studio
# 16.4954301 0.4724366
# R quadro
summary(modello)$r.squared
# [1] 0.9606259
# R quadro aggiustato
summary(modello)$adj.r.squared
# [1] 0.9584385
# Residui
residuals(modello)
# (oppure modello$residuals)
# Valori predetti (fitted values)
fitted(modello)
# (oppure modello$fitted.values)
Intervalli di Confidenza: confint()
La funzione confint() calcola gli intervalli di confidenza per i coefficienti del modello:
# Intervalli di confidenza al 95%
confint(modello)
# 2.5 % 97.5 %
# (Intercept) 15.64688 17.34398
# ore_studio 0.42506 0.51982
# Intervalli di confidenza al 99%
confint(modello, level = 0.99)
# 0.5 % 99.5 %
# (Intercept) 15.31447 17.67639
# ore_studio 0.40736 0.53751
Lâintervallo al 95% per ore_studio e [0.425, 0.520]: siamo al 95% confidenti che il vero effetto di unâora aggiuntiva di studio sul voto sia compreso tra 0.43 e 0.52 punti.
Previsioni con predict()
La funzione predict() permette di fare previsioni per nuove osservazioni:
# Prevedere il voto per studenti che studiano 13 e 27 ore
nuovi_dati <- data.frame(ore_studio = c(13, 27))
# Previsione puntuale
predict(modello, newdata = nuovi_dati)
# 1 2
# 22.63712 29.25122
# Previsione con intervallo di confidenza (per la media)
predict(modello, newdata = nuovi_dati, interval = "confidence")
# fit lwr upr
# 1 22.63712 22.24622 23.02802
# 2 29.25122 28.80017 29.70226
# Previsione con intervallo di previsione (per singola osservazione)
predict(modello, newdata = nuovi_dati, interval = "prediction")
# fit lwr upr
# 1 22.63712 20.92310 24.35114
# 2 29.25122 27.48498 31.01745
Lâintervallo di confidenza stima dove si trova la media della risposta, mentre lâintervallo di previsione stima dove cadra una singola osservazione futura. Lâintervallo di previsione e sempre piu ampio perche include lâincertezza aggiuntiva della variabilita individuale.
Regressione Lineare Multipla
La regressione multipla include piu variabili predittive nel modello.
# Dataset ampliato con piu variabili
set.seed(42)
n <- 30
dati <- data.frame(
ore_studio = round(runif(n, 5, 30)),
ore_sonno = round(runif(n, 4, 9), 1),
frequenza = round(runif(n, 50, 100))
)
# Variabile risposta simulata
dati$voto <- round(16 + 0.35 * dati$ore_studio + 0.8 * dati$ore_sonno +
0.05 * dati$frequenza + rnorm(n, 0, 1.5))
# Modello di regressione multipla
modello_mult <- lm(voto ~ ore_studio + ore_sonno + frequenza, data = dati)
summary(modello_mult)
# Coefficients:
# Estimate Std. Error t value Pr(>|t|)
# (Intercept) 15.38826 2.05424 7.491 5.84e-08 ***
# ore_studio 0.36401 0.03396 10.718 2.11e-11 ***
# ore_sonno 0.87956 0.25117 3.502 0.00167 **
# frequenza 0.04117 0.01764 2.334 0.02759 *
# ---
# Multiple R-squared: 0.8478, Adjusted R-squared: 0.8303
# F-statistic: 48.31 on 3 and 26 DF, p-value: 3.198e-11
Tutti e tre i predittori sono significativi. LâR quadro aggiustato di 0.83 indica che il modello spiega lâ83% della variabilita nei voti.
ANOVA per il Modello: anova()
La funzione anova() esegue unâanalisi della varianza per valutare il contributo di ciascun predittore:
anova(modello_mult)
# Analysis of Variance Table
#
# Response: voto
# Df Sum Sq Mean Sq F value Pr(>F)
# ore_studio 1 275.42 275.42 117.2371 1.204e-11 ***
# ore_sonno 1 26.78 26.78 11.3979 0.002311 **
# frequenza 1 12.80 12.80 5.4497 0.027590 *
# Residuals 26 61.10 2.35
LâANOVA mostra che ore_studio contribuisce con la quota maggiore di varianza spiegata (275.42), seguito da ore_sonno (26.78) e frequenza (12.80).
Confrontare Modelli con anova()
Si puo anche usare anova() per confrontare un modello ridotto con uno completo:
# Modello ridotto (solo ore_studio)
modello_ridotto <- lm(voto ~ ore_studio, data = dati)
# Confronto tra i due modelli
anova(modello_ridotto, modello_mult)
# Analysis of Variance Table
#
# Model 1: voto ~ ore_studio
# Model 2: voto ~ ore_studio + ore_sonno + frequenza
# Res.Df RSS Df Sum of Sq F Pr(>F)
# 1 28 100.672
# 2 26 61.097 2 39.575 8.4217 0.001544 **
Il p-value di 0.0015 indica che il modello completo e significativamente migliore di quello con solo ore_studio.
Assunzioni della Regressione
La regressione lineare si basa su quattro assunzioni fondamentali che devono essere verificate:
- Linearita: la relazione tra predittori e risposta e lineare
- Indipendenza: i residui sono indipendenti tra loro
- Omoschedasticita: la varianza dei residui e costante
- Normalita dei residui: i residui seguono una distribuzione normale
Diagnostic Plots
R offre quattro grafici diagnostici fondamentali accessibili con plot():
# Generare i 4 grafici diagnostici
par(mfrow = c(2, 2))
plot(modello)
par(mfrow = c(1, 1))
Interpretazione dei Grafici
1. Residuals vs Fitted (Residui vs Valori predetti): Verifica linearita e omoschedasticita. I punti devono distribuirsi casualmente attorno alla linea orizzontale a zero, senza pattern evidenti.
# Residui vs valori predetti
plot(modello, which = 1)
# Se si osserva una curva: la relazione non e lineare
# Se si osserva un imbuto: la varianza non e costante (eteroschedasticita)
2. Normal Q-Q Plot (Grafico quantile-quantile): Verifica la normalita dei residui. I punti devono cadere approssimativamente sulla linea diagonale.
plot(modello, which = 2)
# Deviazioni agli estremi indicano code pesanti o leggere
3. Scale-Location (Scala-Posizione): Verifica lâomoschedasticita. La linea rossa deve essere approssimativamente orizzontale e i punti uniformemente distribuiti.
plot(modello, which = 3)
4. Residuals vs Leverage (Residui vs Leva): Identifica osservazioni influenti. I punti oltre le linee tratteggiate della distanza di Cook sono potenziali outlier influenti.
plot(modello, which = 5)
# Osservazioni con distanza di Cook > 0.5 meritano attenzione
Verificare le Assunzioni con Test Formali
# Test di normalita dei residui
shapiro.test(residuals(modello))
# p-value > 0.05 -> i residui sono normali
# Test di omoschedasticita (richiede il pacchetto lmtest)
# install.packages("lmtest")
# library(lmtest)
# bptest(modello) # Test di Breusch-Pagan
Esempio Completo: Analisi di Regressione
Vediamo un esempio end-to-end che integra tutti i concetti:
# Dataset: prezzo case in base a caratteristiche
set.seed(2024)
n <- 50
case <- data.frame(
superficie = round(runif(n, 40, 200)),
stanze = sample(2:6, n, replace = TRUE),
distanza_centro = round(runif(n, 0.5, 15), 1)
)
case$prezzo <- round(50000 + 1500 * case$superficie + 8000 * case$stanze -
3000 * case$distanza_centro + rnorm(n, 0, 15000))
# 1. Costruire il modello
modello_case <- lm(prezzo ~ superficie + stanze + distanza_centro, data = case)
# 2. Riepilogo
summary(modello_case)
# 3. Intervalli di confidenza
confint(modello_case)
# 4. ANOVA
anova(modello_case)
# 5. Diagnostica
par(mfrow = c(2, 2))
plot(modello_case)
par(mfrow = c(1, 1))
# 6. Previsione per una nuova casa
nuova_casa <- data.frame(
superficie = 90,
stanze = 3,
distanza_centro = 5
)
predict(modello_case, newdata = nuova_casa, interval = "prediction")
# fit lwr upr
# 1 204890.3 174201.7 235578.9
Il modello stima un prezzo di circa 205.000 euro per un appartamento di 90 mq con 3 stanze a 5 km dal centro, con un intervallo di previsione tra 174.000 e 236.000 euro.
Conclusione
La regressione lineare in R e uno strumento fondamentale per lâanalisi dei dati. La funzione lm() costruisce il modello, summary() ne fornisce lâinterpretazione completa con R quadro e p-value, predict() genera previsioni con intervalli di confidenza, e confint() quantifica lâincertezza sui coefficienti. Lâuso di anova() permette di valutare il contributo di ciascun predittore e confrontare modelli alternativi. Infine, la verifica delle assunzioni tramite i grafici diagnostici e il test di Shapiro-Wilk e un passaggio irrinunciabile per garantire la validita delle conclusioni. Padroneggiare la regressione lineare e il punto di partenza per affrontare modelli statistici piu avanzati come la regressione logistica, i modelli misti e il machine learning.