Nous avons vu lors du dernier cours l’analyse de la variance. Comme je l’avais expliqué, comme son nom ne l’indique pas, le but de l’anova est de comparer des moyennes. Histoire d’illustrer ce test, considerons la base suivante, qui donne la note d’étudiants à un examen final de statistique (note comprise entre 0 et 20), dans un cours de Master. Ca sera notre variable , comme nous l’avions noté en cours. La variable de “traitement” sera la participation des étudiants en TD, avec comme modalité possible ‘participation volontaire’ (pour aller faire des exercices au tableau), ‘participation non-volontaire’ (les étudiants vont au tableau quand ils y sont appelés) et enfin ‘non-participation’ (les étudiants qui ne participent pas, ou qui refusent de passer au tableau s’ils y sont appelés). Afin de constituer des groupes, nous disposons de deux variables. La première est le genre de l’étudiant (‘F’ et ‘M’) et la seconde est sur l’origine des étudiants (suivant qu’ils ont fait leur licence ou pas, à Rennes, ‘R1’ ou ‘autre’).
> download.file("http://freakonometrics.free.fr/notes.RData",destfile= tempfile())
> load("notes.RData")
> tail(base)
PART GENRE ORIGINE NOTE
112 volontaire F R1 16.50
113 non_vol. M R1 11.50
114 non_vol. F R1 10.25
115 non_vol. F R1 10.75
116 non_vol. F autre 10.50
117 volontaire M R1 15.75
Avant de commencer avec une analyse à plusieurs facteurs, commençons par une analyse à un facteur. On peut regarder l’évolution des notes, en fonction de la variable de traitement (la participation en TD)
> boxplot(base$NOTE~base$PART,ylim=c(6,20))
> abline(h=mean(base$NOTE),lty=2,col="red")
> lines(1:3,with(base,aggregate(NOTE,by=list(PART), mean)$x),pch=19,lwd=3,type="b")
On peut aussi regarder la note, en fonction du genre
> boxplot(base$NOTE~base$GENRE,ylim=c(6,20))
> abline(h=mean(base$NOTE),lty=2,col="red")
> lines(1:2,with(base,aggregate(NOTE, by=list(GENRE),mean)$x),)
ou en fonction de l’origine des étudiants
> boxplot(base$NOTE~base$ORIGINE,ylim=c(6,20))
> abline(h=mean(base$NOTE),lty=2,col="red")
> lines(1:2,with(base,aggregate(NOTE, by=list(ORIGINE),mean)$x))
Dans l’anova, on suppose que , ou mieux encore
où les désigne les traitements possibles (ici, il y en a 3).
On va considérer le test de , avec comme hypothèse alternative le complémentaire . On va alors estimer deux modèles. Le premier est un modèle contraint, au sens où on ne tient pas compte du traitement (et on régresse juste sur la constante)
> sum(residuals(lm(NOTE~1,data=base))^2)
[1] 947.4979
correspondant à
> (SCR0=sum((base$NOTE-mean(base$NOTE))^2))
[1] 947.4979
Le second, on régresse sur les traitements,
> sum(residuals(lm(NOTE~PART,data=base))^2)
[1] 112.5032
ce qui revient à regarder les erreurs quand on compare à la moyenne des sous-groupes,
> Ybar=with(base,aggregate(NOTE,by=list(PART), mean)$x)
> base$moyNOTE=Ybar[as.numeric(base$PART)]
> (SCR1=sum((base$NOTE-base$moyNOTE)^2))
[1] 112.5032
La statistique de Fisher est ici
> (F=(SCR0-SCR1)*(nrow(base)-3)/SCR1/(3-1))
[1] 423.0518
Pour savoir si on est dans la région d’acceptation, ou de rejet de l’hypothèse , on peut regarder la valeur critique, correspondant au quantile à 95% de la loi de Fisher,
> qf(.95,3-1,nrow(base)-3)
[1] 3.075853
Comme on est très largement dessus de ce seuil, on va rejeter . On peut aussi calculer la p-value,
> 1-pf(F,3-1,nrow(base)-3)
[1] 0
qui est ici (numériquement) nul. Ca correspond à ce qu’on obtient avec la fonction
> anova(lm(NOTE~PART,data=base))
Analysis of Variance Table
Response: NOTE
Df Sum Sq Mean Sq F value Pr(>F)
PART 2 834.99 417.50 423.05 < 2.2e-16 ***
Residuals 114 112.50 0.99
---
ou encore
> aov(NOTE~PART,data=base)
Call:
aov(formula = NOTE ~ PART, data = base)
Terms:
PART Residuals
Sum of Squares 834.9946 112.5032
Deg. of Freedom 2 114
Residual standard error: 0.9934135
Estimated effects may be unbalanced
que l’ont peut résumer avec
> anova(aov(NOTE~PART,data=base))
Analysis of Variance Table
Response: NOTE
Df Sum Sq Mean Sq F value Pr(>F)
PART 2 834.99 417.50 423.05 < 2.2e-16 ***
Residuals 114 112.50 0.99
---
On a ici toutes les grandeurs calculées auparavant.
On voit ici que la note n’est pas indépendante du traitement. Mais on n’en sait pas beaucoup plus…
On peut creuser davantage. Le test de Tukey propose un “test multiple“, qui va regarder les différences de moyennes, par paires,
> TukeyHSD(aov(NOTE~PART,data=base))
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = NOTE ~ PART, data = base)
$PART
diff lwr upr p adj
non_vol.-non_part. 0.60416 -0.04784 1.2561 0.07539
volontaire-non_part. 6.66379 5.92912 7.3984 0.00000
volontaire-non_vol. 6.05962 5.54078 6.5784 0.00000
On voit ici que la différence entre entre ‘non-volontaire’ et ‘non-participatif’ est non-significativement non-nulle. Ou dit plus simplement (mais moins juste), disons on va accepter hypothèse qu’elle est nulle. En revanche, la note quand on participe ‘volontairement’ est significativement plus grande que quand on participe ‘non-volontairement’ ou qu’on ne participe pas.
On peut aussi regarder les tests de Student, par paires,
> with(base,pairwise.t.test(NOTE,PART))
Pairwise comparisons using t tests with pooled SD
data: NOTE and PART
non_part. non_vol.
non_vol. 0.03 -
volontaire <2e-16 <2e-16
Si on regroupe les deux modalités du traitement ‘non-volontaire’ et ‘non-participatif’, et qu’on compare cette modalité, avec ‘volontaire’, on se retrouve à faire un test de moyennes,
> with(base,t.test(NOTE[PART=='volontaire'], NOTE[PART!='volontaire']))
Welch Two Sample t-test
data: NOTE[PART == "volontaire"] and NOTE[PART != "volontaire"]
t = 29.511, df = 50.73, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
5.749719 6.589231
sample estimates:
mean of x mean of y
16.66379 10.49432
On voit que l’on accepte ici l’hypothèse que les étudiants ‘volontaires’ ont une note différente des autres.
Avant d’aller plus loin, rappelons que dans le modèle
avec , correspond à un modèle homoscédastique, au sens où ne dépend pas du traitement . On peut tester cette hypothèse, avec un test de Bartlett (qui va tester l’homogénéité des variances), en rappelant que l’hypothèse ‘variance homogène’ est validée si la p-value dépasse 5%
> bartlett.test(base$NOTE,base$PART)
Bartlett test of homogeneity of variances
data: base$NOTE and base$PART
Bartlett's K-squared = 0.5524, df = 2, p-value = 0.7587
On est bien sous les hypothèses du modèle de Fisher.
Pour aller plus loin, on peut tenter une analyse de variance à deux facteurs, avec toujours notre traitement, mais aussi une variable de groupe, basé sur le genre. On parlera d’un modèle sans interraction quand la moyenne est de la forme , et on peut inclure des interactions on considérant
De manière générale, on a ici un modèle de la forme
où désigne les écarts à la moyenne des moyennes des grandeurs observées, par traitement, et où désigne les écarts à la moyenne des moyennes des grandeurs observées, par groupe. Pour que le modèle est identifiable en rajoutant quelques contraintes (les valeurs sont centrées). Les estimateurs du maximum de vraisemblance sont ici
correspondant à la moyenne globale
correspondand à la moyenne pa r traitement (ou plutôt son écart par rapport à la moyenne globale),
et enfin
soit
où on utilise abusivement pour parler des moyennes par traitement, ou par groupe, avec des notations (probablement) naturelles, pour faire notre analyse de la variance, avec un traitement, et un groupe, on utilise lentes grandeurs suivante (on suppose ici qu’il y a individus par traitement et par groupe)
pour le modèle contraint,
où et désignent le nombre de traitement et le nombre de groupes, et où
La formule de décomposition de la variance donne ici
On va passer sur les calculs manuels,
> aov(NOTE~PART*GENRE,data=base)
Call:
aov(formula = NOTE ~ PART * GENRE, data = base)
Terms:
PART GENRE PART:GENRE Residuals
Sum of Squares 834.9946 20.9618 3.4398 88.1017
Deg. of Freedom 2 1 2 111
Residual standard error: 0.8909034
Estimated effects may be unbalanced
que l’on peut résumer avec la fonction suivante
> anova(aov(NOTE~PART*GENRE,data=base))
Analysis of Variance Table
Response: NOTE
Df Sum Sq Mean Sq F value Pr(>F)
PART 2 834.99 417.50 526.0081 < 2.2e-16 ***
GENRE 1 20.96 20.96 26.4099 1.194e-06 ***
PART:GENRE 2 3.44 1.72 2.1669 0.1194
Residuals 111 88.10 0.79
---
Comme il ne semble pas y avoir d’interractions entre le traitement et le groupe, on peut le supprimer de l’analyse de la variance
> anova(aov(NOTE~PART+GENRE,data=base))
Analysis of Variance Table
Response: NOTE
Df Sum Sq Mean Sq F value Pr(>F)
PART 2 834.99 417.50 515.364 < 2.2e-16 ***
GENRE 1 20.96 20.96 25.875 1.461e-06 ***
Residuals 113 91.54 0.81
---
Il y a un effet du genre ici. Mais moins fort que celui de la participartion. Moralité ? Les statistiques, ça sert vraiment à quelque chose, et mieux vaut passer au tableau (volontairement), ça aide ! (même si je n’ai montré aucun lien de causalité ici…)
OpenEdition suggests that you cite this post as follows:
Arthur Charpentier (November 18, 2016). Analyse de la variance, et participation en TD. Freakonometrics. Retrieved January 23, 2025 from https://doi.org/10.58079/ov5k
One thought on “Analyse de la variance, et participation en TD”