Comprenez la logique d'un test statistique
Une machine remplit des paquets de café censés peser 250 g. Sur 16 paquets, la masse moyenne vaut 249,2 g. La machine est-elle déréglée, ou bien ce petit écart est-il le fruit du hasard ? Arrêter la ligne pour rien coûte cher ; laisser partir des paquets trop légers aussi.
Un test statistique est une règle de décision qui tranche ce genre de question en contrôlant le risque de se tromper. Ce chapitre en démonte la mécanique sur ce cas simple ; les chapitres suivants déclineront la même logique pour d’autres paramètres.
Deux hypothèses qui ne jouent pas le même rôle
Section intitulée « Deux hypothèses qui ne jouent pas le même rôle »On formalise la question par deux hypothèses sur la moyenne de la machine :
- l’hypothèse nulle , la machine est bien réglée ;
- l’hypothèse alternative , elle est déréglée.
Ces deux hypothèses ne sont pas symétriques. est l’hypothèse de référence, celle du statu quo ou de la prudence, que l’on garde tant que les données ne la contredisent pas nettement. est ce que l’on cherche à mettre en évidence. Le raisonnement ressemble à un procès : l’accusé est présumé innocent () et on ne le condamne que sur des preuves suffisantes.
L’alternative peut être :
- bilatérale : (un écart dans un sens ou dans l’autre nous intéresse) ;
- unilatérale : (seuls les paquets trop légers posent problème, par exemple pour une association de consommateurs), avec alors .
Deux façons de se tromper
Section intitulée « Deux façons de se tromper »Quelle que soit la règle, deux erreurs sont possibles :
| vraie (machine réglée) | vraie (machine déréglée) | |
|---|---|---|
| On conserve | bonne décision | erreur de seconde espèce (risque ) |
| On rejette | erreur de première espèce (risque ) | bonne décision (probabilité ) |
- , le niveau du test, est la probabilité de rejeter alors qu’elle est vraie : un faux positif, ici arrêter une machine bien réglée.
- est la probabilité de conserver alors qu’elle est fausse : un faux négatif, ici laisser tourner une machine déréglée.
- La puissance est la probabilité de détecter un écart qui existe vraiment.
On ne peut pas rendre et petits en même temps à taille d’échantillon fixée : être plus exigeant pour rejeter (baisser ) fait rater plus d’écarts réels (augmenter ). La convention est donc de fixer (1 %, 5 % ou 10 %) et de choisir, parmi les tests de niveau , le plus puissant.
La démarche en six étapes
Section intitulée « La démarche en six étapes »Supposons, comme l’indique le constructeur, que la masse d’un paquet suit une loi avec g connu. On a et g.
- Hypothèses : contre .
- Niveau : .
- Statistique de test, dont on connaît la loi sous :
où est la valeur testée. mesure l’écart entre la moyenne observée et , en nombre d’erreurs-types.
- Région critique : les valeurs de qui conduisent à rejeter , choisies pour que . Pour une alternative bilatérale, on rejette les valeurs trop grandes en valeur absolue : , avec .
- Valeur observée : .
- Décision et conclusion : , donc : on rejette au niveau 5 %. Les données indiquent un déréglage de la machine.
On peut aussi exprimer la région critique directement sur : on rejette si sort de . Avec 249,2 g, on est juste en dessous.
La p-valeur : jusqu’à quel niveau rejette-t-on ?
Section intitulée « La p-valeur : jusqu’à quel niveau rejette-t-on ? »Le verdict « rejet à 5 % » perd de l’information : rejette-t-on de justesse ou de très loin ? La p-valeur répond. C’est la probabilité, si est vraie, d’observer une statistique au moins aussi extrême que celle obtenue :
où est la fonction de répartition de . Ici, .
La p-valeur est aussi le plus petit niveau auquel on rejette . D’où la règle : on rejette au niveau si et seulement si . Ici, on rejette à 5 % () mais pas à 1 % ().
Pour l’alternative unilatérale , seule la queue gauche compte : , et la région critique devient .
La puissance : détecter ce qui existe
Section intitulée « La puissance : détecter ce qui existe »Supposons que la machine soit en réalité réglée à g. Quelle est la probabilité que notre test (16 paquets, ) le détecte ?
Sous cette hypothèse, n’est plus centrée : elle suit avec . La puissance vaut
Une fois sur quatre, un déréglage d’un gramme passerait inaperçu. Pour faire mieux, il faut plus de données :
| Nombre de paquets | 4 | 9 | 16 | 25 | 36 |
|---|---|---|---|---|---|
| Puissance pour | 0,27 | 0,52 | 0,76 | 0,92 | 0,98 |
La puissance augmente avec la taille de l’échantillon, avec l’écart réel et avec ; elle diminue quand augmente. Pour atteindre 90 %, il faut , soit 24 paquets. C’est ce calcul qu’on fait avant une expérience, par exemple avant un test A/B.
Test et intervalle de confiance : deux faces d’une même pièce
Section intitulée « Test et intervalle de confiance : deux faces d’une même pièce »L’IC à 95 % de (avec connu) vaut . Il ne contient pas 250.
Ce n’est pas un hasard. Pour un test bilatéral, on rejette au niveau si et seulement si n’appartient pas à l’IC de niveau . L’intervalle donne même plus d’information que le test : il indique toutes les valeurs de compatibles avec les données.
# On raisonne directement sur le résumé : n = 16, moyenne 249.2, sigma = 1.5z0 <- sqrt(16) * (249.2 - 250) / 1.52 * (1 - pnorm(abs(z0))) # p-valeur bilatérale : 0.033power.t.test(delta = 1, sd = 1.5, power = 0.9, type = "one.sample") # n nécessaire (version Student)import numpy as npfrom scipy import stats
z0 = np.sqrt(16) * (249.2 - 250) / 1.5print(z0, 2 * stats.norm.sf(abs(z0))) # -2.13 et 0.033
delta = np.sqrt(16) * (249 - 250) / 1.5puissance = stats.norm.cdf(-1.96 - delta) + stats.norm.cdf(-1.96 + delta)print(puissance) # 0.76En résumé
Section intitulée « En résumé »- est l’hypothèse de référence, qu’on ne rejette que sur preuves ; est ce qu’on veut montrer (bilatérale ou unilatérale).
- Erreur de première espèce : rejeter à tort (probabilité , fixée) ; seconde espèce : la conserver à tort () ; puissance .
- Démarche : hypothèses, niveau, statistique de loi connue sous , région critique, valeur observée, décision.
- p-valeur : plus petit niveau qui conduit au rejet ; ce n’est pas la probabilité que soit vraie, et conserver ne la prouve pas.
- La puissance croît avec et avec l’écart réel ; test bilatéral et intervalle de confiance sont équivalents.
Exercices
Section intitulée « Exercices »Exercice · Formuler les hypothèses
facilePour chaque situation, écrivez et et dites si le test est unilatéral ou bilatéral.
- Un fabricant affirme que ses ampoules durent en moyenne au moins 10 000 heures ; une association de consommateurs veut le contredire.
- Un laboratoire vérifie qu’un appareil de mesure n’a pas de biais : la moyenne de mesures d’un étalon de 100 mg doit valoir 100 mg.
- Une équipe produit veut montrer que la nouvelle version d’une page augmente le taux de conversion, actuellement de 4 %.
Voir la solution
- contre (unilatéral). L’association cherche à montrer que la durée est plus courte : c’est .
- contre (bilatéral) : un biais dans un sens ou dans l’autre pose problème.
- contre (unilatéral). L’amélioration est ce qu’il faut démontrer ; sans preuve, on garde le statu quo.
En code
import numpy as npfrom scipy import stats
# Données fictives : le sens de H1 se traduit par l'argument alternativerng = np.random.default_rng(0)ampoules = rng.normal(9800, 500, size=30) # durées de vie (heures)mesures = rng.normal(100.2, 0.5, size=20) # mesures de l'étalon (mg)
# 1. H1 : m < 10 000 (unilatéral à gauche)print(stats.ttest_1samp(ampoules, 10000, alternative="less").pvalue) # 0.0008# 2. H1 : m != 100 (bilatéral)print(stats.ttest_1samp(mesures, 100, alternative="two-sided").pvalue) # 0.0004# 3. H1 : p > 0.04 (unilatéral à droite), 52 conversions sur 1 000 visitesprint(stats.binomtest(52, 1000, p=0.04, alternative="greater").pvalue) # 0.036# Données fictives : le sens de H1 se traduit par l'argument alternativeset.seed(0)ampoules <- rnorm(30, mean = 9800, sd = 500) # durées de vie (heures)mesures <- rnorm(20, mean = 100.2, sd = 0.5) # mesures de l'étalon (mg)
# 1. H1 : m < 10 000 (unilatéral à gauche)t.test(ampoules, mu = 10000, alternative = "less")$p.value # 0.016# 2. H1 : m != 100 (bilatéral)t.test(mesures, mu = 100, alternative = "two.sided")$p.value # 0.057# 3. H1 : p > 0.04 (unilatéral à droite), 52 conversions sur 1 000 visitesbinom.test(52, 1000, p = 0.04, alternative = "greater")$p.value # 0.036Exercice · Mener un test complet
moyenDes bouteilles doivent contenir 1 000 mL. La machine a un écart-type connu de 6 mL et on suppose la normalité. Sur 36 bouteilles, mL. Testez au niveau 5 % si la machine sous-remplit en moyenne, puis donnez la p-valeur.
Voir la solution
On teste contre . Sous (à la frontière ), .
. La région critique unilatérale est : on rejette , la machine sous-remplit.
La p-valeur vaut : on rejetterait même au niveau 1 %.
En code
import numpy as npfrom scipy import stats
n, moyenne, sigma, m0 = 36, 997.6, 6, 1000t0 = np.sqrt(n) * (moyenne - m0) / sigmaprint(t0, stats.norm.ppf(0.05)) # -2.4 < -1.645 : on rejette H0print(stats.norm.cdf(t0)) # p-valeur unilatérale : 0.0082n <- 36; moyenne <- 997.6; sigma <- 6; m0 <- 1000t0 <- sqrt(n) * (moyenne - m0) / sigmat0; qnorm(0.05) # -2.4 < -1.645 : on rejette H0pnorm(t0) # p-valeur unilatérale : 0.0082Exercice · Planifier un test par sa puissance
difficileOn reprend la machine à café ( g, test bilatéral à 5 %). On veut détecter un déréglage de 0,5 g avec une puissance de 80 %. Combien de paquets faut-il peser ? Commentez par rapport au déréglage de 1 g.
Voir la solution
On utilise avec et :
Il faut donc 71 paquets. Pour un déréglage de 1 g à la même puissance, on trouverait , soit 18 paquets. Diviser l’écart à détecter par 2 multiplie la taille d’échantillon par 4 : la taille nécessaire varie comme .
En code
import numpy as npfrom scipy import statsfrom statsmodels.stats.power import tt_solve_power
sigma, alpha, puissance = 1.5, 0.05, 0.80z = stats.norm.ppf(1 - alpha / 2) + stats.norm.ppf(puissance) # 1.96 + 0.842for ecart in [0.5, 1.0]: n = (z * sigma / ecart)**2 print(ecart, n, int(np.ceil(n))) # 0.5 -> 70.6 soit 71 ; 1.0 -> 17.7 soit 18
# Version Student (sigma estimé) : un peu plus de paquetsprint(tt_solve_power(effect_size=0.5 / sigma, alpha=alpha, power=puissance)) # 72.6sigma <- 1.5; alpha <- 0.05; puissance <- 0.80z <- qnorm(1 - alpha / 2) + qnorm(puissance) # 1.96 + 0.842for (ecart in c(0.5, 1)) { n <- (z * sigma / ecart)^2 cat(ecart, n, ceiling(n), "\n") # 0.5 -> 70.6 soit 71 ; 1 -> 17.7 soit 18}
# Version Student (sigma estimé) : un peu plus de paquetspower.t.test(delta = 0.5, sd = sigma, power = puissance, type = "one.sample")$n # 72.6