8.5 Test de Wilcoxon

Nous avons vu que le test t de Student se réfère à une distribution qui n’est exacte que si la population de départ est normale. Même si le théorème central limite permet encore d’utiliser le test dans le cas contraire lorsque n est grand, tous les cas ne sont pas rencontrés. Si n est petit et que l’on soupçonne une distribution non normale (pensez au graphique quantile-quantile pour visualiser la distribution, mais si n est très petit, il ne sera pas non plus d’une grande utilité) que faire ?

En fait, il existe un test similaire qui ne fait aucune hypothèse sur la distribution des données : le test de Wilcoxon (encore appelé test de Mann-Whitney qui l’on découvert à peu près simultanément ; on pourrait encore écrire test de Wilcoxon-Mann-Whitney). Comme il ne se réfère pas aux paramètres d’une distribution théorique, ce type de test est appelé non paramétrique, par opposition au test t de Student qui est qualifié de paramétrique. Les mêmes variantes existent (test indépendant, test apparié, bilatéral versus unilatéral). Ce test se réalise à partir de la fonction wilcox.test(). Bien que ce test ne travaille plus sur les moyennes mais est associé aux médianes, nous le présentons ici parce qu’il représente une alternative au test t de Student.

Pour les données relatives à med1 de sleep2, cela donne48 :

  • \(H_0: mediane_{med1} = 0\)
  • \(H_1: mediane_{med1} \neq 0\)

Et dans R, nous faisons (à part le nom de la fonction, les arguments sont identiques) :

wilcox.test(sleep2$med1,
  alternative = "two.sided", mu = 0, conf.level = 0.95)
# Warning in wilcox.test.default(sleep2$med1, alternative = "two.sided", mu = 0,
# : cannot compute exact p-value with zeroes
# 
#   Wilcoxon signed rank test with continuity correction
# 
# data:  sleep2$med1
# V = 31, p-value = 0.3433
# alternative hypothesis: true location is not equal to 0

Le test n’aime pas les ex-æquos et les valeurs nulles, mais ce n’est pas dramatique. C’est la raison pour laquelle R nous averti seulement mais effectue quand même le calcul. La conclusion est la même que pour le test t de Student, nous ne pouvons pas rejeter \(H_0\).

Dans le cas d’un test indépendant (comparaison de la largeur de carapace à l’arrière rear en fonction du sexe chez L. variegatus en considérant que les femelles sont potentiellement plus grosses), nous obtenons :

  • \(H_0: P(rear_F > rear_M) = P(rear_F < rear_M)\)
  • \(H_1: P(rear_F > rear_M) > P(rear_F < rear_M)\)
wilcox.test(data = crabs, rear ~ sex,
  alternative = "greater", conf.level = 0.95)
# 
#   Wilcoxon rank sum test with continuity correction
# 
# data:  rear by sex
# W = 6710, p-value = 1.473e-05
# alternative hypothesis: true location shift is greater than 0

Nous obtenons un résultat similaire au test t de Student indépendant. Nous rejetons \(H_0\). Concernant les conditions d’application, elles sont les mêmes que pour le test t de Student équivalent à part les contraintes sur la distribution qui disparaissent.

À vous de jouer !
h5p

Quand choisir le test t de Student ou le test de Wilcoxon ? Nous serions tentés d’effectuer tout le temps un test de Wilcoxon puisqu’ainsi nous sommes certains de ne pas commettre d’impair concernant la distribution des données. Mais en fait, le test t de Student est à préférer à chaque fois que c’est possible, car il est plus puissant. Cela signifie qu’il sera capable de détecter un effet significatif avec un plus petit nombre de réplicats que le Wilcoxon. La bonne stratégie est donc d’utiliser le test t de Student autant que possible (ou la variante de Welch si l’on n’est pas certain que les variances sont égales pour le test t indépendant) et de ne se rabattre sur le test de Wilcoxon que si on ne peut pas faire autrement, soit n petit et distribution non normale ou inconnue. À noter que quand n est vraiment petit, il est impossible d’étudier valablement la distribution des données sur cet échantillon. On doit alors se baser sur un échantillon plus grand prélevé sur des données similaires ou alors jouer la sécurité et effectuer un test de Wilcoxon d’office.

Cette analyse est valable pour toute paire de test paramétrique versus non paramétrique. Le tableau suivant résume cela.

Test paramétrique Test non paramétrique
Contrainte (distribution) à vérifier indépendant de toute distribution
Puissance (même jeu de données) plus puissant moins puissant
Choix à privilégier à utiliser seulement si test paramétrique non applicable

Mais au fait, c’est quoi la “puissance” d’un test d’hypothèse ? Considérons les quatre cas possibles.

  • Ne pas rejeter \(H_0\) lorsque \(H_0\) est vraie (correct)
  • Rejeter \(H_0\) lorsque \(H_0\) est fausse (correct)
  • Rejeter \(H_0\) lorsque \(H_0\) est vraie (erreur de première espèce \(\alpha\) ou erreur de type I)
  • Ne pas rejeter \(H_0\) lorsque \(H_0\) est fausse (erreur de seconde espèce \(\beta\) ou erreur de type II)

L’erreur de première espèce est associée au risque \(\alpha\). L’erreur de seconde espèce est associée au risque \(\beta\). Plus \(\beta\) est petit, plus le test est puissant. La puissance est \(1 - \beta\). La puissance d’un test peut se calculer à l’aide des fonctions pwr.xxx() du package {pwr}. Par exemple dans le test t univarié concernant med1 nous ferons :

pwr::pwr.t.test(n = 10, d = 1.3, sig.level = 0.05,
  type = "one.sample", alternative = "two.sided")
# 
#      One-sample t test power calculation 
# 
#               n = 10
#               d = 1.3
#       sig.level = 0.05
#           power = 0.9538774
#     alternative = two.sided

La puissance est de 0,954. Donc, \(\beta\) vaut 1 - 0,954 = 0,046 ou pratiquement 5%. On a un test bien équilibré entre \(\alpha\) et \(\beta\), et de plus, \(\beta\) nous concerne particulièrement puisqu’ici nous ne rejetons pas \(H_0\).

Le système judiciaire des statistiques, par Hadley Wickham.
Le système judiciaire des statistiques, par Hadley Wickham.
À vous de jouer !

Effectuez maintenant les exercices du tutoriel A08Lb_ttest_wmw (Tests de Student et de Wilcoxon/Mann-Whitney).

BioDataScience1::run("A08Lb_ttest_wmw")

  1. Dans le cas d’un test de Wilcoxon apparié, on a \(H_0: mediane_x = mediane_y\).↩︎