lm, en particulier les tests et le coefficient de détermination.library(tidyverse)
data <- readr::read_delim(
here::here("data", "ozone_simple.txt"), delim = ";",
col_types = c(col_double(), col_double())
)
ozone_simple.txt et ajuster un modèle linéaire expliquant \(O3\) à l’aide de \(T12\).Avant tout, on trace les données pour vérifier qu’il n’y ait pas des valeurs aberrantes.
df <- data.frame(data)
n <- nrow(df)
tibble(df) %>%
ggplot(mapping = aes(x = O3)) +
geom_histogram(
aes(y = stat(density)),
bins = 10,
colour = "black", fill = "white"
) +
geom_density(alpha = .2, fill = "blue")
tibble(df) %>%
ggplot(mapping = aes(x = T12)) +
geom_histogram(
aes(y = stat(density)),
bins = 10,
colour = "black", fill = "white"
) +
geom_density(alpha = .2, fill = "blue")
tibble(df) %>%
ggplot(mapping = aes(x = T12, y = O3)) +
geom_point()
summary(df)
## O3 T12
## Min. : 41.8 Min. : 7.90
## 1st Qu.: 66.6 1st Qu.:17.40
## Median : 83.9 Median :19.75
## Mean : 86.3 Mean :20.32
## 3rd Qu.:102.2 3rd Qu.:24.32
## Max. :139.0 Max. :29.50
var(df$O3)
## [1] 571.2494
var(df$T12)
## [1] 21.85224
Nous modélisons \(O3_i = \beta_1 + \beta_2T12_i + \varepsilon_i\)
reg <- lm(O3 ~ T12, data = df)
summary(reg)
##
## Call:
## lm(formula = O3 ~ T12, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -45.256 -15.326 -3.461 17.634 40.072
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 31.4150 13.0584 2.406 0.02 *
## T12 2.7010 0.6266 4.311 8.04e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 20.5 on 48 degrees of freedom
## Multiple R-squared: 0.2791, Adjusted R-squared: 0.2641
## F-statistic: 18.58 on 1 and 48 DF, p-value: 8.041e-05
Les coefficients \(\beta_1\) et \(\beta_2\) sont significatifs au seuil de significativité \(\alpha = 5\%\), avec une \(p\)-value respective de \(0.02\) et \(8.04\times10^{-5}\). Le coefficient de détermination \(\mathfrak{R}^2 = 0.2791\). Cela veut dire que le modèle estimé n’est peut-être pas complet.
confint.hat_beta1 <- reg$coefficients[1]
hat_beta2 <- reg$coefficients[2]
hat_sigma2 <- summary(reg)[["sigma"]]^2
var_beta1 <- (hat_sigma2/n) * ((sum(df$T12^2) / n) / (sum((df$T12 - mean(df$T12))^2) /n ))
var_beta2 <- (hat_sigma2/n) * (1 / (sum((df$T12 - mean(df$T12))^2) / n))
alpha <- 0.05
t.val <- qt(1 - alpha/2, n - 2)
IC1 <- c(hat_beta1 - t.val * sqrt(var_beta1), reg$coefficients[1] + t.val * sqrt(var_beta1))
IC2 <- c(hat_beta2 - t.val * sqrt(var_beta2), reg$coefficients[2] + t.val * sqrt(var_beta2))
n.ic.s2 <- (n - 2) * hat_sigma2
d.ic.low <- qchisq(1 - alpha/2, df = n-2)
d.ic.up <- qchisq(alpha/2, df = n-2)
IC3 <- n.ic.s2 * c(1/d.ic.low, 1/d.ic.up)
IC.confint <- confint(reg, level = 0.95)
| Paramètre | Borne Inférieure | Borne Supérieure |
|---|---|---|
| \(\beta_{1}\) | 5.1592319 | 57.6707146 |
| \(\beta_{2}\) | 1.4411798 | 3.9608898 |
| \(\sigma^2\) | 292.3593056 | 656.1443531 |
Les intervalles de confiance calculés à partir des formules discutées en cours sont égaux à ceux obtenus à l’aide de la fonction confint. À partir des intervalles de confiance à \(95\%\), nous remarquons que ceux associés aux coefficients \(\beta\) ne comprennent pas zéro. Cela n’est pas étonnant puisque nous avons vu précédemment que ces coefficients étaient significatifs. Cependant, \(\beta_1\) montre une grande variabilité ce qui est expliqué par l’ordre de magnitude des résidus.
predict. Commenter.plot(O3 ~ T12, data = df, ylim = c(min(df$O3), max(df$O3)))
seq.x <- seq(min(df$T12), max(df$T12), length=3*n)
grid.x <- data.frame(seq.x)
dimnames(grid.x)[[2]] <- "T12"
ICconf <- predict(reg, new=grid.x, interval="confidence", level=0.95)
ICprev <- predict(reg, new=grid.x, interval="prediction", level=0.95)
matlines(
grid.x, cbind(ICconf,ICprev[,-1]),
lty=c(1,2,2,3,3), col= c(1, 2, 2, 3, 3)
)
legend(
"topleft", lty = 1:3,
c("Régression","Int. confiance", "Int. prevision")
)
L’écart des points par rapport à la ligne de régression est en accord avec la discussion précédente sur les résidus et la variance. Les intervalles des prévision sont toujours plus amples que ceux de confiance. Ceci est interprétable comme suit : Les intervalles de confiance concernent l’espérance de la concentration \(O3\), pour une température \(T12\) donnée, alors que les intervalles de prévision essaient de prendre en compte toute concentration possible dans le seuil fixé.
| Paramètre | \(H_{0}\) | \(H_{1}\) |
|---|---|---|
| \(\beta_{1}\) | \(\beta_{1} = 0\) | \(\beta_{1} \ne 0\) |
| \(\beta_{2}\) | \(\beta_{2} = 0\) | \(\beta_{2} \ne 0\) |
t.val <- qt(0.975, n - 2)
Test1 <- hat_beta1[[1]] / sqrt(var_beta1)
Test1 > t.val
## [1] TRUE
Le coefficient \(\beta_{2}\) est significatif au seuil de \(\alpha = 0.05\).
Test2 <- hat_beta2[[1]] / sqrt(var_beta2)
Test2 > t.val
## [1] TRUE
Le coefficient \(\beta_{1}\) est significatif au seuil de \(\alpha = 0.05\).
Pour les deux paramètres, on rejette l’hypothèse nulle.
Les valeurs sont \(T1 =\frac{\hat{\beta}_1}{\hat{\sigma}_{\beta_1}} =\) 2.4057229 et \(T2 =\frac{\hat{\beta}_2}{\hat{\sigma}_{\beta_2}} =\) 4.3106503.
| \(H_{0}\) | \(Y_{i} = \beta_1 + \varepsilon_i\) est vrai |
| \(H_{1}\) | \(Y_{i} = \beta_1 + \beta_2 x_{i} + \varepsilon_i\) est vrai |
SCR <- sum(residuals(reg)^2)
SCM <- sum((fitted(reg) - mean(df$O3))^2)
SCT <- sum((df$O3 - mean(df$O3))^2)
r2.hat <- SCM /SCT
F.hat <- (SCM / 1) / (SCR / (n - 2))
f.test <- qf(0.95, 1, n - 2)
F.hat > f.test
## [1] TRUE
La valeur estimé du test Fisher est \(\mathcal{F}_{0.95}(1, 48) =\) 18.5817059. On rejette \(H_{0}\) : Le modèle \(Y_{i} = \beta_1 + \beta_2 x_{i} + \varepsilon_i\) explique mieux la relation entre la concentration d’ozone et la température que \(Y_{i} = \beta_1 + \varepsilon_i\).
lm.Les résidus ne semblent pas suivre une loi normale d’après le qqplot puisque les queues de la densité des résidus standardardisés sont plus faibles que celles de la loi normale \(\mathcal{N}(0, 1)\).
L’hypothèse d’homoscedasticité ne semble pas être vérifiée car les \(\hat{\epsilon}_{i}\) n’ont pas tous la même variance. En effet, \(\epsilon_{1}, \cdots, \epsilon_{n}\) dépend de \(x_{1}, \cdots, x_{n}\) \(\rightarrow\) hétéroscedasticité.
hat_sigma <- sqrt(hat_sigma2)
residus <- tibble(
n = 1:50,
residus = reg$residuals,
T12 = df$T12,
O3 = df$O3,
e.standardized = reg$residuals / hat_sigma,
adjusted = predict(reg)
)
residus %>%
ggplot(mapping = aes(sample = e.standardized)) +
stat_qq() +
stat_qq_line()
residus %>%
ggplot(mapping = aes(x = T12, y = e.standardized)) +
geom_point() +
geom_smooth() +
ggtitle("epsilon ~ temperature")
residus %>%
ggplot(mapping = aes(x = O3, y = e.standardized)) +
geom_point() +
geom_smooth() +
ggtitle("epsilon ~ O3")
residus %>%
ggplot(mapping = aes(x = e.standardized)) +
geom_histogram(
aes(y = stat(density)),
bins = 10,
colour = "black", fill = "white"
) +
geom_density(alpha = .2, fill = "blue") +
geom_vline(xintercept = 2, colour="red") +
geom_vline(xintercept = -2, colour="red")
residus %>% filter( abs(e.standardized) > 2)
On ne peut pas conclure qu’il y a des valeurs aberrantes à partir de ce graphique. En effet, si l’on filtre les erreurs standardisées dont la valeur absolue est supérieure à 2, on constate qu’il s’agit d’une seule observation \(\hat{\epsilon}/\sigma = -2.20\) qui est plausible.
D’après le graphique \(\left(x_i,\hat{\varepsilon}_i\right)\), nous remarquons une rupture entre les températures inférieures et supérieures à 20-22 dégrés. Nous pouvons donc proposer deux modèles univariés: modèle (1) \(O3_{i} = \beta_1^\star + \beta_2^\star \times T12_i + \varepsilon_i \quad \forall\; T_i < 21\) et modèle (2) \(O3_{i} = \beta_1^\ast + \beta_2^\ast \times T12_i + \varepsilon_i \quad \forall\; T_i > 21\).
reg1 <- lm(O3 ~ T12, data = df[df$T12<21,])
summary(reg1)
##
## Call:
## lm(formula = O3 ~ T12, data = df[df$T12 < 21, ])
##
## Residuals:
## Min 1Q Median 3Q Max
## -28.661 -11.422 -1.862 13.147 31.950
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 103.192 18.112 5.698 4.14e-06 ***
## T12 -1.589 1.035 -1.535 0.136
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 16.54 on 28 degrees of freedom
## Multiple R-squared: 0.07765, Adjusted R-squared: 0.04471
## F-statistic: 2.357 on 1 and 28 DF, p-value: 0.1359
reg2 <- lm(O3 ~ T12, data = df[df$T12>21,])
summary(reg2)
##
## Call:
## lm(formula = O3 ~ T12, data = df[df$T12 > 21, ])
##
## Residuals:
## Min 1Q Median 3Q Max
## -26.103 -12.500 -3.174 9.842 31.458
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -87.176 41.529 -2.099 0.051042 .
## T12 7.612 1.647 4.623 0.000243 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 16.09 on 17 degrees of freedom
## Multiple R-squared: 0.5569, Adjusted R-squared: 0.5309
## F-statistic: 21.37 on 1 and 17 DF, p-value: 0.000243
Dans le modèle (1), nous remarquons que le coefficient \(\beta_2^\star\) n’est pas significatif. En effet, la \(p-\text{value}\) est de \(0.136\) donc il n’y a pas de significativité même au seuil de \(\alpha = 10\%\). Concernant le modèle (2), le coefficient \(\beta_2^\ast\) est très significatif avec une \(p-\text{value} \approx 0\). Nous remarquons également un coefficient de détermination \(\mathfrak{R}^2 = 0.56\). Ce coefficient est très supérieur au coefficient \(\mathfrak{R}^2 = 0.28\) obtenu à la question (1). En revanche, le coefficient de détermination est très faible dans le modèle (1) car la concentration en \(O3\) n’est pas significativement expliquée par la température en deçà de 21 degrés celsius.
reg3 <- lm(O3 ~ 1, data = df[df$T12<21,])
summary(reg3)
##
## Call:
## lm(formula = O3 ~ 1, data = df[df$T12 < 21, ])
##
## Residuals:
## Min 1Q Median 3Q Max
## -33.973 -12.623 0.227 12.677 30.827
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 75.773 3.089 24.53 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 16.92 on 29 degrees of freedom
df.mod1 <- df[df$T12 < 21, ]
df.mod2 <- df[df$T12 > 21, ]
tibble(df.mod1) %>%
ggplot(mapping = aes(x = T12, y = O3)) +
geom_point() +
geom_abline(
slope = reg1$coefficients[["T12"]],
intercept = reg1$coefficients[["(Intercept)"]],
colour = "blue",
) +
geom_abline(
slope = 0,
intercept = reg3$coefficients[["(Intercept)"]],
colour = "red"
) +
ggtitle("Modele T12 < 21, bleu : avec Beta2, rouge sans Beta2")
tibble(df.mod2) %>%
ggplot(mapping = aes(x = T12, y = O3)) +
geom_point() +
geom_abline(
slope = reg2$coefficients[["T12"]],
intercept = reg2$coefficients[["(Intercept)"]],
colour = "green"
) +
ggtitle("Modele T12 > 21")