Module 10 — Projet : prévision de demande avec intervalles
Neuf modules de méthodes. Ce dixième module les assemble en un projet complet — le pilotage d'approvisionnement de notre réseau de pharmacies — avec les décisions qui accompagnent la mise en production : le choix argumenté d'un modèle, la production d'intervalles honnêtes par régression quantile, un plan de réentraînement, et la communication des incertitudes au métier.
Le tableau final
Reprenons toutes les évaluations glissantes du module 9 et remplissons la dernière ligne du tableau démarré au module 4.
| Modèle | MAE | RMSE | MASE | Couverture 95 % | Largeur relative |
|---|---|---|---|---|---|
| Naïf | 96,2 | 128,3 | 1,45 | — | — |
| Naïf saisonnier | 62,1 | 84,5 | 1,00 | — | — |
| Recomposition STL | 55,8 | 76,2 | 0,90 | — | — |
| SARIMA(1,1,1)(0,1,1)₇ | 51,4 | 70,1 | 0,83 | 87 % | 1,00 |
| Holt-Winters | 52,7 | 71,9 | 0,85 | 83 % | 0,95 |
| Prophet | 54,2 | 74,3 | 0,87 | 78 % | 1,15 |
| Gradient boosting | 43,8 | 60,7 | 0,71 | 91 % | 0,88 |
| LSTM global (500 séries) | 41,2 | 58,4 | 0,66 | 89 % | 0,85 |
Ces valeurs illustrent des ordres de grandeur typiques ; les vôtres varieront selon la richesse du jeu de données. Deux enseignements se dégagent. Le gradient boosting et le LSTM global sont les meilleurs ici, mais la différence est modeste et la complexité opérationnelle du LSTM (infrastructure GPU, gestion de version, dérives) coûte beaucoup plus. Ensuite, les couvertures des intervalles théoriques à 95 % sont toutes en dessous de 95 %, souvent nettement — c'est la raison d'être de la section suivante.
Choisir un modèle : la méthode
Le meilleur modèle sur le tableau n'est pas forcément celui qu'on met en production. Trois critères pèsent au-delà du score.
Le coût total de possession : coût de calcul, de maintenance, de compétence dans l'équipe. Sur notre fil rouge, un gradient boosting est immédiatement opérable par une équipe data qui connaît scikit-learn ; un LSTM global exige un cycle CI de plus d'une heure et une compétence PyTorch qui n'est pas toujours présente.
La robustesse aux dérives : un modèle qui perd 10 % de performance pendant les six premiers mois d'exploitation est un problème même s'il gagne aujourd'hui. Le gradient boosting du module 7 a montré une remarquable stabilité sur nos douze origines glissantes ; le LSTM a montré une variance plus forte selon la graine.
L'explicabilité : le métier doit comprendre pourquoi le modèle prédit 900 unités et pas 700 aujourd'hui. Un gradient boosting expose une importance de variables claire et permet des explications SHAP par prédiction. Un LSTM est plus opaque.
Sur ces trois critères combinés, notre choix se porte sur le gradient boosting du module 7 enrichi de régresseurs de calendrier. Le LSTM sera gardé comme baseline concurrent, réentraîné trimestriellement pour surveiller si son avance devient significative.
Produire des intervalles par régression quantile
Un gradient boosting standard prédit une moyenne conditionnelle. Pour obtenir des intervalles, on entraîne plusieurs modèles, chacun optimisant une perte quantile différente :
pour par exemple. Cette perte, appelée pinball loss, pénalise asymétriquement selon le quantile visé : le modèle du quantile 0,95 est encouragé à surestimer, celui du 0,05 à sous-estimer, celui du 0,5 est la médiane.
import lightgbm as lgb
def entrainer_quantile(train, variables, tau):
return lgb.LGBMRegressor(
n_estimators=800,
learning_rate=0.03,
num_leaves=64,
min_child_samples=30,
objective="quantile",
alpha=tau,
random_state=42,
).fit(train[variables], train["y"])
modele_q05 = entrainer_quantile(train, variables, tau=0.05)
modele_q50 = entrainer_quantile(train, variables, tau=0.50)
modele_q95 = entrainer_quantile(train, variables, tau=0.95)
previsions = pd.DataFrame({
"q05": modele_q05.predict(test[variables]),
"mediane": modele_q50.predict(test[variables]),
"q95": modele_q95.predict(test[variables]),
}, index=test.index)
# Verification : la mediane doit se trouver entre q05 et q95.
assert (previsions["q05"] <= previsions["mediane"]).all()
assert (previsions["mediane"] <= previsions["q95"]).all()
Un point subtil : les trois modèles étant entraînés indépendamment, il arrive que le modèle 0,95 prédise en dessous du modèle 0,05 sur certains points (croisement des quantiles). L'assertion ci-dessus attrape ce problème ; en pratique, on ordonne les quantiles a posteriori (np.sort par ligne) pour éviter les incohérences.
Calibrer les intervalles
Un intervalle nominal à 90 % (entre les quantiles 0,05 et 0,95) est censé contenir 90 % des observations réelles. En pratique, il en contient souvent 82 à 88 %. La technique de la calibration conforme corrige cela.
L'idée : on tient un lot de calibration (une année, par exemple) sur lequel on mesure la vraie couverture, on calcule l'écart avec la couverture cible, et on élargit les intervalles d'un facteur constant jusqu'à obtenir la couverture souhaitée. Cette procédure, connue sous le nom de quantile conforme, garantit théoriquement la couverture souhaitée à l'échantillon, à condition que la distribution des erreurs reste stationnaire.
def calibrer_intervalles(cal_bas, cal_haut, y_cal, cible=0.90):
# Score de non-conformite : ecart max au-dessus ou en dessous.
scores = np.maximum(cal_bas - y_cal, y_cal - cal_haut)
quantile = np.quantile(scores, cible)
return quantile # a ajouter en marge : haut + q, bas - q
Plan de réentraînement
Un modèle en production dérive — la structure de la série change, de nouveaux produits sont ajoutés, les habitudes évoluent. Trois questions structurent le plan de réentraînement.
À quelle fréquence ? Sur des ventes quotidiennes de pharmacie, un réentraînement hebdomadaire est en général suffisant : la structure se déplace lentement et un cycle de 7 jours permet d'intégrer les nouvelles données récentes sans coûter cher.
Sur quelle fenêtre ? L'expérience empirique conseille de garder au moins 3 ans d'historique (pour capter la saison annuelle deux fois) et d'écarter les données antérieures au dernier grand changement (par exemple avant un changement de gamme). Une fenêtre trop courte perd la saison annuelle, une fenêtre trop longue traîne des régimes obsolètes.
Quel critère de déclenchement d'un réentraînement d'urgence ? Une dérive de MAE de plus de 25 % sur une fenêtre glissante de 4 semaines, mesurée en production en comparant les prévisions passées aux valeurs réelles arrivées entre-temps, doit déclencher une revue. Cette surveillance est indépendante du réentraînement périodique et vise à détecter les cassures brutales.
Communiquer l'incertitude
C'est le point où beaucoup de projets échouent en réunion, indépendamment de la qualité technique. Trois règles utiles.
Ne jamais donner une seule valeur en réponse à un métier qui décide. Toujours accompagner la médiane d'un intervalle (par exemple 80 %) et d'un rappel du niveau naïf. « Nous prévoyons 900 unités demain, entre 750 et 1050 avec 80 % de confiance ; le naïf saisonnier prédirait 830 ». Cette phrase, en trois nombres, informe une décision.
Distinguer incertitude épistémique (mal du modèle) et incertitude aléatoire (bruit irréductible). Une nouvelle promotion sans historique augmente l'incertitude épistémique — le modèle ne connaît pas la situation. Un vendredi 13 augmente l'incertitude aléatoire — même connu, il reste volatil. Le métier saura mieux réagir à un « nous ne savons pas » qu'à un « voici notre meilleure estimation ».
Enfin, documenter les limites : la liste des situations pour lesquelles le modèle est mal calibré (première année d'un nouveau produit, changement de fournisseur, campagne de communication inédite). Cette liste, tenue à jour, est le seul contrat honnête qu'un modèle peut passer avec le métier.
Publier des intervalles présentés comme des « 95 % de couverture théorique » alors qu'ils couvrent 80 % en pratique érode définitivement la confiance quand le métier s'en rend compte. Toujours rapporter la couverture empirique mesurée, jamais la couverture nominale seule. C'est ce qu'attend le module 9 et c'est ce que la production exige.
Un tableau des modèles avec MAE et MASE, une figure d'intervalles calibrés sur 28 jours, une courbe de MAE par horizon, un tableau des importances de variables, et une note d'une page décrivant le plan de réentraînement et les limites connues. Ce dossier, présenté à un comité, suffit à obtenir un budget de mise en production. Rien de plus n'est nécessaire ; rien de moins n'est acceptable.
En résumé
- Le tableau final compare tous les modèles sur les mêmes origines glissantes ; le meilleur score n'est pas toujours le meilleur choix opérationnel.
- Les intervalles par régression quantile (pinball loss) donnent une prévision probabiliste à trois nombres ; la calibration conforme garantit la couverture réelle.
- Le plan de réentraînement définit la fréquence, la fenêtre et le seuil de dérive qui déclenche une revue ; hebdomadaire sur 3 ans est un point de départ raisonnable.
- La communication d'incertitude repose sur trois nombres (médiane, borne basse, borne haute) et une documentation des limites — c'est ce qui fait la différence en production.
Module suivant : la récapitulation du cours et l'annonce de l'examen de 40 questions.