Aller au contenu

Raisonnez sous condition avec la formule de Bayes

Un test de dépistage détecte 95 % des malades. Votre résultat est positif. Quelle est la probabilité que vous soyez malade ? Si vous avez répondu « 95 % », vous êtes en bonne compagnie : c’est la réponse que donnent aussi beaucoup de médecins interrogés… et elle est fausse, souvent de très loin.

Dans ce chapitre, vous allez apprendre à raisonner quand une information nouvelle arrive : c’est la probabilité conditionnelle, et son outil phare, la formule de Bayes. Le fil rouge sera ce test de dépistage, que nous suivrons jusqu’au bout.

Une maladie touche 2 % d’une population. Un laboratoire propose un test dont on connaît deux caractéristiques :

  • sa sensibilité : parmi les malades, 95 % ont un test positif ;
  • sa spécificité : parmi les personnes saines, 90 % ont un test négatif (donc 10 % de faux positifs).

Avant tout formalisme, faisons le calcul « en effectifs » sur 10 000 personnes :

Test positifTest négatifTotal
Malades19010200
Saines9808 8209 800
Total1 1708 83010 000

Sur les 1 170 tests positifs, seuls 190 concernent des malades : 190/1 170≈16 %190 / 1\,170 \approx 16\,\%. Les faux positifs, qui ne touchent pourtant que 10 % des personnes saines, sont bien plus nombreux que les vrais positifs, simplement parce que les personnes saines sont 49 fois plus nombreuses. Retenez cette image, elle résume tout le chapitre.

10 000 personnes testées190 malades16 %980 sains(faux positifs)84 %Sachant « positif » :les 1 170 positifs■ malade, positif (190)■ malade, négatif (10)■ sain, positif (980)■ sain, négatif (8 820)
Les malades n'occupent que deux lignes de la grille, alors que les faux positifs en remplissent près de dix. Parmi les positifs, les malades ne sont donc que 16 %.

Savoir que le test est positif revient à restreindre l’univers : on ne regarde plus les 10 000 personnes, mais seulement les 1 170 positives. La probabilité conditionnelle formalise cette restriction.

Soit BB un événement de probabilité non nulle. La probabilité de AA sachant BB est :

P(A∣B)=P(A∩B)P(B)P(A \mid B) = \frac{P(A \cap B)}{P(B)}
  • A∩BA \cap B est l’événement « AA et BB » ;
  • P(B)P(B) sert de normalisation : on divise par la « taille » du nouvel univers BB, pour que P(B∣B)=1P(B \mid B) = 1.

Pour BB fixé, l’application A↦P(A∣B)A \mapsto P(A \mid B) est une probabilité à part entière : elle vérifie les axiomes de Kolmogorov. Toutes les règles du chapitre 1 restent donc valables « sachant BB », par exemple P(Aˉ∣B)=1−P(A∣B)P(\bar{A} \mid B) = 1 - P(A \mid B).

En retournant la définition, on obtient la formule des probabilités composées, qui sert à calculer la probabilité d’un « et » :

P(A∩B)=P(B) P(A∣B)=P(A) P(B∣A)P(A \cap B) = P(B) \, P(A \mid B) = P(A) \, P(B \mid A)

Elle se généralise en chaîne : P(A∩B∩C)=P(A) P(B∣A) P(C∣A∩B)P(A \cap B \cap C) = P(A) \, P(B \mid A) \, P(C \mid A \cap B). C’est exactement ce que vous faites en multipliant les probabilités le long d’une branche d’arbre.

Pour calculer P(positif)P(\text{positif}), on découpe la population en deux groupes, malades et saines, et on additionne les contributions de chaque groupe. C’est un cas particulier d’un résultat général.

Une famille d’événements A1,…,AnA_1, \dots, A_n forme une partition (ou système complet) de Ω\Omega s’ils sont deux à deux incompatibles et si leur union est Ω\Omega : chaque issue tombe dans exactement un AiA_i. Alors, pour tout événement BB :

P(B)=∑i=1nP(Ai) P(B∣Ai)P(B) = \sum_{i=1}^{n} P(A_i) \, P(B \mid A_i)

Autrement dit, P(B)P(B) est une moyenne pondérée des probabilités conditionnelles P(B∣Ai)P(B \mid A_i), les poids étant les probabilités P(Ai)P(A_i) de chaque groupe.

Le schéma ci-dessous montre l’arbre du test. Chaque chemin multiplie les probabilités de ses branches (probabilités composées), et P(+)P(+) additionne les deux chemins qui finissent par « positif » (probabilités totales).

0,020,98M (malade)S (sain)0,950,050,100,90+ : 0,02 × 0,95 = 0,019− : 0,001+ : 0,98 × 0,10 = 0,098− : 0,882

Nous connaissons P(+∣M)P(+ \mid M) (la sensibilité), mais c’est P(M∣+)P(M \mid +) qui intéresse le patient. La formule de Bayes permet justement de retourner le conditionnement. Il suffit d’écrire P(M∩+)P(M \cap +) de deux façons avec les probabilités composées :

P(M∣+)=P(+∣M) P(M)P(+)P(M \mid +) = \frac{P(+ \mid M) \, P(M)}{P(+)}

Et comme le dénominateur se calcule par les probabilités totales, on obtient la forme générale : pour une partition A1,…,AnA_1, \dots, A_n et un événement BB de probabilité non nulle,

P(Ai∣B)=P(B∣Ai) P(Ai)∑j=1nP(B∣Aj) P(Aj)P(A_i \mid B) = \frac{P(B \mid A_i) \, P(A_i)}{\sum_{j=1}^{n} P(B \mid A_j) \, P(A_j)}

Le vocabulaire associé est important, car vous le retrouverez partout en apprentissage automatique :

  • P(Ai)P(A_i) est la probabilité a priori (prior) : ce qu’on croit avant l’observation ;
  • P(B∣Ai)P(B \mid A_i) est la vraisemblance (likelihood) : la probabilité de l’observation si AiA_i est vrai ;
  • P(Ai∣B)P(A_i \mid B) est la probabilité a posteriori (posterior) : ce qu’on croit après l’observation.

Que faire après un test positif ? On en refait un. Si les deux tests se trompent indépendamment l’un de l’autre (une hypothèse à discuter avec le laboratoire), l’a posteriori du premier test devient l’a priori du second :

P(M∣+,+)=0,95×0,1620,95×0,162+0,10×0,838≈0,648P(M \mid +, +) = \frac{0{,}95 \times 0{,}162}{0{,}95 \times 0{,}162 + 0{,}10 \times 0{,}838} \approx 0{,}648

Deux tests positifs portent la probabilité à 65 % environ. C’est le cœur du raisonnement bayésien : chaque observation met à jour la croyance précédente. Le cours d’Apprentissage automatique en tire un classifieur complet, le Bayes naïf.

0,00,20,40,60,81,0a priori P(M)0,00,20,40,60,81,0a posteriori P(M | résultat du test)diagonale : le testn’apprend rien1er test : 0,02 → 0,1622e test : 0,162 → 0,648test négatif : 0,02 → 0,001après un test positifaprès un test négatif
Chaque test positif fait monter d'une marche : l'a posteriori du premier test (0,162) sert d'a priori au second (0,648). Partie de 2 %, la probabilité reste faible après un seul test.

On vérifie ces calculs en quelques lignes de R, et même par simulation :

prevalence <- 0.02; sensibilite <- 0.95; specificite <- 0.90
bayes <- function(prior) {
vrais_pos <- sensibilite * prior
faux_pos <- (1 - specificite) * (1 - prior)
vrais_pos / (vrais_pos + faux_pos) # P(M | +)
}
bayes(prevalence) # 0.162
bayes(bayes(prevalence)) # 0.648 après deux tests positifs
# Vérification par simulation sur un million de personnes
set.seed(3)
n <- 1e6
malade <- runif(n) < prevalence
positif <- ifelse(malade, runif(n) < sensibilite, runif(n) < 1 - specificite)
mean(malade[positif]) # proportion de malades parmi les positifs, proche de 0.162

La dernière ligne traduit exactement la définition : parmi les personnes positives (malade[positif]), quelle proportion est malade ?

  • La probabilité conditionnelle P(A∣B)=P(A∩B)/P(B)P(A \mid B) = P(A \cap B) / P(B) restreint l’univers aux issues où BB est réalisé ; c’est une information, pas un ordre dans le temps.
  • Les probabilités composées P(A∩B)=P(A) P(B∣A)P(A \cap B) = P(A) \, P(B \mid A) multiplient les probabilités le long d’une branche d’arbre.
  • Les probabilités totales P(B)=∑iP(Ai) P(B∣Ai)P(B) = \sum_i P(A_i) \, P(B \mid A_i) additionnent les branches d’une partition.
  • La formule de Bayes donne l’a posteriori P(Ai∣B)P(A_i \mid B) à partir de l’a priori P(Ai)P(A_i) et de la vraisemblance P(B∣Ai)P(B \mid A_i).
  • Ignorer l’a priori (l’oubli du taux de base) conduit à surestimer énormément P(malade∣+)P(\text{malade} \mid +) pour une maladie rare.
  • Raisonner en effectifs (sur 10 000 personnes) est le moyen le plus sûr de vérifier un calcul.

Exercice · Conditionner sur un dé

facile

On lance deux dés équilibrés. Sachant que la somme vaut 8, quelle est la probabilité que l’un des dés affiche un 6 ? Comparez avec la probabilité, sans condition, qu’au moins un dé affiche un 6.

Voir la solution

Les couples de somme 8 sont (2,6),(3,5),(4,4),(5,3),(6,2)(2,6), (3,5), (4,4), (5,3), (6,2) : 5 couples équiprobables. Deux d’entre eux contiennent un 6. Donc :

P(un 6∣somme=8)=P(un 6 et somme=8)P(somme=8)=2/365/36=25=0,4P(\text{un 6} \mid \text{somme} = 8) = \frac{P(\text{un 6 et somme} = 8)}{P(\text{somme} = 8)} = \frac{2/36}{5/36} = \frac{2}{5} = 0{,}4

Sans condition, P(au moins un 6)=11/36≈0,306P(\text{au moins un 6}) = 11/36 \approx 0{,}306 (chapitre 1). L’information « la somme vaut 8 » augmente donc la probabilité d’avoir un 6.

En code

import numpy as np
# Les 36 couples équiprobables
d1, d2 = np.meshgrid(np.arange(1, 7), np.arange(1, 7))
somme_8 = (d1 + d2 == 8)
un_six = (d1 == 6) | (d2 == 6)
# P(un 6 | somme = 8) = P(un 6 et somme = 8) / P(somme = 8)
print(np.sum(un_six & somme_8) / np.sum(somme_8)) # 0.4
print(np.mean(un_six)) # 0.3056 (11/36, sans condition)

Exercice · Un filtre anti-spam

moyen

Dans une boîte de réception, 40 % des courriels sont des spams. Le mot « gratuit » apparaît dans 25 % des spams et dans 2 % des courriels légitimes. Un courriel contient « gratuit » : quelle est la probabilité que ce soit un spam ? Et s’il ne le contient pas ?

Voir la solution

Notons SS = « spam » et GG = « contient gratuit ». Par les probabilités totales :

P(G)=0,4×0,25+0,6×0,02=0,1+0,012=0,112P(G) = 0{,}4 \times 0{,}25 + 0{,}6 \times 0{,}02 = 0{,}1 + 0{,}012 = 0{,}112

Par Bayes : P(S∣G)=0,1/0,112≈0,893P(S \mid G) = 0{,}1 / 0{,}112 \approx 0{,}893.

Sans le mot : P(Gˉ)=1−0,112=0,888P(\bar{G}) = 1 - 0{,}112 = 0{,}888 et P(S∩Gˉ)=0,4×0,75=0,3P(S \cap \bar{G}) = 0{,}4 \times 0{,}75 = 0{,}3, donc P(S∣Gˉ)=0,3/0,888≈0,338P(S \mid \bar{G}) = 0{,}3 / 0{,}888 \approx 0{,}338.

Le mot fait passer la probabilité de spam de 40 % à 89 % ; son absence ne la fait descendre qu’à 34 %, car la plupart des spams ne contiennent pas ce mot. Un vrai filtre combine des centaines de mots : c’est le principe du Bayes naïf.

En code

p_spam = 0.40
p_g_spam, p_g_legit = 0.25, 0.02 # P(G | S) et P(G | non S)
# Probabilités totales, puis Bayes
p_g = p_spam * p_g_spam + (1 - p_spam) * p_g_legit
print(p_g) # 0.112
print(p_spam * p_g_spam / p_g) # 0.8929 P(S | G)
print(p_spam * (1 - p_g_spam) / (1 - p_g)) # 0.3378 P(S | non G)

Exercice · Trois portes

difficile

Dans un jeu télévisé, une voiture est cachée derrière l’une de trois portes, au hasard. Vous choisissez la porte 1. L’animateur, qui sait où est la voiture, ouvre toujours une porte non choisie qui cache une chèvre ; s’il a le choix, il tire au sort. Il ouvre la porte 3. Avez-vous intérêt à changer pour la porte 2 ? Justifiez avec la formule de Bayes, puis écrivez une simulation R.

Voir la solution

Notons ViV_i = « la voiture est derrière la porte ii », avec P(Vi)=1/3P(V_i) = 1/3, et O3O_3 = « l’animateur ouvre la porte 3 ». Les vraisemblances sont :

  • si V1V_1 : il peut ouvrir 2 ou 3, il tire au sort, donc P(O3∣V1)=1/2P(O_3 \mid V_1) = 1/2 ;
  • si V2V_2 : il est obligé d’ouvrir la 3, donc P(O3∣V2)=1P(O_3 \mid V_2) = 1 ;
  • si V3V_3 : il n’ouvre jamais la porte de la voiture, donc P(O3∣V3)=0P(O_3 \mid V_3) = 0.

Par les probabilités totales, P(O3)=13(12+1+0)=12P(O_3) = \tfrac{1}{3}\left(\tfrac{1}{2} + 1 + 0\right) = \tfrac{1}{2}. Par Bayes :

P(V1∣O3)=12×1312=13,P(V2∣O3)=1×1312=23P(V_1 \mid O_3) = \frac{\tfrac{1}{2} \times \tfrac{1}{3}}{\tfrac{1}{2}} = \frac{1}{3}, \qquad P(V_2 \mid O_3) = \frac{1 \times \tfrac{1}{3}}{\tfrac{1}{2}} = \frac{2}{3}

Il faut changer : on gagne alors deux fois sur trois. L’intuition « une chance sur deux » oublie que le choix de l’animateur dépend de la position de la voiture, donc apporte de l’information.

En code

import numpy as np
rng = np.random.default_rng(0)
n = 100_000
gagne_en_changeant = 0
for _ in range(n):
voiture = rng.integers(1, 4)
choix = 1
# portes que l'animateur peut ouvrir : ni la nôtre, ni celle de la voiture
possibles = [p for p in (1, 2, 3) if p not in (choix, voiture)]
ouverte = rng.choice(possibles) # tirage au sort s'il y en a deux
nouveau = ({1, 2, 3} - {choix, ouverte}).pop() # on change de porte
gagne_en_changeant += (nouveau == voiture)
print(gagne_en_changeant / n) # 0.6670, proche de 2/3

(On passe par possibles[sample(length(possibles), 1)] car sample(x, 1) se comporte différemment quand x est un seul nombre : il tirerait alors dans 1:x.)