fix(ml,backend): corrige la revue, le typage du drapeau CSV et la portée du biais

`load_from_csv` gardait un `astype(bool)` sur `is_working_hours`, joué avant `_typer` :
une case vide du CSV arrivait en `NaN` et en ressortait `True`, soit une heure ouvrée
inventée. Le chemin base était corrigé, pas celui-ci, et rien ne le couvrait. La ligne
disparaît, et `_typer` ramène désormais les colonnes de `FLAG_COLUMNS` à `float64` quel
que soit le contenu lu : sans cela le dtype dépendait de l'écriture du fichier (`0`/`1`
contre `True`/`False`) et de la présence d'un trou, et l'égalité de schéma entre les deux
chargeurs que promet ML-START n'était vraie que par accident du jeu de test.

`Seuils.seuil_biais` valait `0` et `_verdict` exigeait `> 0` : la règle était inerte
partout, CLI et DAG compris, et aucun test ne l'exerçait. Elle reste désactivée par
défaut, parce qu'un seuil en kWh ne se transpose pas d'un bureau de 10 kWh à une usine
de 1 000 kWh et qu'aucune valeur n'a été calibrée sur la vraie série, mais `--bias-threshold`
la rend atteignable et l'ADR 0011 porte l'arbitrage. Trois tests couvrent le chemin :
inerte par défaut, dérive au-delà du seuil réglé, et priorité de la MAE sur le biais.

Deux lignes de doc devenues fausses au passage : la signature de `load_recent_from_database`
dans ML-START, qui omettait `until` devenu obligatoire, et la ligne `bias` de 20-backend,
qui laissait croire que la métrique décide du verdict.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Johan LEROY
2026-09-22 16:25:02 +02:00
co-authored by Claude Opus 5
parent f21a843fc2
commit 81c8a67af3
10 changed files with 153 additions and 7 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ Le choix du modèle est dans l'ADR 0005. Ce document ne les répète pas.
|---|---|---|
| `load_from_csv(path)` | `ml/data/all_sites_combined.csv` | Chemin de démarrage, tant que la base n'est pas peuplée |
| `load_from_database(connection)` | `reading` joint à `site`, **historique complet** | Entraînement |
| `load_recent_from_database(connection, since=…)` | `reading` joint à `site`, **borné par `since`** | Scoring |
| `load_recent_from_database(connection, since=…, until=…)` | `reading` joint à `site`, **borné des deux côtés** | Scoring |
L'égalité des schémas n'est pas un confort : c'est ce qui permet de valider tout le pipeline sur
CSV, sans base joignable, et d'obtenir le même comportement une fois la base peuplée. Une