ML Model Monitoring expliqué simplement (avec schémas et vrai code)
ML Model Monitoring : l'essentiel en un article — vrai code, schémas et étapes concrètes, extraits d'un cours de 24 leçons.
Un guide qui va droit au but : ML Model Monitoring décortiqué avec des schémas, des exemples concrets et des commandes testées. Tout vient d'un cours structuré de 7 chapitres — en voici le meilleur.
- Introduction ML Monitoring
- Data Drift
- Model Drift et performance
- Outils du marche
- Monitoring en production
Configurer les alertes Prometheus, Slack et PagerDuty
Objectifs pédagogiques
- Écrire des règles d'alerte Prometheus (
alerting_rules.yml) sur des KPI ML - Configurer Alertmanager pour router vers Slack et PagerDuty
- Distinguer alerte warning et alerte critical par sévérité
- Mettre en place du regroupement (
group_by) et de l'inhibition - Réduire la fatigue d'alerte avec
for, seuils et silences
De la métrique à l'alerte : la chaîne complète
Une métrique exposée sur /metrics ne sert à rien si personne ne la regarde à 3 h du matin. La chaîne d'alerting relie une valeur numérique à une action humaine. Elle comporte quatre maillons.
1. Exporter la métrique
Votre service ML publie des Gauge et Counter : score de drift, latence p95, taux d'erreur, accuracy glissante.
2. Évaluer la règle
Prometheus évalue périodiquement des expressions PromQL. Quand l'expression reste vraie pendant for, l'alerte passe de pending à firing.
3. Router l'alerte
Alertmanager reçoit les alertes firing, les regroupe, les déduplique et choisit le receiver selon les labels.
4. Notifier l'humain
Le receiver envoie un message Slack (warning) ou déclenche un PagerDuty avec astreinte (critical).
Écrire des règles d'alerte ML dans Prometheus
Les règles vivent dans un fichier YAML chargé par Prometheus via rule_files. Pour un modèle en production, on surveille trois familles : le drift des données, la dégradation de performance, et la santé infra (latence, erreurs).
| Levier | Effet |
|---|---|
for: 15m | Élimine les pics transitoires, n'alerte que sur les dérives soutenues |
| Inhibition | Si l'API est down, on n'alerte pas aussi sur le drift (cause racine unique) |
| Silences | Pendant un retraining planifié, on coupe les alertes drift temporairement |
| Seuils calibrés | Seuils issus de l'historique, pas de valeurs arbitraires copiées d'un tutoriel |
Les 3 piliers du monitoring ML
Chapitre 00 • Leçon 02 • Durée : 45 min
- Identifier les 3 catégories de métriques à surveiller
- Comprendre quelles métriques mesurer selon le type de modèle
- Établir une roadmap progressive d'instrumentation
- Connaître les bonnes pratiques de logging ML
1. Vue d'ensemble : les 3 piliers
┌─────────────────────────────────────────────────────────────┐ │ MONITORING ML EN PRODUCTION │ └─────────────────────────────────────────────────────────────┘ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ PILIER 1 │ │ PILIER 2 │ │ PILIER 3 │ │ Système │ │ Données │ │ Modèle │ │ (infra) │ │ (data + drift) │ │ (performance) │ └────────────────┘ └────────────────┘ └────────────────┘ - Latence - Distribution X - Accuracy - QPS - Valeurs manqu. - F1, AUC - CPU/Mémoire - Outliers - Calibration - Erreurs 5xx - Drift KS/PSI - Business KPI
2. Pilier 1 — Monitoring système (infra)
C'est le monitoring classique des applications, identique à n'importe quelle API REST.
| Métrique | Outils | Seuil typique |
|---|---|---|
| Latence p50/p95/p99 | Prometheus, Datadog, CloudWatch | p99 < 500 ms |
| QPS (Queries Per Second) | Prometheus, ALB metrics | Suivre tendance |
| Taux d'erreur HTTP (5xx) | Prometheus, CloudWatch | < 0.1 % |
| CPU / Mémoire | cAdvisor, Datadog | < 80 % |
| GPU usage (si applicable) | NVIDIA DCGM, Prometheus | < 90 % |
| Disk I/O | node_exporter | — |
| Saturation queue (Kafka, SQS) | Kafka exporter | < 10k messages |
Spécificité ML : La latence peut exploser sur des modèles deep learning à cause des GPU mal partagés. Toujours mesurer la latence p99, pas juste la moyenne.
3. Pilier 2 — Monitoring des données (entrées)
3.1 Métriques par feature
| Type de feature | Métriques |
|---|---|
| Numérique | Min, max, mean, std, médiane, quantiles, valeurs manquantes |
| Catégorielle | Distribution des classes, nouvelles classes, NULL |
| Texte | Longueur moyenne, vocabulaire, langues détectées |
| Image | Taille, ratio, histogrammes RGB |
| Timestamp | Plages de dates, fréquence par heure du jour |
3.2 Drift detection
| Test statistique | Type de feature | Quand utiliser |
|---|---|---|
| Kolmogorov-Smirnov (KS) | Numérique | Test continu vs distribution de référence |
| Chi-squared (χ²) | Catégorielle | Comparaison de fréquences |
| Population Stability Index (PSI) | Numérique discretisé | Standard finance et banque |
| Wasserstein distance | Numérique | Plus sensible que KS pour grosses distributions |
| Jensen-Shannon divergence | Catégorielle | Comparaison probabiliste |
Détails et code dans le Chapitre 01 leçon 02.
3.3 Qualité des données
4. Pilier 3 — Monitoring du modèle
4.1 Métriques de prédiction (sans labels)
| Métrique | Description |
|---|---|
| Distribution des prédictions | % de chaque classe pour la classification |
| Score de confiance moyen | Indicateur de doute du modèle |
| Entropie des sorties | Plus c'est haut, plus le modèle est incertain |
| Taux d'OOD (Out-of-Distribution) | % d'inputs en dehors de la distribution d'entraînement |
| Taux de fallback / unknown | % de prédictions où le modèle ne sait pas |
4.2 Performance (avec labels)
| Problème | Métriques principales |
|---|---|
| Classification binaire | Accuracy, Precision, Recall, F1, AUC-ROC, AUC-PR |
| Classification multi-classe | Accuracy, F1-macro, F1-weighted, confusion matrix |
| Régression | RMSE, MAE, MAPE, R² |
| Ranking / Recommandation | NDCG, MAP, Recall@k, Precision@k |
| Détection d'anomalies | Precision/Recall sur la classe rare |
| Génération (LLM) | BLEU, ROUGE, perplexité, eval humaine |
4.3 Calibration
Un modèle calibré est un modèle dont les probabilités prédites correspondent aux fréquences réelles. Ex : sur 100 prédictions à 80 % de confiance, ~80 doivent être correctes.
from sklearn.calibration import calibration_curve
import matplotlib.pyplot as plt
prob_pred = model.predict_proba(X_test)[:, 1]
prob_true, prob_pred = calibration_curve(y_test, prob_pred, n_bins=10)
plt.plot([0, 1], [0, 1], 'k--')
plt.plot(prob_pred, prob_true, 'o-')
plt.xlabel('Probabilité prédite')
plt.ylabel('Probabilité observée')
plt.title('Calibration plot')5. Le problème du "delayed feedback"
Souvent, on ne connaît la vérité (le label) que des jours/semaines/mois après la prédiction.
| Cas d'usage | Délai feedback |
|---|---|
| Détection de spam | Quelques minutes (utilisateur signale) |
| Recommandation | Heures (clic) ou jours (achat) |
| Détection de fraude bancaire | Jours à semaines (chargeback) |
| Score crédit | 1-3 ans (défaut de paiement) |
| Prédiction de churn | 30 à 90 jours |
| Diagnostic médical | Semaines à années |
Concepts et causes du data drift
Chapitre 01 • Leçon 01 • Durée : 45 min
- Définir précisément ce qu'est le data drift (et ce qu'il n'est pas)
- Distinguer covariate shift, label shift, et concept drift
- Reconnaître les causes courantes : saisonnalité, événements, bugs en amont
- Établir une stratégie de référence (reference dataset)
1. Définition formelle
Le data drift survient quand la distribution statistique des données en production diffère de celle utilisée pour entraîner le modèle.
P_train(X) ≠ P_prod(X) ou plus généralement : P_train(X, Y) ≠ P_prod(X, Y)
Mathématiquement, on parle de covariate shift quand seule la distribution des features X change, mais la relation P(Y|X) reste identique.
2. Les 3 types de shift
| Type | Définition | Exemple |
|---|---|---|
| Covariate shift | P(X) change, P(Y|X) constant | Modèle santé entraîné sur adultes, en prod on a des seniors. Mais la relation symptômes → maladie est la même. |
| Label shift | P(Y) change, P(X|Y) constant | Détection de spam : 5 % de spams en train, 50 % en prod (campagne massive de phishing). Le profil des spams est similaire mais leur fréquence explose. |
| Concept drift | P(Y|X) change | Reconnaissance de fraude : les fraudeurs s'adaptent, donc même profil = comportement différent. La règle change. |
3. Schéma visuel
Distribution training Distribution production
* *
*** *
***** ***
******* *****
********* vs ********
*********** **********
************* *************
─────────────────── ──────────────────────────
Pas de drift DRIFT DÉTECTÉ
(la distribution s'est décalée)4. Causes principales du data drift
4.1 Saisonnalité
| Domaine | Exemple saisonnier |
|---|---|
| E-commerce | Black Friday (volumes ×10), période de Noël |
| Météo | Temperature features très différentes hiver/été |
| Trafic | Weekend vs jours ouvrés, heures de pointe |
| Tourisme | Été dans l'hémisphère sud vs nord |
| Énergie | Consommation hiver vs été (climatisation/chauffage) |
4.2 Événements externes
4.3 Évolution business
4.4 Bugs et changements techniques (souvent oubliés)
- Pipeline ETL en amont qui change un encoding (UTF-8 vs Latin-1)
- Mise à jour de l'API source qui renvoie des champs en plus/moins
- Fix de bug qui modifie les valeurs en amont (ex: arrondi changé)
- Changement de version d'une lib (numpy 1.x vs 2.x différent)
- Migration de base de données qui altère les types
- Nouveau champ optionnel : NULL en prod, jamais NULL en train
5. Exemple concret en Python — simuler un drift
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
np.random.seed(42)
n_train = 5000
train_age = np.random.normal(35, 10, n_train)
train_age = np.clip(train_age, 18, 80)
train_income = train_age * 1000 + np.random.normal(0, 5000, n_train)
prod_age = np.random.normal(50, 12, n_train)
prod_age = np.clip(prod_age, 18, 80)
prod_income = prod_age * 1000 + np.random.normal(0, 5000, n_train)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
axes[0].hist(train_age, bins=30, alpha=0.5, label='Train', color='blue')
axes[0].hist(prod_age, bins=30, alpha=0.5, label='Production', color='red')
axes[0].axvline(train_age.mean(), color='blue', linestyle='--', label=f'Train moy={train_age.mean():.1f}')
axes[0].axvline(prod_age.mean(), color='red', linestyle='--', label=f'Prod moy={prod_age.mean():.1f}')
axes[0].set_title('Distribution de "age" — covariate shift visible')
axes[0].set_xlabel('Age')
axes[0].legend()
axes[1].hist(train_income, bins=30, alpha=0.5, label='Train', color='blue')
axes[1].hist(prod_income, bins=30, alpha=0.5, label='Production', color='red')
axes[1].set_title('Distribution de "income"')
axes[1].set_xlabel('Income')
axes[1].legend()
plt.tight_layout()
plt.savefig('drift_visualization.png')
plt.show()6. Le concept de "reference dataset"
Pour détecter un drift, il faut comparer à quelque chose de connu. C'est le reference dataset.
| Option | Avantages | Inconvénients |
|---|---|---|
| Dataset d'entraînement | Sample de ce que le modèle a vu | Peut être obsolète (1 an+) |
| Dataset de validation | Indépendant du train | Petit, parfois biaisé |
| Fenêtre glissante prod (semaine passée) | Toujours frais | Drift progressif non détecté |
| Mois précédent | Bon équilibre | Saisonnalité ignorée |
| Mois précédent N-12 (même mois) | Saisonnalité prise en compte | Bouleversements long terme manqués |
Recommandation : Garder 2 références — (1) dataset de validation initial pour le drift "structurel" (2) fenêtre glissante de 30 jours pour le drift "comportemental".
7. Granularité de la détection
| Granularité | Quand l'utiliser |
|---|---|
| Par feature | Identifier précisément quelle variable drifte |
| Multivariée (dataset entier) | Détecte des drifts subtils (corrélations) |
| Par segment (cohorte, géographie) | Détecte des drifts localisés |
| Par time window | Tendance temporelle (jour, semaine, mois) |
8. Fréquence d'analyse
Cet article couvre les extraits les plus utiles — le cours complet ML Model Monitoring (7 chapitres, 24 leçons, exercices corrigés et projet final) t'emmène jusqu'au bout.
./acceder-au-cours-complet cours gratuit : Maîtriser Claude CodeFAQ
Combien de temps pour apprendre ML Model Monitoring ?
Faut-il des prérequis ?
Par où commencer concrètement ?
📬 Tu veux recevoir ce type de guide chaque semaine ? Abonne-toi gratuitement — code réel, zéro blabla.