Une marche aléatoire qui explore les valeurs plausibles des paramètres d'un modèle, en s'attardant là où elles collent le mieux aux données. On obtient non pas un chiffre, mais des milliers de valeurs plausibles : de quoi donner à chaque estimation une fourchette honnête, même sur un petit segment.
Un randonneur dans le brouillard cherche les zones hautes d'un massif. Il fait un pas au hasard : si ça monte, il y va ; si ça descend, il y va parfois. Au bout de milliers de pas, la carte de ses passages dessine le relief.
La vraisemblance dit à quel point des paramètres expliquent les données. L'a priori dit ce qu'on croyait avant de les voir. Leur produit donne la plausibilité de chaque jeu de paramètres, à une constante près.
À chaque itération, on propose un petit pas. Si la proposition est plus plausible, on l'accepte. Sinon, on l'accepte avec une probabilité égale au rapport des plausibilités (règle de Metropolis).
Après une phase de chauffe qu'on jette, les points visités forment un échantillon de la loi a posteriori. Moyenne, médiane, intervalle à 95 % : tout se calcule sur cet échantillon.
Pour chaque contrat : l'âge du conducteur, la zone, la durée d'exposition dans l'année et le nombre de sinistres déclarés. Question du tarificateur : de combien un jeune conducteur urbain est-il plus risqué, et avec quelle certitude ?
Sur le jeu d'exemple, un conducteur de moins de 25 ans a une fréquence environ 3 fois plus élevée (intervalle à 95 % : 2,5 à 3,9) et la zone urbaine multiplie la fréquence par 1,4 environ. Le segment jeune urbain ressort vers 0,42 sinistre par an, entre 0,34 et 0,51.
Avant de lire les résultats, on vérifie le taux d'acceptation (ici autour de 40 %), on lance plusieurs chaînes depuis des points de départ différents et on contrôle qu'elles donnent la même chose (indicateur R-hat proche de 1).
Dans la pratique, on n'écrit pas la chaîne soi-même : Stan (via brms en R) ou PyMC en Python règlent le pas automatiquement avec un échantillonneur plus efficace (NUTS). Les notions restent les mêmes.
Trop petit : presque tout est accepté, mais la chaîne avance à peine. Trop grand : presque tout est refusé. Pour Metropolis, viser 20 à 50 % d'acceptation.
Les premières itérations dépendent du point de départ. On les jette : ici 5 000 sur 20 000.
Lancer au moins 4 chaînes depuis des points différents. Si elles ne se superposent pas, les résultats ne valent rien.
Elle résume ce qu'on sait avant les données. Une loi large laisse parler les données ; une loi serrée stabilise les petits segments, mais doit se justifier devant un auditeur.
# Fréquence de sinistres : MCMC (algorithme de Metropolis) en R
sin <- read.csv("sinistres.csv")
jeune <- as.numeric(sin$age_conducteur < 25)
urbain <- as.numeric(sin$zone == "urbain")
# Log-vraisemblance de Poisson (avec exposition) + a priori normal N(0, 2²) sur chaque paramètre
log_post <- function(b) {
eta <- b[1] + b[2] * jeune + b[3] * urbain + log(sin$exposition)
sum(sin$nb_sinistres * eta - exp(eta)) - sum(b^2) / 8
}
set.seed(42)
b <- c(-2, 0, 0)
lp <- log_post(b)
chaine <- matrix(NA, nrow = 20000, ncol = 3)
for (it in 1:20000) {
prop <- b + rnorm(3, mean = 0, sd = 0.08) # petit pas au hasard
lp_prop <- log_post(prop)
if (log(runif(1)) < lp_prop - lp) { # accepter, ou rester sur place
b <- prop; lp <- lp_prop
}
chaine[it, ] <- b
}
chaine <- chaine[-(1:5000), ] # on jette la phase de chauffe
cat("Effet jeune conducteur (x fréquence), IC 95 % :", round(quantile(exp(chaine[, 2]), c(0.025, 0.5, 0.975)), 2), "\n")
cat("Effet zone urbaine (x fréquence), IC 95 % :", round(quantile(exp(chaine[, 3]), c(0.025, 0.5, 0.975)), 2), "\n")
cat("Fréquence annuelle jeune urbain, IC 95 % :", round(quantile(exp(rowSums(chaine)), c(0.025, 0.5, 0.975)), 3), "\n")
# Fréquence de sinistres : MCMC (algorithme de Metropolis) en Python
import numpy as np
import pandas as pd
sin = pd.read_csv("sinistres.csv")
jeune = (sin["age_conducteur"] < 25).astype(float).values
urbain = (sin["zone"] == "urbain").astype(float).values
n, expo = sin["nb_sinistres"].values, sin["exposition"].values
# Log-vraisemblance de Poisson (avec exposition) + a priori normal N(0, 2²) sur chaque paramètre
def log_post(b):
eta = b[0] + b[1] * jeune + b[2] * urbain + np.log(expo)
return np.sum(n * eta - np.exp(eta)) - np.sum(b ** 2) / 8
rng = np.random.default_rng(42)
b = np.array([-2.0, 0.0, 0.0])
lp, chaine = log_post(b), []
for it in range(20000):
prop = b + rng.normal(0, 0.08, 3) # petit pas au hasard
lp_prop = log_post(prop)
if np.log(rng.uniform()) < lp_prop - lp: # accepter, ou rester sur place
b, lp = prop, lp_prop
chaine.append(b)
chaine = np.array(chaine[5000:]) # on jette la phase de chauffe
print("Taux d'acceptation :", round(np.mean(np.any(np.diff(chaine, axis=0) != 0, axis=1)), 2))
print("Effet jeune conducteur (x fréquence), IC 95 % :", np.round(np.percentile(np.exp(chaine[:, 1]), [2.5, 50, 97.5]), 2))
print("Effet zone urbaine (x fréquence), IC 95 % :", np.round(np.percentile(np.exp(chaine[:, 2]), [2.5, 50, 97.5]), 2))
freq = np.exp(chaine.sum(axis=1))
print("Fréquence annuelle jeune urbain, IC 95 % :", np.round(np.percentile(freq, [2.5, 50, 97.5]), 3))
MCMC signifie Monte Carlo par chaînes de Markov. C'est une famille d'algorithmes qui produisent un échantillon de valeurs plausibles des paramètres d'un modèle bayésien, en se déplaçant pas à pas. Chaque pas ne dépend que de la position actuelle, d'où le terme chaîne de Markov.
Metropolis-Hastings propose un nouveau point et l'accepte ou le refuse selon sa plausibilité. Gibbs met à jour un paramètre à la fois en le tirant directement dans sa loi conditionnelle, sans refus. Les outils modernes comme Stan utilisent plutôt NUTS, une variante de Monte Carlo hamiltonien qui explore bien plus vite.
On lance plusieurs chaînes depuis des points de départ différents et on compare : l'indicateur R-hat doit être très proche de 1, et la taille d'échantillon effective (ESS) suffisante, typiquement plusieurs centaines. Les tracés des chaînes doivent ressembler à un bruit stable, sans tendance.
La règle qui combine a priori et données. MCMC sert à l'appliquer quand le calcul exact est impossible.
Voir la fiche → la version classiqueLe même modèle de fréquence, estimé par maximum de vraisemblance. Plus rapide, fourchettes approchées.
Voir la fiche → le cousinTire des scénarios d'une loi connue. MCMC tire des paramètres d'une loi qu'on ne sait pas calculer directement.
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