feat(ml): replace logistic regression with MLP fusion and KS drift with ADWIN online learning

Replace the LogisticRegression meta-learner with a PyTorch MetaFusionMLP
(Linear(3,16)->BN->ReLU->Dropout->Linear(16,1)->Sigmoid) for non-linear
fusion of EIF, NF, and XGBoost scores. Replace KS-test + quantile digest
drift detection with ADWIN (adaptive sliding window, Hoeffding bound).
Replace weekly XGBoost batch retraining with River HoeffdingAdaptiveTree
for incremental online learning (learn_one per cycle). Update all thesis
documentation sections (2.4.2c, 2.4.3, 3.8, discussion, conclusion).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jacquin Antoine
2026-04-13 16:32:34 +02:00
parent c6cb12981c
commit 7894d39f1c
12 changed files with 502 additions and 306 deletions

View File

@ -23,19 +23,19 @@
## A1 — Détection de dérive conceptuelle
### ✅ IMPLÉMENTÉ
### ✅ IMPLÉMENTÉ (ADWIN)
**Module** : `scoring.py`fonctions `_compute_drift_score()` et `_compute_drift_score_zscore()`
**Module** : `scoring.py`classe `ADWINDriftMonitor` (remplace `_compute_drift_score`)
**Différences avec la proposition initiale** :
| Proposition | Implémentation |
|-------------|----------------|
| KS-test (scipy `ks_2samp`) | Méthode principale : comparaison par quantiles interpolés (KS-like sans scipy). Fallback : z-score `\|μ_current - μ_trained\| / σ_trained > 2.0` |
| Seuil par `p_value < 0.05` | Même seuil p < 0.05 pour la méthode quantile ; z > 2.0 pour le fallback |
| KS-test + quantile digest | ADWIN (fenêtre glissante adaptative, borne de Hoeffding) |
| Seuil par `p_value < 0.05` | Borne de Hoeffding automatique (delta = 0.002) |
| `DRIFT_THRESHOLD` (30%) | ✅ Identique : `DRIFT_THRESHOLD = 0.30` (fraction de features en dérive) |
| Sauvegarde dans `.meta.json` | `baseline_stats` avec `{mean, std, p25, p75}` par feature |
| Événement `DRIFT_DETECTED` | ✅ Journalisé avec la liste des features déroutantes |
| Sauvegarde dans `.meta.json` | ADWIN stateful — pas de sauvegarde nécessaire (fenêtre adaptative) |
| Événement `DRIFT_DETECTED` | ✅ Journalisé avec la liste des features dérivées |
**Appelé depuis** : `models.py``load_or_train_model()`, avant la décision de chargement vs retrain.