Aller au contenu

Testez une hypothèse

Le service marketing veut imprimer « 28 minutes d’autonomie » sur la boîte du drone. Les 10 batteries testées au chapitre 9 donnent 26,95 minutes en moyenne. Est-ce la preuve que la promesse est fausse, ou un simple aléa d’échantillonnage ? Et quand un second fournisseur propose des batteries qui tiennent en moyenne une minute de plus sur 10 essais, faut-il changer de fournisseur ?

Pour trancher ce genre de question de façon reproductible, on utilise un test statistique. Ce chapitre en présente la logique, le vocabulaire et les pièges, sur l’exemple des batteries. Le cours de Statistiques étend ensuite la démarche à d’autres tests (khi-deux, tests non paramétriques, régression).

Un test confronte deux hypothèses sur la loi des données :

  • l’hypothèse nulle H0H_0, qui doit définir complètement la loi de la statistique utilisée, et que l’on suppose vraie jusqu’à preuve du contraire : ici, H0:μ=28H_0 : \mu = 28 ;
  • l’hypothèse alternative H1H_1, souvent ce que l’on cherche à montrer : ici, H1:μ≠28H_1 : \mu \neq 28 (test bilatéral) ou H1:μ<28H_1 : \mu \lt 28 (test unilatéral).

Le raisonnement est celui d’un procès : H0H_0 est « présumée innocente ». On calcule une statistique de test dont on connaît la loi sous H0H_0, et l’on regarde si la valeur observée est plausible sous cette loi. Si elle est trop extrême, on rejette H0H_0 ; sinon, on la conserve, faute de preuves suffisantes.

Comme la décision repose sur un échantillon aléatoire, elle peut être fausse de deux façons :

H0H_0 vraieH1H_1 vraie
On rejette H0H_0erreur de 1re espèce (risque α\alpha)bonne décision (puissance 1−β1 - \beta)
On conserve H0H_0bonne décisionerreur de 2e espèce (risque β\beta)
  • Le risque de première espèce α=P(rejeter H0∣H0 vraie)\alpha = P(\text{rejeter } H_0 \mid H_0 \text{ vraie}) est celui d’un « faux positif ». On le fixe à l’avance, souvent à 5 %.
  • Le risque de seconde espèce β=P(conserver H0∣H1 vraie)\beta = P(\text{conserver } H_0 \mid H_1 \text{ vraie}) est celui d’un « faux négatif ». Il n’est pas fixé : il dépend de l’écart réel entre la vérité et H0H_0, et de la taille de l’échantillon.
  • La puissance 1−β1 - \beta est la probabilité de détecter un effet qui existe vraiment.

Vous reconnaissez la matrice de confusion du test de dépistage du chapitre 2 : un test statistique est un classifieur binaire entre H0H_0 et H1H_1, réglé pour limiter les faux positifs.

Si H0:μ=μ0H_0 : \mu = \mu_0 est vraie, le pivot du chapitre 9 devient une statistique entièrement calculable :

T=Xˉn−μ0S′/n∼tn−1sous H0T = \frac{\bar{X}_n - \mu_0}{S' / \sqrt{n}} \sim t_{n-1} \quad \text{sous } H_0
  • μ0\mu_0 est la valeur testée (28 minutes) ;
  • S′S' est l’écart-type empirique corrigé, nn la taille de l’échantillon ;
  • si σ\sigma est connu, on utilise Z=Xˉn−μ0σ/n∼N(0,1)Z = \frac{\bar{X}_n - \mu_0}{\sigma/\sqrt{n}} \sim \mathcal{N}(0, 1) à la place.

Au risque α\alpha, la zone d’acceptation est l’intervalle où TT tombe avec probabilité 1−α1 - \alpha sous H0H_0 : [−tn−1(1−α/2) ; tn−1(1−α/2)][-t_{n-1}(1 - \alpha/2)\,;\,t_{n-1}(1 - \alpha/2)] pour un test bilatéral. On rejette H0H_0 si la valeur observée tt en sort.

−4−2,26202,2624statistique T sous H₀ : μ = 28 (loi de Student à 9 degrés de liberté)0,000,050,100,150,200,250,300,350,40densitézone d’acceptationprobabilité 0,95 sous H₀rejet2,5 %rejet2,5 %t observé = −3,56→ on rejette H₀
Sous H₀, la statistique tombe dans la zone verte 95 fois sur 100. La valeur observée pour les batteries, −3,56, est au-delà de −2,262 : on rejette H₀.

Plutôt que de répondre seulement « rejet » ou « non-rejet », on donne en général la p-valeur : la probabilité, sous H0H_0, d’obtenir une statistique au moins aussi extrême que celle observée. Pour un test bilatéral :

p=PH0(∣T∣≥∣t∣)p = P_{H_0}\big(\lvert T \rvert \geq \lvert t \rvert\big)

On rejette H0H_0 au risque α\alpha si et seulement si p<αp \lt \alpha. La p-valeur est donc aussi le plus petit risque α\alpha pour lequel on rejetterait H0H_0 : elle permet à chacun d’appliquer son propre seuil.

Pour les batteries, p=P(∣T9∣≥3,56)≈0,006p = P(\lvert T_9 \rvert \geq 3{,}56) \approx 0{,}006. Si l’autonomie moyenne était vraiment de 28 minutes, un écart aussi grand n’arriverait qu’environ 6 fois sur 1 000 : c’est peu plausible.

2,53,03,54,04,55,0t0,0000,0050,0100,0150,0200,0250,030densité|t| = 3,56aire ≈ 0,003de chaque côté(la queue gaucheest symétrique)Zoom sur la queue droite012345|t| observé0,00,20,40,60,81,0p-valeur bilatéraleα = 0,05p < α ⟺ |t| > 2,262batteries :p ≈ 0,006Plus |t| est grand, plus p est petite
La p-valeur est l'aire des deux queues au-delà de la valeur observée. Elle passe sous α = 0,05 exactement quand |t| dépasse le seuil 2,262 : les deux règles de décision coïncident.
autonomie <- c(26.1, 27.4, 25.8, 28.2, 26.9, 27.7, 25.5, 26.6, 28.0, 27.3)
t.test(autonomie, mu = 28) # t = -3.56, df = 9, p-value = 0.0061
t.test(autonomie, mu = 28, alternative = "less") # version unilatérale : p divisée par 2
# Le même calcul à la main
t_obs <- (mean(autonomie) - 28) / (sd(autonomie) / sqrt(10))
2 * pt(-abs(t_obs), df = 9) # p-valeur bilatérale

Test et intervalle de confiance sont les deux faces d’une même médaille : on rejette H0:μ=μ0H_0 : \mu = \mu_0 au risque α\alpha (en bilatéral) si et seulement si μ0\mu_0 est en dehors de l’intervalle de confiance de niveau 1−α1 - \alpha. L’intervalle du chapitre 9, [26,28 ; 27,62][26{,}28\,;\,27{,}62], ne contient pas 28 : le rejet était prévisible. L’intervalle a l’avantage de montrer en plus l’ampleur de l’écart.

Un second fournisseur propose ses batteries. Sur 10 essais, elles tiennent 28,0 minutes en moyenne, avec s2′≈0,646s'_2 \approx 0{,}646, contre 26,95 et s1′≈0,932s'_1 \approx 0{,}932 pour le fournisseur actuel. La différence est-elle réelle ?

On teste H0:μ1=μ2H_0 : \mu_1 = \mu_2 à l’aide de la différence D=Xˉ1−Xˉ2D = \bar{X}_1 - \bar{X}_2, que l’on standardise. Trois cas se présentent, selon ce que l’on sait des variances :

SituationÉcart-type de DDLoi sous H0H_0
σ1\sigma_1, σ2\sigma_2 connusσ12/n1+σ22/n2\sqrt{\sigma_1^2/n_1 + \sigma_2^2/n_2}N(0,1)\mathcal{N}(0, 1)
variances inconnues mais égalesσ^1/n1+1/n2\hat{\sigma}\sqrt{1/n_1 + 1/n_2}, avec σ^2=(n1−1)s1′2+(n2−1)s2′2n1+n2−2\hat{\sigma}^2 = \frac{(n_1 - 1)s_1'^2 + (n_2 - 1)s_2'^2}{n_1 + n_2 - 2}tn1+n2−2t_{n_1 + n_2 - 2}
variances inconnues quelconques (Welch)s1′2/n1+s2′2/n2\sqrt{s_1'^2/n_1 + s_2'^2/n_2}Student à ν\nu degrés de liberté (formule de Welch-Satterthwaite)

Dans le deuxième cas, σ^2\hat{\sigma}^2 est la variance commune estimée en regroupant les deux échantillons. Le troisième cas, le test de Welch, ne suppose pas l’égalité des variances ; c’est le choix par défaut de t.test en R, et le plus sûr en pratique.

actuel <- c(26.1, 27.4, 25.8, 28.2, 26.9, 27.7, 25.5, 26.6, 28.0, 27.3)
nouveau <- c(27.9, 28.4, 27.1, 28.8, 27.6, 28.3, 27.0, 28.9, 27.8, 28.2)
t.test(actuel, nouveau) # Welch (défaut) : t = -2.93, df = 16.0, p-value = 0.0099
t.test(actuel, nouveau, var.equal = TRUE) # variances supposées égales : df = 18, p-value = 0.0090
25,526,026,527,027,528,028,529,0autonomie (minutes)fournisseuractuelnouveaufournisseurmoyenne 26,95moyenne 28,00−2−10IC à 95 % de la différence (min)différence nulle(H₀)−1,81−0,29μ₁ − μ₂ : −1,05
Les deux nuages se chevauchent beaucoup, mais l'intervalle de confiance de la différence ne contient pas 0 : l'écart de 1,05 minute n'est pas qu'une fluctuation.

Les tests sur les moyennes supposent des données normales, mais ils restent approximativement valables sans normalité quand les effectifs dépassent une trentaine, grâce au théorème central limite. Avec 10 mesures par groupe, comme ici, il faut que l’hypothèse de normalité soit plausible (un histogramme ou un diagramme quantile-quantile, qqnorm, aide à en juger).

Fixer α\alpha ne dit rien de la capacité du test à détecter un effet réel. Supposons l’écart-type connu, σ=1\sigma = 1 minute, et un test bilatéral de H0:μ=28H_0 : \mu = 28 au risque 5 % avec n=10n = 10 batteries. Si la vraie moyenne est μ=27\mu = 27 (un écart δ=1\delta = 1), la statistique ZZ est centrée non plus sur 0, mais sur −δn/σ≈−3,16-\delta\sqrt{n}/\sigma \approx -3{,}16 (la vraie moyenne est en dessous de 28). Le test étant bilatéral, seule la distance à 0 compte : le calcul est le même qu’avec +3,16+3{,}16. La puissance est la probabilité qu’elle sorte de [−1,96 ; 1,96][-1{,}96\,;\,1{,}96] :

1−β=P(Z′>1,96−3,16)+P(Z′<−1,96−3,16)≈0,8851 - \beta = P(Z' \gt 1{,}96 - 3{,}16) + P(Z' \lt -1{,}96 - 3{,}16) \approx 0{,}885

où Z′∼N(0,1)Z' \sim \mathcal{N}(0, 1). Pour un écart plus faible, δ=0,5\delta = 0{,}5, la puissance tombe à 0,35 : le test passera à côté de l’effet près de deux fois sur trois.

0,00,10,20,30,40,5densitésous H₀vraie moyenne 27,0puissance :on rejette H₀β : on garde H₀à tortα/2 = 2,5 %écart δ = 1,0 min : puissance 0,885, β = 0,115−6−4−1,9601,964statistique Z = (x̄ − 28)/(σ/√n), avec σ = 1 et n = 100,00,10,20,30,40,5densitésous H₀vraie moyenne 27,5écart δ = 0,5 min : puissance 0,353, β = 0,647
La zone de rejet est fixée par α (en rose, sous H₀). Quand l'écart réel diminue, la loi réelle glisse vers H₀ et la part violette β grandit : la puissance chute de 0,885 à 0,353.

La puissance augmente avec l’écart réel δ\delta, avec la taille d’échantillon nn, quand la dispersion σ\sigma diminue, et quand α\alpha augmente (on accepte plus de faux positifs pour moins de faux négatifs). Dans une comparaison de deux groupes à effectif total fixé, elle est maximale quand les deux groupes ont la même taille. En pratique, on dimensionne l’étude avant de collecter les données :

# Nombre de batteries pour détecter un écart de 0.5 minute avec 80 % de puissance
power.t.test(delta = 0.5, sd = 1, sig.level = 0.05, power = 0.80, type = "one.sample")
# n = 33.4 environ : il faut 34 batteries (l'approximation normale donne 32)
020406080100nombre n de batteries (σ = 1, test bilatéral à 5 %)0,00,20,40,60,81,0puissance 1 − βpuissance visée : 80 %δ = 0,5 : 32 batteries(34 avec Student)n = 10 : 0,885n = 10 : 0,35écart δ = 1,0 minécart δ = 0,5 min
La puissance croît avec n, d'autant plus vite que l'écart à détecter est grand. Diviser l'écart par deux demande environ quatre fois plus de batteries.
  • Un test oppose H0H_0 (loi connue, présumée vraie) à H1H_1 ; on rejette H0H_0 si la statistique observée est trop extrême sous H0H_0.
  • Le risque de 1re espèce α\alpha (faux positif) est fixé ; le risque de 2e espèce β\beta (faux négatif) dépend de l’effet réel et de nn ; la puissance vaut 1−β1 - \beta.
  • La p-valeur est la probabilité, sous H0H_0, d’un résultat au moins aussi extrême ; on rejette si p<αp \lt \alpha. Ce n’est pas P(H0∣donneˊes)P(H_0 \mid \text{données}).
  • Conformité d’une moyenne : ZZ si σ\sigma est connu, T∼tn−1T \sim t_{n-1} sinon ; rejeter au risque α\alpha équivaut à μ0\mu_0 hors de l’intervalle de confiance à 1−α1 - \alpha.
  • Deux moyennes : test ZZ, test de Student à variances égales, ou test de Welch (défaut de t.test).
  • On dimensionne une étude par un calcul de puissance (power.t.test) ; « non significatif » ne prouve pas l’absence d’effet.

Exercice · Un test avec écart-type connu

facile

Une machine est réglée pour remplir des bouteilles à 500 mL, avec un écart-type connu de 6 mL. On contrôle 36 bouteilles : la moyenne vaut 498,2 mL. Au risque 5 %, la machine est-elle déréglée ? Donnez la p-valeur.

Voir la solution

H0:μ=500H_0 : \mu = 500 contre H1:μ≠500H_1 : \mu \neq 500. Sous H0H_0, Z=Xˉ−5006/36∼N(0,1)Z = \frac{\bar{X} - 500}{6/\sqrt{36}} \sim \mathcal{N}(0, 1). La valeur observée est z=498,2−5001=−1,8z = \frac{498{,}2 - 500}{1} = -1{,}8.

Elle reste dans la zone d’acceptation [−1,96 ; 1,96][-1{,}96\,;\,1{,}96] : on conserve H0H_0. La p-valeur vaut 2 P(Z≥1,8)=2×(1−Φ(1,8))≈0,0722\,P(Z \geq 1{,}8) = 2 \times (1 - \Phi(1{,}8)) \approx 0{,}072, supérieure à 0,05.

Attention à la conclusion : on ne prouve pas que la machine est bien réglée, on constate seulement que 36 bouteilles ne suffisent pas à démontrer un dérèglement de cet ordre. En R : 2 * pnorm(-1.8).

En code

import numpy as np
from scipy import stats
mu0, sigma, n, moyenne = 500, 6, 36, 498.2
z = (moyenne - mu0) / (sigma / np.sqrt(n))
p_valeur = 2 * stats.norm.sf(abs(z)) # bilatéral
print(z) # -1.8
print(p_valeur) # 0.0719
print(abs(z) > stats.norm.ppf(0.975)) # False : on conserve H0

Exercice · Un A/B test non significatif

moyen

Un site teste deux versions de sa page d’accueil sur 1 000 visiteurs chacune. La version A convertit 50 visiteurs, la version B en convertit 70. Sous H0H_0 (même taux de conversion pp), on estime pp par la proportion globale p^=120/2 000=0,06\hat{p} = 120/2\,000 = 0{,}06, et la statistique

Z=p^B−p^Ap^(1−p^)(1/nA+1/nB)Z = \frac{\hat{p}_B - \hat{p}_A}{\sqrt{\hat{p}(1 - \hat{p})(1/n_A + 1/n_B)}}

suit approximativement N(0,1)\mathcal{N}(0, 1).

  1. Calculez zz et la p-valeur bilatérale. Que concluez-vous au risque 5 % ?
  2. Le responsable produit en déduit que « la version B ne fait pas mieux ». Qu’en pensez-vous ?
Voir la solution
  1. p^B−p^A=0,07−0,05=0,02\hat{p}_B - \hat{p}_A = 0{,}07 - 0{,}05 = 0{,}02. Le dénominateur vaut 0,06×0,94×0,002≈0,0106\sqrt{0{,}06 \times 0{,}94 \times 0{,}002} \approx 0{,}0106, donc z≈1,88z \approx 1{,}88 et p=2(1−Φ(1,88))≈0,060p = 2(1 - \Phi(1{,}88)) \approx 0{,}060. Au risque 5 %, on ne rejette pas H0H_0. En R, prop.test(c(70, 50), c(1000, 1000), correct = FALSE) donne la même p-valeur (sa statistique du khi-deux vaut z2≈3,55z^2 \approx 3{,}55).
  2. C’est une erreur d’interprétation. Le test n’a pas montré l’absence d’effet : il a manqué de puissance. L’effet observé (+2 points, soit +40 % de conversions) serait considérable s’il était réel. Il faut soit prolonger le test pour augmenter nn, soit présenter l’intervalle de confiance de la différence, qui contient à la fois 0 et des gains importants.

En code

import numpy as np
from scipy import stats
from statsmodels.stats.proportion import proportions_ztest
conv = np.array([70, 50]) # conversions B puis A
n = np.array([1000, 1000])
p_b, p_a = conv / n
p_global = conv.sum() / n.sum() # 0.06 sous H0
z = (p_b - p_a) / np.sqrt(p_global * (1 - p_global) * (1 / n[0] + 1 / n[1]))
print(z, 2 * stats.norm.sf(abs(z))) # 1.883 0.0597
print(proportions_ztest(conv, n)) # même z et même p-valeur
# IC de Wald à 95 % de la différence : il contient 0 et des gains importants
ecart = np.sqrt(p_b * (1 - p_b) / n[0] + p_a * (1 - p_a) / n[1])
print(p_b - p_a + np.array([-1, 1]) * 1.96 * ecart) # [-0.0008 0.0408]

Exercice · Dimensionner une comparaison

difficile

On veut comparer deux fournisseurs de batteries dont l’autonomie a un écart-type commun connu σ=1\sigma = 1 minute. On utilisera un test ZZ bilatéral au risque 5 %, avec nn batteries par fournisseur.

  1. Montrez que, si la vraie différence des moyennes est δ\delta, la puissance vaut approximativement Φ(δσ2/n−1,96)\Phi\left(\frac{\delta}{\sigma\sqrt{2/n}} - 1{,}96\right) (on néglige la probabilité de rejeter du « mauvais côté »).
  2. Quelle valeur de nn faut-il pour détecter δ=0,5\delta = 0{,}5 minute avec une puissance de 80 % ?
  3. Pourquoi est-il préférable de prendre 50 batteries de chaque fournisseur plutôt que 20 d’un côté et 80 de l’autre ?
Voir la solution
  1. L’écart-type de D=Xˉ1−Xˉ2D = \bar{X}_1 - \bar{X}_2 vaut σD=σ2/n\sigma_D = \sigma\sqrt{2/n}. Sous H1H_1, Z=D/σDZ = D/\sigma_D suit N(δ/σD,1)\mathcal{N}(\delta/\sigma_D, 1). On rejette si ∣Z∣>1,96\lvert Z \rvert \gt 1{,}96 ; du côté de l’effet, P(Z>1,96)=P(Z′>1,96−δ/σD)=Φ(δ/σD−1,96)P(Z \gt 1{,}96) = P(Z' \gt 1{,}96 - \delta/\sigma_D) = \Phi(\delta/\sigma_D - 1{,}96), où Z′∼N(0,1)Z' \sim \mathcal{N}(0,1). L’autre côté est négligeable dès que l’effet n’est pas minuscule.
  2. On veut Φ(δσ2/n−1,96)=0,80\Phi\left(\frac{\delta}{\sigma\sqrt{2/n}} - 1{,}96\right) = 0{,}80, soit δσ2/n−1,96=0,842\frac{\delta}{\sigma\sqrt{2/n}} - 1{,}96 = 0{,}842 (quantile d’ordre 0,8). Donc n/2=2,802/0,5=5,604\sqrt{n/2} = 2{,}802/0{,}5 = 5{,}604, soit n=2×5,6042≈62,8n = 2 \times 5{,}604^2 \approx 62{,}8 : il faut 63 batteries par fournisseur, 126 au total.
  3. Avec des groupes de tailles n1n_1 et n2n_2, σD2=σ2(1/n1+1/n2)\sigma_D^2 = \sigma^2(1/n_1 + 1/n_2). Pour 50+5050 + 50 : σD2=0,04 σ2\sigma_D^2 = 0{,}04\,\sigma^2 ; pour 20+8020 + 80 : σD2=(0,05+0,0125) σ2=0,0625 σ2\sigma_D^2 = (0{,}05 + 0{,}0125)\,\sigma^2 = 0{,}0625\,\sigma^2. À effectif total égal, les groupes équilibrés donnent la plus petite variance de DD, donc la plus grande puissance.

En code

import numpy as np
from scipy import stats
def puissance(n, delta=0.5, sigma=1.0, alpha=0.05):
"""Puissance approchée du test Z bilatéral, n batteries par fournisseur."""
sigma_d = sigma * np.sqrt(2 / n)
return stats.norm.cdf(delta / sigma_d - stats.norm.ppf(1 - alpha / 2))
# 2. n tel que la puissance vaille 80 %
u, v = stats.norm.ppf(0.975), stats.norm.ppf(0.80) # 1.96 0.842
n_exact = 2 * ((u + v) * 1.0 / 0.5) ** 2
print(n_exact, puissance(62), puissance(63)) # 62.79 0.7950 0.8013
# 3. Variance de D (en unités de sigma^2) selon la répartition de 100 batteries
for n1, n2 in [(50, 50), (20, 80)]:
print(n1, n2, 1 / n1 + 1 / n2) # 0.04 puis 0.0625