Une méthode pour estimer un modèle quand une information manque : le segment de chaque client, la cause d'une panne, une valeur non renseignée. EM alterne deux étapes simples, deviner l'information cachée puis réestimer le modèle, jusqu'à ce que plus rien ne bouge. C'est le moteur des mélanges gaussiens, des modèles de Markov cachés et de l'imputation de données.
On mélange les sacs de billes de 4 joueurs. Pour retrouver à qui est chaque bille, on devine d'abord les profils de chaque joueur, on estime pour chaque bille la probabilité qu'elle vienne de chaque joueur, on recalcule les profils en pondérant par ces probabilités, et on recommence.
Des paramètres initiaux, même grossiers : 4 segments avec une moyenne et une dispersion chacun, tirés au hasard ou issus d'un K-means.
Avec ces paramètres, on calcule pour chaque client la probabilité d'appartenir à chaque segment. L'information cachée est remplacée par une estimation probabiliste, pas par un choix tranché.
On recalcule les paramètres de chaque segment en pondérant chaque client par sa probabilité d'appartenance. C'est un maximum de vraisemblance ordinaire, rendu possible parce que rien n'est plus caché.
Chaque tour fait monter la vraisemblance, ou la laisse égale. On s'arrête quand elle ne progresse plus.
Panier moyen, achats par mois, récence du dernier achat, nombre de catégories achetées, part des achats en promotion. Le segment de chaque client est l'information cachée que l'on cherche.
Sur le jeu d'exemple, EM isole notamment 316 gros clients fidèles (panier de 151 € en moyenne, 10 achats par mois) et 516 clients très sensibles aux promotions et peu actifs. Chaque client reçoit sa probabilité d'appartenance : seuls 26 sont affectés avec moins de 80 % de certitude.
La log-vraisemblance doit monter à chaque itération puis se stabiliser : partie au hasard, elle plafonne ici après une trentaine de tours. Ensuite, le marketing vérifie que chaque segment est lisible et actionnable.
Noms donnés pour R (mclust) et Python (scikit-learn), pour le cas le plus courant : le mélange gaussien.
EM ne le choisit pas seul. Le critère BIC aide à comparer plusieurs valeurs, mais un segment inutilisable par le métier ne sert à rien, même s'il améliore le BIC.
EM peut s'arrêter sur un optimum local. On part d'un K-means (par défaut dans scikit-learn) ou on relance plusieurs fois et on garde la meilleure vraisemblance.
Segments ronds ou allongés, de même taille ou non. mclust teste plusieurs formes et garde la meilleure au BIC ; scikit-learn utilise « full » par défaut.
EM s'arrête quand la vraisemblance ne progresse plus au-delà d'un seuil. Un message de non-convergence doit faire relancer avec plus d'itérations.
# Segments clients cachés : algorithme EM en R
library(mclust)
clients <- read.csv("clients_segmentation.csv")
variables <- c("panier_moyen", "achats_par_mois", "recence_jours", "nb_categories", "part_promo")
X <- scale(clients[, variables])
# Mélange de 4 segments gaussiens estimé par EM (le BIC choisit la forme des nuages)
modele <- Mclust(X, G = 4)
print(summary(modele))
cat("Log-vraisemblance finale :", round(modele$loglik, 1), "\n")
# Profils moyens des segments, en unités d'origine
clients$segment <- modele$classification
print(round(aggregate(clients[, variables], by = list(segment = clients$segment), FUN = mean), 2))
print(table(clients$segment))
# Étape E : probabilité d'appartenance de chaque client à chaque segment
cat("Clients affectés avec moins de 80 % de certitude :", sum(apply(modele$z, 1, max) < 0.8), "\n")
# Segments clients cachés : algorithme EM en Python
import warnings
import numpy as np
import pandas as pd
from sklearn.mixture import GaussianMixture
from sklearn.preprocessing import StandardScaler
warnings.filterwarnings("ignore") # EM arrêté volontairement à 1 itération
clients = pd.read_csv("clients_segmentation.csv")
variables = ["panier_moyen", "achats_par_mois", "recence_jours", "nb_categories", "part_promo"]
X = StandardScaler().fit_transform(clients[variables])
# EM pas à pas : une itération = étape E (qui appartient à quel segment ?) + étape M (mise à jour des segments)
em = GaussianMixture(n_components=4, max_iter=1, warm_start=True, init_params="random", random_state=42) # départ au hasard, pour voir EM progresser
for it in range(1, 41):
em.fit(X)
if it in (1, 5, 10, 20, 30, 40):
print(f"Itération {it:2d} : log-vraisemblance moyenne {em.score(X):.3f}")
# Résultat : taille des segments, profils moyens, certitude des affectations
proba = em.predict_proba(X)
clients["segment"] = proba.argmax(axis=1)
print(clients.groupby("segment")[variables].mean().round(2).assign(taille=clients["segment"].value_counts()).to_string())
print("Clients affectés avec moins de 80 % de certitude :", int(np.sum(proba.max(axis=1) < 0.8)))
Il estime les paramètres d'un modèle statistique quand une partie des données est inobservée : appartenance à un groupe, état caché, valeur manquante. Il est utilisé pour la segmentation par mélange gaussien, les modèles de Markov cachés, l'imputation de données et certains modèles de traduction ou de reconnaissance vocale.
K-means affecte chaque point à un seul groupe, puis recalcule les centres. EM calcule une probabilité d'appartenance à chaque groupe et estime aussi la dispersion et le poids de chacun. K-means peut se voir comme un cas limite d'EM, avec des groupes ronds, de même dispersion et une affectation tranchée.
Non. Chaque itération améliore la vraisemblance, ou la laisse égale, mais l'algorithme peut s'arrêter sur un optimum local qui dépend du point de départ. On le relance donc plusieurs fois avec des initialisations différentes et on garde la solution de plus forte vraisemblance.
Le modèle de segmentation qu'EM sait estimer. La fiche GMM détaille le choix du nombre de segments.
Voir la fiche → la version tranchéeMême alternance affecter puis recalculer, mais chaque client va entièrement dans un seul groupe.
Voir la fiche → EM dans le tempsSes paramètres s'estiment avec une version d'EM (Baum-Welch), quand l'état caché évolue d'une période à l'autre.
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