Une formule de trois termes qui dit comment réviser une probabilité quand arrive un indice. Elle corrige une erreur de raisonnement très répandue : oublier que l'événement recherché est rare. C'est la base de tous les modèles bayésiens, du filtre anti-spam à la lecture d'un test de dépistage ou d'une alerte fraude.
Une alarme incendie sonne presque toujours en cas de feu, mais aussi, parfois, pour un toast brûlé. Comme les vrais incendies sont très rares, la plupart des alarmes sont des toasts.
La probabilité avant tout indice, ici le taux de fraude : 2 transactions sur 1 000.
L'alerte se déclenche sur 95 % des fraudes, mais aussi sur 3 % des transactions normales. Comme les transactions normales sont environ 500 fois plus nombreuses, elles produisent la grande majorité des alertes.
P(fraude | alerte) = P(alerte | fraude) × P(fraude) / P(alerte). Ici environ 6 % : l'immense majorité des alertes sont fausses. Ce résultat devient l'a priori de l'indice suivant.
Le taux de fraude (0,2 %), la part des fraudes repérées par la règle d'alerte (95 %) et la part des transactions normales qui la déclenchent à tort (3 %). Pas besoin de modèle : ces taux se lisent dans l'historique.
Environ 6 % seulement. Si la transaction a aussi lieu dans un pays jamais visité par le client, la probabilité monte à 66 %. De quoi prioriser le travail des analystes fraude.
Dans l'exemple Python, sur un million de transactions simulées, 6 % des alertes sont de vraies fraudes, comme le prévoit la formule. Le coût réel apparaît aussi : près de 32 000 alertes à traiter pour environ 1 900 fraudes.
Pas d'hyperparamètre : tout se joue sur les probabilités qu'on injecte dans la formule.
Le terme le plus souvent oublié et le plus décisif. Il doit correspondre à la population réellement examinée : le taux de fraude des achats à l'étranger n'est pas celui de l'ensemble des transactions.
Les deux se mesurent sur l'historique. Ici, faire passer les fausses alertes de 3 % à 1 % change bien plus le résultat que faire passer la sensibilité de 95 % à 99 %.
Enchaîner deux mises à jour suppose que les indices sont indépendants une fois la fraude connue. Sinon, on compte deux fois la même information.
# Alertes fraude : théorème de Bayes en R
p_fraude <- 0.002 # a priori : 2 transactions sur 1 000 sont frauduleuses
p_alerte_si_fraude <- 0.95 # la règle repère 95 % des fraudes (sensibilité)
p_alerte_si_normale <- 0.03 # et se déclenche à tort sur 3 % des transactions normales
bayes <- function(a_priori, p_si_fraude, p_si_normale) {
# P(fraude | indice) = P(indice | fraude) x P(fraude) / P(indice)
p_si_fraude * a_priori / (p_si_fraude * a_priori + p_si_normale * (1 - a_priori))
}
apres_alerte <- bayes(p_fraude, p_alerte_si_fraude, p_alerte_si_normale)
cat("P(fraude | alerte) :", round(apres_alerte, 3), "\n")
# Deuxième indice (achat dans un pays jamais visité par le client) : l'a posteriori devient l'a priori
apres_pays <- bayes(apres_alerte, 0.60, 0.02)
cat("P(fraude | alerte + pays inhabituel) :", round(apres_pays, 3), "\n")
# Vérification par simulation sur 1 million de transactions
set.seed(42)
n <- 1e6
fraude <- runif(n) < p_fraude
alerte <- runif(n) < ifelse(fraude, p_alerte_si_fraude, p_alerte_si_normale)
cat("Alertes :", sum(alerte), "| dont vraies fraudes :", sum(fraude & alerte),
"| part :", round(mean(fraude[alerte]), 3), "\n")
# Alertes fraude : théorème de Bayes en Python
import numpy as np
p_fraude = 0.002 # a priori : 2 transactions sur 1 000 sont frauduleuses
p_alerte_si_fraude = 0.95 # la règle repère 95 % des fraudes (sensibilité)
p_alerte_si_normale = 0.03 # et se déclenche à tort sur 3 % des transactions normales
def bayes(a_priori, p_si_fraude, p_si_normale):
# P(fraude | indice) = P(indice | fraude) x P(fraude) / P(indice)
return p_si_fraude * a_priori / (p_si_fraude * a_priori + p_si_normale * (1 - a_priori))
apres_alerte = bayes(p_fraude, p_alerte_si_fraude, p_alerte_si_normale)
print("P(fraude | alerte) :", round(apres_alerte, 3))
# Deuxième indice (achat dans un pays jamais visité par le client) : l'a posteriori devient l'a priori
apres_pays = bayes(apres_alerte, 0.60, 0.02)
print("P(fraude | alerte + pays inhabituel) :", round(apres_pays, 3))
# Vérification par simulation sur 1 million de transactions
rng = np.random.default_rng(42)
n = 1_000_000
fraude = rng.random(n) < p_fraude
alerte = rng.random(n) < np.where(fraude, p_alerte_si_fraude, p_alerte_si_normale)
print("Alertes :", alerte.sum(), "| dont vraies fraudes :", (fraude & alerte).sum(),
"| part :", round(fraude[alerte].mean(), 3))
P(A | B) = P(B | A) × P(A) / P(B). En clair : la probabilité de la cause sachant l'indice est égale à la probabilité de l'indice sachant la cause, multipliée par la probabilité de la cause avant l'indice, divisée par la probabilité totale de l'indice.
L'erreur qui consiste à juger une alerte fiable à 95 % sans tenir compte de la rareté de l'événement. Quand l'événement est rare, même un bon détecteur produit plus de fausses alertes que de vraies. Le théorème de Bayes corrige ce biais.
L'approche fréquentiste traite les paramètres comme des valeurs fixes et raisonne sur la répétition des expériences. L'approche bayésienne décrit l'incertitude sur les paramètres par des probabilités, mises à jour par les données grâce au théorème de Bayes. Les deux coexistent en entreprise.
Applique Bayes à des dizaines de variables en les supposant indépendantes. Rapide et efficace sur le texte.
Voir la fiche → quand les causes s'enchaînentUn graphe qui applique Bayes à de nombreuses variables liées, sans les supposer indépendantes.
Voir la fiche → le calcul bayésien avancéQuand la formule ne se résout plus à la main, on tire des milliers d'échantillons de la loi a posteriori.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus