Exercices autour du CM 3 (Modèles linéaires gaussiennes) SB & RR 28 septembre 2015 Contents 1 Données synthétiques 1 1.1 Traitement des données synthétiques à la main . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2 Traitement des données synthétiques à l’aide de lm . . . . . . . . . . . . . . . . . . . . . . . . 2 1.3 Comparaison des régions de confiance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.4 Estimation de la variance du bruit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 Sélection de modèles (données synthétiques) 3 3 Données whiteside 4 1 3.1 Séparation des données en deux sous-échantillons, régression linéaire sur les deux sous-échantillons. 5 3.2 Faire réaliser l’approche split-apply-combine par lm mais en créant les variables de contraste à la main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.3 Test d’hypothèses associé. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.4 Variantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.5 Visualiser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.6 Les outils de diagnostic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.7 Elimination de quelques points suspects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Données synthétiques On veut d’abord travailler sur un problème de régression gaussienne dont on aura choisi la matrice de design “au hasard” en effectuant des tirages gaussiens. n <- 100 p <- 10 sigma <- 1 Créer une matrice Z de dimensions n × p. Z <- matrix(rnorm(n*p), ncol=p) On pourra étudier la décomposition spectrale de Z t Z à l’aide de eigen ou appliquer à Z la fonction svd. Choisir θ et engendrer le bruit. On choisit θ au hasard en effectuant des tirages exponentiels. 1 theta <- rexp(p) eps <- rnorm(n) Y <- Z %*% theta + eps 1.1 Traitement des données synthétiques à la main Estimation par la méthode des moindres carrés. Utiliser (par exemple) la fonction solve. #thetahat <- .... # #Yhat <- ... # predictions #residuals <- ... # residus cov(residuals,Yhat) Spectre de Z t Z. Calcul de Residual Sum of Squares Visualiser prédictions Yhat contre valeurs de Y 1.2 Traitement des données synthétiques à l’aide de lm On essaye maintenant de traiter les données synthétiques à l’aide de la fonction lm. Pour cela il faut d’abord mettre les données synthétiques sous forme de data.frame. On crée un data.frame avec n lignes et p + 1 colonnes (les p variables explicatives et la variable à expliquer). df <- as.data.frame(cbind(Y,Z)) names(df) <- c("Y", plyr::aaply(.data=1:10,.margin=1, .fun= function(n) paste("x",n,sep=""))) On peut maintenant évoquer lm. Essayer deux formulae : Y ~ . -1 et Y ~ .. Quelles différences ? #lm0 <- ... #summary(lm0) Visualiser à nouveau résidus contre prédictions (on les retrouve comme attributs de “lm0) #ggplot2::qplot(...) 1.3 Comparaison des régions de confiance Lorsque la variance du buit homoscédastique est connue, l’ellipsoïde de confiance est construit à partir des quantiles de la loi du χ2 . Lorsque la variance n’est pas connue, l’ellipsoïde de confiance est construit à partir des quantiles de la loi de Fischer. 1.4 Estimation de la variance du bruit Estimation de σ. 2 # sigmahat2 <- ... Region de confiance pour σ 2 et pour les prédictions alpha <- .05 # sum((Y-Yhat)^2)*c(1/qchisq(1-alpha/2,df = n-p),1/qchisq(alpha/2,df=n-p)) 2 Sélection de modèles (données synthétiques) On construit maintenant un paramètre en imposant la nullité de quelques colonnes 1, . . . , k k <- 5 theta <- c(rep(0,5),rexp(p-k)) Y <- Z %*% theta + eps df <- as.data.frame(cbind(Y,Z)) names(df) <- c("Y", plyr::aaply(.data=1:10,.margin=1, .fun= function(n) paste("x",n,sep=""))) lm10 <- lm(formula = Y ~ ., data = df) summary(lm10) ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## Call: lm(formula = Y ~ ., data = df) Residuals: Min 1Q -1.91945 -0.62654 Median 0.05619 3Q 0.60252 Max 2.40351 Coefficients: Estimate Std. Error t value (Intercept) 0.22026 0.10694 2.060 x1 0.18977 0.09776 1.941 x2 -0.13897 0.11003 -1.263 x3 -0.14603 0.09993 -1.461 x4 -0.11199 0.09255 -1.210 x5 -0.05328 0.10720 -0.497 x6 0.20529 0.10215 2.010 x7 0.72875 0.11237 6.485 x8 0.59010 0.10646 5.543 x9 3.47499 0.09708 35.793 x10 1.47221 0.08392 17.544 --Signif. codes: 0 '***' 0.001 '**' 0.01 Pr(>|t|) 0.0424 0.0554 0.2099 0.1474 0.2295 0.6204 0.0475 4.83e-09 3.00e-07 < 2e-16 < 2e-16 * . * *** *** *** *** '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 0.9589 on 89 degrees of freedom Multiple R-squared: 0.9422, Adjusted R-squared: 0.9357 F-statistic: 145.1 on 10 and 89 DF, p-value: < 2.2e-16 3 xtable::xtable(summary(lm10)) % latex table generated in R 3.2.1 by xtable 1.7-4 package % Mon Oct 5 08:55:47 2015 (Intercept) x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 Estimate 0.2203 0.1898 -0.1390 -0.1460 -0.1120 -0.0533 0.2053 0.7288 0.5901 3.4750 1.4722 Std. Error 0.1069 0.0978 0.1100 0.0999 0.0926 0.1072 0.1022 0.1124 0.1065 0.0971 0.0839 t value 2.06 1.94 -1.26 -1.46 -1.21 -0.50 2.01 6.49 5.54 35.79 17.54 Pr(>|t|) 0.0424 0.0554 0.2099 0.1474 0.2295 0.6204 0.0475 0.0000 0.0000 0.0000 0.0000 Recalcul du modèle en imposant la nullité des premiers coefficients : quand s’arrêter ? lm_2_10 <- update(object=fit, . ~ xtable::xtable(summary(lm_2_10)) lm_3_10 <- update(object=lm_2_10, xtable::xtable(summary(lm_3_10)) lm_4_10 <- update(object=lm_3_10, xtable::xtable(summary(lm_4_10)) lm_5_10 <- update(object=lm_4_10, xtable::xtable(summary(lm_5_10)) lm_6_10 <- update(object=lm_5_10, xtable::xtable(summary(lm_6_10)) lm_7_10 <- update(object=lm_6_10, xtable::xtable(summary(lm_7_10)) lm_8_10 <- update(object=lm_7_10, xtable::xtable(summary(lm_8_10)) . - x1) . ~ . - x2) . ~ . - x3) . ~ . - x4) . ~ . - x5) . ~ . - x6) . ~ . - x7) xtable::xtable(summary(lm_8_10)) Où en sommes nous ? getCall(lm_8_10) 3 Données whiteside Les données whiteside sont issues du package MASS data(whiteside, package = 'MASS') head(whiteside) ## Insul Temp Gas ## 1 Before -0.8 7.2 ## 2 Before -0.7 6.9 4 ## ## ## ## 3 4 5 6 Before Before Before Before 0.4 2.5 2.9 3.2 6.4 6.0 5.8 5.8 ?whiteside Effectuer une régression de Gas par rapport à Temp. lm1 <- lm(data=whiteside, formula = Gas ~ Temp ) Visualiser Gas contre Temp en utilisant un code forme ou couleur pour la variable qualitative Insul . ggplot2::ggplot(data=whiteside) + ggplot2::geom_point(mapping=ggplot2::aes(...))+ ggplot2::geom_abline(intercept=...,slope=...) On observe que les points correspandant à l’hiver précédent l’isolation se situent au dessus de la droite de régression et les autres au dessous. Si on postule une dépendance linéaire entre Temp et Gas, on peut se demander si l’isolation modifie les paramètres de cette liaison. Avant de ce lancer dans l’étude de cette liaison, on peut chercher à comparer les deux hivers. xtable::xtable(dplyr::group_by(.data=whiteside,Insul) %>% dplyr::summarise(mean(Temp),sd(Temp))) % latex table generated in R 3.2.1 by xtable 1.7-4 package % Mon Oct 5 08:55:47 2015 1 2 Insul Before After mean(Temp) 5.35 4.46 sd(Temp) 2.87 2.62 Peut-on déceler l’effet du réchauffement climatique ? ggplot2::qplot(data=whiteside, y= Temp, x = Insul, geom="boxplot") L’hiver qui suit l’isolation semble plus doux que l’hiver précédent. Il n’est donc pas loyal de chercher à comparer les consommations de gaz globalement. Il faut essayer de comparer ces consommations de gaz toutes choses égales par ailleurs. 3.1 Séparation des données en deux sous-échantillons, régression linéaire sur les deux sous-échantillons. lm2 <- dplyr::filter(.data=whiteside, Insul=='Before') %>% lm(formula = Gas ~ Temp) lm3 <- dplyr::filter(.data=whiteside, Insul=='After') %>% lm(formula = Gas ~ Temp) ou alors d’une pierre deux coups . . . by(whiteside,INDICES = whiteside$Insul, FUN=lm, formula = Gas ~Temp) 5 10.0 Temp 7.5 5.0 2.5 0.0 Before After Insul Figure 1: 6 ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## whiteside$Insul: Before Call: FUN(formula = ..1, data = data[x, , drop = FALSE]) Coefficients: (Intercept) 6.8538 Temp -0.3932 -------------------------------------------------------whiteside$Insul: After Call: FUN(formula = ..1, data = data[x, , drop = FALSE]) Coefficients: (Intercept) 4.7238 Temp -0.2779 ou encore lms <- plyr::dlply(.data=whiteside, .variables = c("Insul"), .fun = lm, formula = Gas ~Temp) lms <- c(list(lm1),lms) Visualisation p <- ggplot2::ggplot(data=whiteside) + ggplot2::geom_point(mapping=ggplot2::aes(x=Temp, y=Gas, shape=Insul)) p <- p+ ggplot2::geom_abline(intercept=lm1$coefficients[1],slope=lm1$coefficients[2])+ ggplot2::geom_abline(intercept=lm2$coefficients[1],slope=lm2$coefficients[2],linetype="dotted")+ ggplot2::geom_abline(intercept=lm3$coefficients[1],slope=lm3$coefficients[2],linetype="dashed") p Il faut maintenant se demander si la complexification du modèle est justifiée. 3.2 Faire réaliser l’approche split-apply-combine par lm mais en créant les variables de contraste à la main Pour faire rentrer l’étude détaillée des données whiteside dans le cadre de la régression gaussienne vue en cours, on peut enrichir le design avec une colonne contenant des 0 pour les lignes Before et des 1 pour les lignes After, et scinder la colonne Temp en deux colonnes: une copie de la colonne Temp et une copie de la colonne Temp ou les coefficients des lignes Before sont anullés. whiteside <- cbind(whiteside, InterceptAfter= whiteside$Insul=="After", TempAfter= whiteside$Temp*(whiteside$Insul=="After")) lmfull <- lm(data=whiteside, formula = Gas ~ ...) summary(lmfull) 7 6 Gas Insul Before 4 After 2 0.0 2.5 5.0 7.5 Temp Figure 2: 8 10.0 On peut revenir au modèle de départ avec update. summary(update(lmfull, . ~ Temp)) Comportement des résidus dans les deux configurations. 3.3 Test d’hypothèses associé. • H0 : La liaison linéaire entre la consommation de gaz et la température extérieure n’est pas modifiée par l’isolation • H1 : La liaison linéaire entre la consommation de gaz et la température extérieure est modifiée par l’isolation. Il s’agit d’un test d’hypothèse linéaire. On peut calculer la statistique de Fisher. On peut confier les résultats de lm sur le modèle complet et sur le sous-modèle à la fonction anova. Celle-ci se charge de calculer la statistique de Fischer et de renvoyer un rapport. anova(lmfull,update(lmfull, . ~ Temp)) 3.4 Variantes Il n’est pas nécessaire d’ajouter à la main les variables explicatives InterceptAfter, TempAfter. R permet d’utiliser le facteur Insul pour construire un contraste. Pour cela, il faut savoir construire de bonnes formulae lors des invocations de lm. lmgood <- lm(data=whiteside, Gas ~ Insul summary(lmgood) ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## * Temp) Call: lm(formula = Gas ~ Insul * Temp, data = whiteside) Residuals: Min 1Q -0.97802 -0.18011 Median 0.03757 3Q 0.20930 Max 0.63803 Coefficients: Estimate Std. Error t value (Intercept) 6.85383 0.13596 50.409 InsulAfter -2.12998 0.18009 -11.827 Temp -0.39324 0.02249 -17.487 InsulAfter:Temp 0.11530 0.03211 3.591 --Signif. codes: 0 '***' 0.001 '**' 0.01 '*' Pr(>|t|) < 2e-16 2.32e-16 < 2e-16 0.000731 *** *** *** *** 0.05 '.' 0.1 ' ' 1 Residual standard error: 0.323 on 52 degrees of freedom Multiple R-squared: 0.9277, Adjusted R-squared: 0.9235 F-statistic: 222.3 on 3 and 52 DF, p-value: < 2.2e-16 9 lmgood %>% anova ## ## ## ## ## ## ## ## ## ## Analysis of Variance Table Response: Gas Df Sum Sq Mean Sq F value Pr(>F) Insul 1 22.348 22.348 214.198 < 2.2e-16 *** Temp 1 45.896 45.896 439.908 < 2.2e-16 *** Insul:Temp 1 1.345 1.345 12.893 0.0007307 *** Residuals 52 5.425 0.104 --Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 summary(lm(data=whiteside, Gas ~ Insul ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## Call: lm(formula = Gas ~ Insul + Temp %in% Insul, data = whiteside) Residuals: Min 1Q -0.97802 -0.18011 Median 0.03757 3Q 0.20930 Max 0.63803 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 6.85383 0.13596 50.41 < 2e-16 *** InsulAfter -2.12998 0.18009 -11.83 2.32e-16 *** InsulBefore:Temp -0.39324 0.02249 -17.49 < 2e-16 *** InsulAfter:Temp -0.27793 0.02292 -12.12 < 2e-16 *** --Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 0.323 on 52 degrees of freedom Multiple R-squared: 0.9277, Adjusted R-squared: 0.9235 F-statistic: 222.3 on 3 and 52 DF, p-value: < 2.2e-16 lm(data=whiteside, Gas ~ Insul anova ## ## ## ## ## ## ## ## ## + Temp %in% Insul)) + Temp %in% Insul) %>% Analysis of Variance Table Response: Gas Df Sum Sq Mean Sq F value Pr(>F) Insul 1 22.348 22.3476 214.2 < 2.2e-16 *** Insul:Temp 2 47.241 23.6207 226.4 < 2.2e-16 *** Residuals 52 5.425 0.1043 --Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 10 3.5 Visualiser Les deux graphiques qui suivent décrivent la même modélisation des données whiteside. Demandez-vous lequel est le plus parlant ? Si vous deviez exposer une analyse des données whiteside à un public éclairé mais qui n’a pas eu lui-même l’opportunité de manipuler ces données, quel graphique choisiriez vous ? Le premier graphique présente toutes les données globalement. ggplot2::ggplot(data=whiteside, mapping=ggplot2::aes(x=Temp,y=Gas,shape=Insul)) + ggplot2::geom_point() + ggplot2::stat_smooth(method="lm") 6 Gas Insul Before After 4 2 0.0 2.5 5.0 7.5 10.0 Temp A notre insu, stat_smooth a utilisé comme formula : Gas ~ Insul + Temp %in% Insul ou Gas ~ Insul * Temp ou encore Gas ~ Insul + Temp:Insul. Le second graphique développe un facette pour chaque niveau du facteur Insul. ggplot2::ggplot(data=whiteside, mapping=ggplot2::aes(x=Temp,y=Gas))+ ggplot2::geom_point() + ggplot2::stat_smooth(method="lm") • Quelle distinction entre + et : dans une formule ? • Quel rôle pour * ? • Quel rôle pour \ ? ?formula 11 ggplot2::facet_grid( . ~ Insul) + Before After Gas 6 4 2 0.0 2.5 5.0 7.5 10.0 Temp Figure 3: 12 0.0 2.5 5.0 7.5 10.0 3.6 Les outils de diagnostic #plot(lmgood, which=c(1)) #plot(lmgood, which=c(2)) #plot(lmgood, which=c(3)) #plot(lmgood, which=c(4)) #plot(lmgood, which=c(5)) #plot(lmgood, which=c(6)) #shapiro.test(lmgood$residuals) 3.7 Elimination de quelques points suspects Elimination des trois dernières lignes du design. ggplot2::ggplot(whiteside[1:53,],mapping=ggplot2::aes(x=Temp,y=Gas,shape=Insul)) + ggplot2::geom_point() + ggplot2::stat_smooth(method="lm") lmverygood <- lmgood <- lm(data=whiteside[1:53,], Gas ~ Insul plot(lmverygood, which=c(6)) 13 * Temp) 7 6 Gas Insul Before 5 After 4 3 0.0 2.5 5.0 7.5 Temp Figure 4: 14 10.0