Un écart observé peut venir du hasard
Un test d’hypothèse décide si un écart observé dans des données peut s’expliquer par le hasard seul. Vous saurez poser une affirmation, calculer une p-valeur par permutation et éviter les erreurs les plus courantes.
Le loueur croit que le week-end rapporte plus de locations que la semaine. L’écart qu’il voit est-il réel, ou un coup de chance ?
À la fin de cette leçon
Remarque
Je peux tester une affirmation avec une p-valeur et en dire les limites.
Mots clés
| Mot | Ce que ça veut dire |
|---|---|
| Hypothèse nulle | l’idée qu’il n’y a aucun effet réel |
| Statistique de test | le nombre calculé pour juger l’écart |
| Permutation | un mélange des étiquettes des données |
| p-valeur | la chance d’un écart aussi grand si rien n’est vrai |
| Seuil | la p-valeur sous laquelle on rejette l’hypothèse nulle |
| Faux positif | un effet trouvé alors qu’il n’existe pas |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
On teste une affirmation contre le hasard
Une affirmation se teste en la comparant à son contraire, l’hypothèse nulle : il n’y a pas de vraie différence entre le week-end et la semaine. Si les données la rendent trop peu plausible, on la rejette.
On choisit d’abord un nombre qui résume l’écart, la statistique de test. Ici, c’est la moyenne des locations du week-end moins celle de la semaine.
L’écart de moyenne entre week-end et semaine
docker exec jupyter python3 -c "import csv, statistics; r = list(csv.DictReader(open('hires.csv'))); v = [int(x['hires']) for x in r]; j = [x['weekday'] in ('Sat', 'Sun') for x in r]; a = [v[i] for i in range(365) if j[i]]; b = [v[i] for i in range(365) if not j[i]]; print(len(a), len(b), round(statistics.mean(a), 1), round(statistics.mean(b), 1), round(statistics.mean(a) - statistics.mean(b), 1))"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
L’écart observé est de 55 locations
La commande précédente affiche 104 jours de week-end et 261 jours de semaine. Les moyennes sont 309,7 et 254,6, soit un écart de 55,2 locations.
Cet écart est-il grand ? Cela dépend de ce que le hasard seul peut produire. C’est ce que mesure la p-valeur.
Un test de permutation mélange les étiquettes
Si le jour de la semaine ne compte pas, les étiquettes « week-end » et « semaine » ne sont que des noms posés au hasard. On peut les mélanger sans rien changer à la vérité.
On mélange donc les étiquettes, on recalcule l’écart, et on regarde quelle part des mélanges donne un écart au moins aussi grand que le vrai. Cette part est la p-valeur.
Exemple travaillé : cinq jours, dix découpages
| Les 2 jours « week-end » | Les 3 autres | Écart des moyennes |
|---|---|---|
| 330, 350 (le vrai) | 270, 290, 250 | 70,0 |
| 350, 290 | 330, 270, 250 | 36,7 |
| 330, 290 | 350, 270, 250 | 20,0 |
| 350, 270 | 330, 290, 250 | 20,0 |
| 330, 270 | 350, 290, 250 | 3,3 |
| 350, 250 | 330, 270, 290 | 3,3 |
| 330, 250 | 350, 270, 290 | -13,3 |
| 270, 290 | 330, 350, 250 | -30,0 |
| 290, 250 | 330, 350, 270 | -46,7 |
| 270, 250 | 330, 350, 290 | -63,3 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Compter les découpages en Python
# Deux jours de week-end et trois jours de semaine.
valeurs = [330, 350, 270, 290, 250]
reel = (330 + 350) / 2 - (270 + 290 + 250) / 3
total = 0
plus_grands = 0
for i in range(5):
for j in range(i + 1, 5):
groupe = [valeurs[i], valeurs[j]]
reste = []
for k in range(5):
if k != i and k != j:
reste.append(valeurs[k])
ecart = sum(groupe) / 2 - sum(reste) / 3
total = total + 1
if ecart >= reel - 0.000001:
plus_grands = plus_grands + 1
print("découpages :", total)
print("au moins aussi grands :", plus_grands)
print("p-valeur :", plus_grands / total)
# Remplacez 350 par 280 aux deux endroits, puis relancez.
# La p-valeur monte-t-elle ou descend-elle ?
Un petit échantillon ne peut pas prouver beaucoup
Dans le tableau, un seul découpage sur dix atteint l’écart de 70 : la p-valeur est 1 sur 10, soit 0,1. Même avec deux groupes parfaitement séparés, cinq jours ne suffisent pas pour être sûr.
Avec plus de jours, il y a bien plus de découpages, et un écart réel devient très rare dans les mélanges.
Sur l’année, aucun mélange n’égale l’écart réel
Pour les 365 jours, il y a trop de découpages pour les compter tous. La commande suivante en fait dix, par une règle fixe : l’étiquette du jour i est celle du jour (i fois k) modulo 365.
Elle affiche dix écarts, tous entre −25,0 et 8,0. Aucun n’approche 55,2. Un vrai test fait des milliers de mélanges.
Dix mélanges fixes des étiquettes
docker exec jupyter python3 -c "import csv, statistics; r = list(csv.DictReader(open('hires.csv'))); v = [int(x['hires']) for x in r]; j = [x['weekday'] in ('Sat', 'Sun') for x in r]; print([round(statistics.mean([v[i] for i in range(365) if j[i * k % 365]]) - statistics.mean([v[i] for i in range(365) if not j[i * k % 365]]), 1) for k in [2, 3, 4, 6, 8, 9, 11, 12, 13, 14]])"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
La p-valeur suppose que rien n’est vrai
La p-valeur est la chance d’obtenir un écart au moins aussi grand que le vrai, si l’hypothèse nulle est vraie. Plus elle est petite, plus les données sont surprenantes dans un monde sans effet.
Par convention, on rejette l’hypothèse nulle quand la p-valeur est sous un seuil, souvent 0,05. Ce seuil est un choix, pas une loi de la nature.
Une erreur fréquente
Attention
Beaucoup pensent que la p-valeur est la chance que l’hypothèse nulle soit vraie. Elle dit seulement la chance de ces données si elle l’est. Une p-valeur de 0,03 ne veut pas dire 3 % de chances de se tromper.
Tester beaucoup de questions crée de faux positifs
Avec un seuil de 0,05, un test sans aucun effet réel se trompe une fois sur vingt. Si l’on teste vingt questions et que l’on ne garde que les « significatives », on en trouvera probablement une fausse.
La chance d’au moins un faux positif sur n tests est 1 moins 0,95 puissance n. Annoncez toujours combien de questions vous avez posées.
Exemple travaillé : de plus en plus de tests
| Nombre de tests | Chance d’au moins un faux positif |
|---|---|
| 1 | 0,05 |
| 5 | 0,23 |
| 10 | 0,40 |
| 20 | 0,64 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Pour aller plus loin
Dans un carnet du labo, écrivez un vrai test de permutation sur les 365 jours. Mélangez les étiquettes dix mille fois avec numpy.random.permutation. Comptez la part des écarts au moins égaux à 55,2.
Quelle p-valeur trouvez-vous ? Écrivez en une phrase ce qu’elle dit et ce qu’elle ne dit pas.