Trois environnements et un frontal SNI au lieu de deux, certificats Let's Encrypt par DNS-01, sept DAGs, index des ADR complété jusqu'à 0020. Les exemples de l'ETL passent en bash et n'utilisent plus l'option --limit, retirée. L'adresse de la machine est masquée dans l'arbre, les ADR 0009 et 0014 portent une note datée sur l'approbation de la production.
102 lines
6.9 KiB
Markdown
102 lines
6.9 KiB
Markdown
# 0005 - Modèle de prédiction de consommation : LightGBM
|
||
|
||
- Statut : accepté
|
||
- Date : 2026-09-17
|
||
|
||
## Contexte
|
||
|
||
Le schéma `prediction` contraint déjà la forme de la solution (deux cibles de régression,
|
||
`consumption_kw` instantané et `consumption_kwh` sur `period_minutes`, un statut
|
||
`insufficient_data` à détecter explicitement), mais aucun modèle n'était choisi. Trois
|
||
contraintes non négociables cadrent le choix, discutées dans l'issue #89 :
|
||
|
||
1. **EC06** (grille de notation individuelle) exige un modèle **entraîné, versionné avec
|
||
MLflow**, exposé via un endpoint fonctionnel, avec **surveillance du drift** en production.
|
||
2. **Aucun GPU dédié** : l'infra tourne on-premise sur une VM à 4 CPU / 8 Gio RAM (ou
|
||
`Standard_B2s`/`B2ms` côté Azure, 2 vCPU max) ; Azure Machine Learning est de toute façon
|
||
bloqué par la politique Azure du projet.
|
||
3. **Délai serré** : le jalon J3 arrive à échéance le lendemain de la décision, J4 concentre déjà
|
||
26 issues sur 4 jours. Un modèle long à mettre en œuvre retarde la chaîne complète (service de
|
||
scoring #37, moteur de recommandations #38, tests ML #44/#45, tous bloqués par ce choix).
|
||
|
||
Le jeu de données est déjà disponible (`all_sites_combined.csv`, fourni par le formateur) : 7
|
||
sites, 2 ans au pas horaire (~17 500 lignes/site), avec `temperature_celsius`,
|
||
`humidity_percent`, `solar_irradiance_wm2` en régresseurs exogènes et des features calendaires
|
||
déjà dérivées.
|
||
|
||
## Options comparées
|
||
|
||
| Critère | Prophet | LightGBM/XGBoost | NeuralProphet | SARIMA | Holt-Winters | Mistral (LLM) |
|
||
|---|---|---|---|---|---|---|
|
||
| Saisonnalités multiples (jour/semaine/an) | Oui, nativement | Oui, via features engineered | Oui, nativement, + autorégression | Une seule, lourd à régler (SARIMAX) | Une seule, aucune | Non conçu pour ça |
|
||
| Régresseurs exogènes | Oui, mais doivent être connus dans le futur au moment de la prédiction | Oui, via lags/moyennes glissantes sur le passé | Oui, natif | Difficile en multivarié | Aucun support | Contexte de prompt seulement, non appris |
|
||
| Coût de calcul (VM sans GPU) | Faible | Faible | Élevé (deep learning) | Faible | Faible | Élevé à prohibitif |
|
||
| Versionnable MLflow | Oui, nativement | Oui, nativement | Pas de support direct | Oui, générique | Pas de support direct | Rien à versionner (pas un modèle entraîné) |
|
||
| Granularité | Un modèle par site (ou par site × métrique) | Un seul modèle global sur tous les sites | Un par site | Un par site | Un par site | - |
|
||
| Effort avant l'échéance | Faible | Moyen (feature engineering) | Élevé | Moyen à élevé | Faible en soi | Élevé, ou factice |
|
||
|
||
## Décision
|
||
|
||
**LightGBM, un seul modèle global** couvrant tous les sites, plutôt qu'un modèle par site
|
||
(Prophet) ou par famille de site. Cible : `consumption_kwh`, avec `period_minutes` comme feature
|
||
d'entrée plutôt que comme étape d'agrégation post-prédiction. Suivi et versioning via **MLflow**
|
||
(tracking + registre de modèles), sur le magasin local par défaut dans un premier temps ;
|
||
l'hébergement sur l'infra k3s reste une question ouverte, non bloquante pour démarrer.
|
||
|
||
Raisons retenues, au-delà du tableau ci-dessus :
|
||
|
||
- **Un modèle global plutôt qu'un modèle par site** évite la fragilité des sites les moins
|
||
fournis en historique : ils bénéficient de ce qu'apprennent les autres sites, ce qu'un Prophet
|
||
par site ne permet pas.
|
||
- **Aucune dépendance à une prévision météo future.** Prophet exige que ses régresseurs
|
||
(`add_regressor`) soient connus au moment prédit ; `temperature_celsius`,
|
||
`humidity_percent` et `solar_irradiance_wm2` sont des mesures passées, pas des prévisions, et
|
||
aucune source de prévision météo n'existe dans le projet. LightGBM s'en sort avec des features
|
||
de lag/moyenne glissante calculées sur l'historique déjà présent dans `reading`, cf.
|
||
`ml/enervision_ml/features.py`, un choix qui vaut aussi bien à l'entraînement qu'au futur
|
||
scoring.
|
||
- **Apprentissage direct sur `consumption_kwh`** avec `period_minutes` en feature, sans étape
|
||
d'agrégation intermédiaire que la sortie continue de Prophet aurait demandée.
|
||
- **Coût de calcul compatible avec l'infra on-premise sans GPU.**
|
||
|
||
Débat complet, comparatif détaillé et décision finale : issue #89 (Johan, phyri0s,
|
||
ValentinDeFaria), actée en réunion d'équipe du 2026-09-17 et validée par l'ensemble de l'équipe.
|
||
|
||
## Conséquences
|
||
|
||
- Le pipeline d'entraînement (`ml/`, ce commit) lit `reading` + `site` par connexion PostgreSQL
|
||
directe et construit ses features par lags/moyennes glissantes plutôt que par régresseurs
|
||
contemporains, cf. `docs/ML-START.md`.
|
||
- Le rôle PostgreSQL dédié `enervision_ml` (lecture seule sur `reading`/`site`) n'est pas encore
|
||
provisionné : dette déjà assumée par l'ADR 0003 pour les comptes ETL/ML, `ML_DATABASE_URL`
|
||
pointe pour l'instant vers la même base que le backend applicatif en développement.
|
||
- Le service de scoring (#37), le moteur de recommandations (#38) et les tests de dérive
|
||
(#44/#45) restent à construire ; ils consommeront le même module `enervision_ml.features`, qui
|
||
doit rester strictement identique entre entraînement et scoring pour éviter un train/serve skew
|
||
silencieux.
|
||
- La surveillance de drift exigée par EC06 n'est pas encore implémentée : ce ticket ne livre que
|
||
l'entraînement et son suivi MLflow (paramètres, métriques, artefact modèle), pas le monitoring
|
||
en production.
|
||
- L'hébergement de MLflow sur l'infra k3s reste une question ouverte ; le magasin SQLite local
|
||
(`ml/mlflow.db`, ignoré par git) suffit pour l'instant à comparer des runs sur un poste.
|
||
|
||
## Alternatives écartées
|
||
|
||
- **Prophet** : proposition initiale, écartée après débat pour les raisons ci-dessus (modèle par
|
||
site, dépendance à une météo future indisponible, agrégation kWh en post-traitement). Reste un
|
||
candidat solide si un jour le projet doit produire une décomposition tendance/saisonnalité
|
||
explicable pour un usage différent.
|
||
- **Mistral (LLM)** : aucun produit dédié aux séries temporelles ; interroger un LLM généraliste
|
||
ne constitue pas un modèle entraîné et versionnable au sens MLflow, et le fine-tuning est hors
|
||
budget de calcul et hors délai.
|
||
- **SARIMA** : ne gère pas nativement plusieurs régresseurs exogènes ; réglage (p,d,q,P,D,Q) plus
|
||
long que le délai disponible.
|
||
- **NeuralProphet** : fait tout ce que fait Prophet et apprend en plus des motifs autorégressifs,
|
||
mais coûte plus cher en calcul (pas de GPU disponible) et n'a pas d'outil MLflow direct : piste
|
||
d'évolution possible, non engageante à ce stade.
|
||
- **Holt-Winters** : écarté d'entrée, pas seulement différé : aucun support de régresseurs
|
||
exogènes, alors que la météo et l'irradiance sont nécessaires ici.
|
||
- **CatBoost** : même famille que LightGBM, gère nativement les colonnes catégorielles (comme
|
||
`site_type`) sans encodage manuel. Non rejeté, différé : candidat à comparer si LightGBM
|
||
plafonne en précision.
|