Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Test d’hypothèse et p-valeur

Après cette leçon: Je peux tester une affirmation avec une p-valeur et en dire les limites.

Leçon de 65 min2 commandesLab JupyterLab de science des données : pandas, Matplotlib et scikit-learn dans le navigateur

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

MotCe que ça veut dire
Hypothèse nullel’idée qu’il n’y a aucun effet réel
Statistique de testle nombre calculé pour juger l’écart
Permutationun mélange des étiquettes des données
p-valeurla chance d’un écart aussi grand si rien n’est vrai
Seuilla p-valeur sous laquelle on rejette l’hypothèse nulle
Faux positifun 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

Commande
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, 25070,0
350, 290330, 270, 25036,7
330, 290350, 270, 25020,0
350, 270330, 290, 25020,0
330, 270350, 290, 2503,3
350, 250330, 270, 2903,3
330, 250350, 270, 290-13,3
270, 290330, 350, 250-30,0
290, 250330, 350, 270-46,7
270, 250330, 350, 290-63,3

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Compter les découpages en Python

Code: 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

Commande
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 testsChance d’au moins un faux positif
10,05
50,23
100,40
200,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.

À propos de ce labo et de sa source: Lab JupyterLab de science des données : pandas, Matplotlib et scikit-learn dans le navigateur

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.