CVN-N001-EI-S14 — LightGBM probability-compression diagnostic (calibration-vs-underfit fork) · hub Story¶
Hub documentaire de la Story S14 (validité de la sortie famille GBDT). Partie du programme CVN-N001-EI. État live = OpenProject (wp#274, GH #1174, ADR-76).
En une phrase¶
s43 a montré que CatBoost étale ses probas BUY jusqu'à ~0.9 alors que LightGBM ne dépasse jamais ~0.30
(≈ le base rate). LightGBM est-il cassé, ou l'écart est-il bénin ? Re-scopé (r3) en deux forks après
un §0bis sur le logging prod (draws non-auditables : metrics={}, artifacts=[], pas de best_iteration) :
- Q1 — validité config/harness (PRÉ-S09, décisif) : fit contrôlé instrumenté sur données de confiance
régime-matchées (le chemin FE-split qui produit le canonique d'A6) → best_iteration réel vs plafond 156,
AUPRC-lift, ECE equal-mass, + ablation métrique d'early-stopping (2×2 cause). Si dégénéré → bug sans S09.
- Q2 — rang/calibration fold-3 (POST-S09, gaté) : sur le replay blanchi, seulement si Q1=CONFIG_OK.
Pourquoi ça compte (et pourquoi AVANT S09)¶
S09 demande « le replay s18 est-il fidèle à la prod ? ». S14 demande la question logiquement
antérieure : « la sortie LightGBM est-elle seulement valide (range-t-elle, est-elle calibrée, a-t-elle
entraîné) ? ». Si LGB sort le prior (best_iter ≈ 1), S09 vérifie la fidélité à une baseline dégénérée
et le verdict GBDT de s43/S05 mesure en partie un modèle non-entraîné. S14 est moins cher (recompute
read-only sur prédictions S3 + métadonnées MLflow ; pas de replay, pas de run cluster) et son signal
best_iter est replay-independent → un verdict partiel tient même avant S09.
Les documents (dans l'ordre de lecture)¶
| # | Document | Quoi | Pour qui | État |
|---|---|---|---|---|
| 1 | Plan dossier (r4) | le quoi & pourquoi — re-scope Q1/Q2 (§0bis pivot), Q1 fit instrumenté sur données de confiance (best_iteration vs plafond + AUPRC-lift + ECE equal-mass + ablation), Q2 S09-gaté, §0-§7 |
décideur, quant, relecteur | ✅ plan_review PASSED·OK (Meeting 272) |
| — | Ticket observabilité (§0bis) | cause racine : draws LGB prod non-auditables (metrics={}, artifacts=[], pas de best_iteration) — GH #1178 |
DRI obs, EK | ✅ filed |
| 2 | Architecture (r1) | Hamilton-native, 2 slices (A=decision core pur, B=fit in-pod) ; contrat FitResult ; le pivot §0bis (ADR-90 → fit in-pod) ; events ; conformité ADR |
ingénieur, archi | ✅ pour revue |
| 3 | Runbook opérateur (r1) | déclencher Q1 (smoke local + run in-pod), lire le verdict + désambiguïsation cause, troubleshooting (ADR-90 in-pod) | opérateur | ✅ pour revue |
| 4 | Stratégie de tests (r1) | exhaustivité truth-table Q1 (slice A 12/12 vert), invariants I1–I7, smoke slice B + dry-run in-pod | dev, QA | ✅ pour revue |
| 5 | MLOps readiness | au merge (ADR-70) | DRI | ⏳ |
Règle de décision (pré-enregistrée — résumé)¶
Q1 (pré-S09, sur données de confiance régime-matchées) — fork config-validity :
| Verdict Q1 | Condition | Action aval |
|---|---|---|
CONFIG_DEGENERATE_LGB (cause=early_stopping) |
best_iteration ≤ 3 alors que plafond best_n_estimators ≫ (≈156) ; ablation métrique ES confirme |
bug trouvé sans S09 ; arm LGB de s43 contaminé à la source, rouvrir ; fix métrique/rounds ES (WA1) |
CONFIG_DEGENERATE_LGB (cause=capacity/feature/label) |
best_iteration ≈ plafond mais AUPRC-lift ≈ hasard (156 arbres qui n'apprennent rien) |
investigation training/features plus profonde |
CONFIG_OK_LGB |
entraîne + AUPRC-lift > hasard | le config tient ; si s43 montrait quand même la compression → fold-3/replay-spécifique → Q2/S09 ; sinon suspicion LGB levée |
INCONCLUSIVE_POWER / INCONCLUSIVE_TOOLING(reason) |
IC trop large / illisible / label mis-aligné / fold non régime-matché | corriger + relancer |
Q2 (post-S09, seulement si Q1=CONFIG_OK) — rang-de-queue (AUPRC/prec@rate, pas l'AUC global) + calibration
(ECE equal-mass, miroir CB-sur-confiant) sur le replay blanchi → RANK_DEFICIT_LGB / CALIBRATION_LGB /
NO_LGB_ANOMALY / INCONCLUSIVE_{POWER,REPLAY_GATED,TOOLING}. Pré-S09 = INCONCLUSIVE_REPLAY_GATED.
État¶
Specified (OP wp#274) — committee plan_review ✅ PASSED·OK (session 3713e74b, Meeting 272,
5 experts, strong consensus, 0 blocker/0 dissent ; 4 recos cheap foldées en r4, reste = follow-ups).
Story créée 2026-06-09 (GH #1174 + OP wp#274 + registre Epic) ; cvn_id S14 (slot S10 = wp#238, non-destructif).
Précède S09 dans l'ordre logique. Transition New → Specified faite 2026-06-10 (forcée, plan_review PASSED — CLAUDE.md §0, précédent S09).
Prochaine étape : Specified → In progress au démarrage impl (single-WIP à vérifier) ; slices A+B déjà sur feat/CVN-N001-EI-S14-lgb-output-validity — Q1 = _data/s14_q1_fit_inpod.py (fit instrumenté, déclenché via Airflow).
Carte de traçabilité¶
problématisation (plan A1) → user stories (A2) → hypothèses H1/H2/H3 (A3) → état de l'art (A4) → consolidation + decision routing (A5) → sections techniques §0-§7.