Files
turf_saas/POD/Intelligence/ML_Predictions_SaaS.md
DevOps Engineer 0492f06bfd docs(HRT-96): Note Intelligence ML + documentation API v1 finale
- Création POD/Intelligence/ML_Predictions_SaaS.md : architecture ML complète,
  flow ml_predictions_cache → ml_feedback_saas → paris → ROI dashboard,
  schéma données/jointures, décision duplication vs modification turf_scraper,
  documentation des 4 stratégies XGBoost, idempotence, usage CLI
- Mise à jour DOCUMENTATION.md : ajout section Turf SaaS API v1 complète
  avec tous les endpoints documentés dont /api/v1/roi/* et /api/v1/ml/feedback/*
  (HRT-92 ROI backend + HRT-93 ML feedback loop)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-30 21:28:52 +02:00

11 KiB
Raw Blame History

Note Intelligence — Système ML Prédictions dans turf_saas

Date de création : 2026-04-30
Auteur : IngenieurDev (H3R7Tech)
Ticket de référence : HRT-96 (sprint ML SaaS — HRT-90)
Scope : /home/h3r7/turf_saas/ — AUCUNE modification de /home/h3r7/turf_scraper/


1. Contexte & Décision architecturale

1.1 Deux systèmes, deux DB

H3R7Tech exploite deux dépôts séparés :

Dépôt Rôle Base de données
/home/h3r7/turf_scraper/ Scraping PMU + entraînement XGBoost turf.db
/home/h3r7/turf_saas/ SaaS utilisateurs + API v1 + dashboard turf_saas.db

1.2 Décision de duplication (vs modification turf_scraper)

Choix : dupliquer les tables et scripts ML dans turf_saas.db, sans toucher à turf_scraper.

Justification :

  • turf_scraper est la source de vérité du scraping PMU et des modèles XGBoost — toute modification risque de casser la chaîne de collecte de données.
  • turf_saas doit fonctionner de manière autonome, avec ses propres utilisateurs, subscriptions et données.
  • La table ml_predictions_cache est pré-peuplée dans turf_saas.db par un processus de synchronisation (scheduler ou copie périodique depuis turf.db).
  • Le feedback loop (ml_feedback_saas.py) écrit dans paris de turf_saas.db uniquement.

2. Architecture du système ML dans turf_saas

2.1 Vue d'ensemble du flow

[turf_scraper/turf.db]
    └── ml_predictions_cache (XGBoost v1)
            │
            │  [sync périodique / scheduler]
            ▼
[turf_saas/turf_saas.db]
    ├── ml_predictions_cache  ← prédictions XGBoost importées
    ├── pmu_partants           ← données courses PMU
    ├── pmu_rapports           ← dividendes réels PMU
    ├── paris                  ← paris virtuels ML (ml_feedback_saas.py)
    │
    └── API v1 ──┬── GET /api/v1/predictions/*    (lecture ml_predictions_cache)
                 ├── GET /api/v1/roi/by-model      (jointure paris + rapports)
                 ├── POST /api/v1/ml/feedback/run  (déclenche ml_feedback_saas)
                 └── GET /api/v1/ml/feedback/stats (stats par stratégie)
                          │
                          ▼
               [dashboard_saas.html]
                  Section "Performance & ROI"
                  Chart.js — ROI par modèle / évolution

2.2 Table ml_predictions_cache (turf_saas.db)

Table centrale du système ML. Contient les prédictions XGBoost pour chaque cheval/course.

Colonne Type Description
date TEXT Date de la course (YYYY-MM-DD)
num_reunion INTEGER Numéro de réunion
num_course INTEGER Numéro de course
horse_name TEXT Nom du cheval
horse_number INTEGER Numéro du cheval
odds REAL Cote au moment de la prédiction
prob_top1 REAL Probabilité XGBoost de finir 1er
prob_top3 REAL Probabilité XGBoost de finir top 3
ml_score REAL Score ML composite (0100)
recommendation TEXT top1 / top3 / value_bet
is_value_bet INTEGER 1 si value bet détecté
is_outlier INTEGER 1 si outlier de cote
race_label TEXT Ex: R1C3
model_version TEXT Version du modèle (ex: xgboost_v1)
risque_label TEXT Niveau de risque (low/neutral/high)
risque_score INTEGER Score risque (0100)

Contrainte d'unicité : (date, num_reunion, num_course, horse_name) — garantit l'idempotence des imports.

Volume actuel : ~1 000 entrées (2 dates de courses).


3. Feedback Loop ML — ml_feedback_saas.py

3.1 Rôle

Script Python autonome qui :

  1. Lit les prédictions XGBoost dans ml_predictions_cache de turf_saas.db
  2. Génère des paris virtuels selon 4 stratégies XGBoost
  3. Insère les paris dans la table paris de turf_saas.db
  4. Est idempotent : ne duplique pas les paris existants

3.2 Stratégies supportées

Stratégie Type pari Condition sélection Mise
xgboost_sg simple_gagnant top 1 ML par course, ml_score >= 70 1€
xgboost_value simple_gagnant is_value_bet = 1 1€
xgboost_sp simple_place top 1 ML par course, ml_score >= 50 1€
xgboost_2sur4 deux_sur_quatre top 4 ML par course, 6 combos générés 6€ (1€/combo)

3.3 Schéma d'idempotence

# Vérifie avant insertion
SELECT id FROM paris
WHERE date_course = ?
  AND source_reco = ?    # ex: 'xgboost_sg'
  AND type_pari = ?
  AND numero1 = ?
  AND race_label = ?

Si le pari existe déjà → skip (aucune duplication).

3.4 Table paris — colonnes clés pour le ML

Colonne Valeur ML
source_reco xgboost_sg / xgboost_value / xgboost_sp / xgboost_2sur4
model_source xgboost_v1 (héritée de ml_predictions_cache)
type_pari simple_gagnant / simple_place / deux_sur_quatre
statut EN_ATTENTEGAGNE / PERDU (mise à jour par update_paris_results.py)
gain Dividende réel × mise (depuis pmu_rapports)

3.5 Usage CLI

# Traitement du jour
python3 ml_feedback_saas.py

# Date spécifique
python3 ml_feedback_saas.py --date 2026-04-29

# Backfill
python3 ml_feedback_saas.py --backfill 2026-04-20

Différence avec turf_scraper/ml_feedback.py :

  • DB_PATH = /home/h3r7/turf_saas/turf_saas.db (PAS /home/h3r7/turf_scraper/turf.db)
  • Logs dans /home/h3r7/turf_saas/logs/
  • AUCUNE référence à turf_scraper

4. API ROI — /api/v1/roi/*

4.1 Route principale

GET /api/v1/roi/by-model — Calcul du ROI par modèle/stratégie

Jointures SQL :

-- paris  ←→  pmu_partants  (via race_label + date + numero)
-- paris  ←→  pmu_rapports  (dividendes réels)

SELECT
    p.source_reco        AS model_source,
    COUNT(p.id)          AS nb_paris,
    SUM(p.mise)          AS mise_totale,
    SUM(p.gain)          AS gain_total,
    (SUM(p.gain) - SUM(p.mise)) / SUM(p.mise) * 100  AS roi_pct,
    COUNT(CASE WHEN p.statut='GAGNE' THEN 1 END) * 100.0 / COUNT(p.id)  AS win_rate
FROM paris p
WHERE p.date_course BETWEEN :start AND :end
  AND (:strategy IS NULL OR p.source_reco = :strategy)
GROUP BY p.source_reco

Paramètres query :

  • ?strategy=xgboost_sg — filtrer par stratégie (optionnel)
  • ?days=30 — fenêtre temporelle en jours (défaut : 30, max : 365)

Réponse JSON :

{
  "period": {"start": "2026-04-01", "end": "2026-04-30", "days": 30},
  "models": [
    {
      "model_source": "xgboost_sg",
      "nb_paris": 42,
      "mise": 42.0,
      "gain": 51.3,
      "roi_pct": 22.1,
      "win_rate": 28.6
    }
  ]
}

Accès plan :

  • free : 1 stratégie max
  • premium : complet
  • pro : complet + historique illimité

4.2 Blueprint api_v1/routes/roi.py

Enregistré dans api_v1/__init__.py avec :

from .routes.roi import roi_bp
app.register_blueprint(roi_bp)

5. API ML Feedback — /api/v1/ml/feedback/*

5.1 Routes

Méthode Path Auth Description
POST /api/v1/ml/feedback/run Admin Déclenche ml_feedback_saas.py manuellement
GET /api/v1/ml/feedback/stats Premium+ Stats paris par stratégie XGBoost

5.2 POST /api/v1/ml/feedback/run

  • Réservé aux admins (token admin requis)
  • Déclenche le script ml_feedback_saas.py en subprocess
  • Corps optionnel : {"date": "2026-04-29"} ou {"backfill": "2026-04-20"}

5.3 GET /api/v1/ml/feedback/stats

Retourne les statistiques agrégées par stratégie :

{
  "stats": [
    {
      "source_reco": "xgboost_sg",
      "nb_paris": 42,
      "nb_gagnes": 12,
      "win_rate_pct": 28.6,
      "mise_totale": 42.0,
      "gain_total": 51.3,
      "roi_pct": 22.1
    }
  ],
  "last_run": "2026-04-29T18:30:00"
}

5.4 Blueprint api_v1/routes/ml_feedback.py

Enregistré dans api_v1/__init__.py avec :

from .routes.ml_feedback import ml_feedback_bp
app.register_blueprint(ml_feedback_bp)

6. Jointures de données — Schéma complet

ml_predictions_cache
    date, num_reunion, num_course, horse_name, horse_number
    ml_score, recommendation, is_value_bet
    race_label, model_version
         │
         │ [ml_feedback_saas.py]
         ▼
       paris
    date_course, race_label, numero1
    source_reco (= stratégie XGBoost)
    model_source (= xgboost_v1)
    type_pari, mise, statut, gain
         │
         ├──── JOIN pmu_partants ──── date_programme + num_reunion + num_course + num_pmu
         │         ordre_arrivee (résultat réel)
         │
         └──── JOIN pmu_rapports ──── date_programme + num_reunion + num_course + type_pari
                   dividende_euro (gain réel calculé)

7. Dashboard SaaS — Section ROI

Le dashboard dashboard_saas.html intègre une section "Performance & ROI" (implémentée dans HRT-94) :

  • Graphique ROI par model_source (histogramme Chart.js)
  • Évolution ROI dans le temps (line chart, 7j/30j/90j)
  • Tableau : model_source | nb paris | mise | gain | ROI% | win_rate%
  • Filtre dropdown par stratégie
  • Gating plan : Free = 1 stratégie, Premium/Pro = complet

Appel API dashboard :

fetch('/api/v1/roi/by-model?days=30')

8. Points d'attention & limites

  1. Données ML limitées : actuellement 1 000 prédictions sur 2 dates (2026-04-24 et 2026-04-25). La pertinence du ROI augmentera avec le volume de données.

  2. Pas de paris XGBoost actifs : la table paris contient des paris manual, scoring_v2, canalturf mais pas encore de paris xgboost_*. HRT-93 (ml_feedback_saas.py) doit être complété et exécuté.

  3. Modèle unique : model_version = 'xgboost_v1'. L'évolution vers des versions de modèle multiples est prévue dans la roadmap.

  4. Sync turf_scraper → turf_saas : le mécanisme de synchronisation de ml_predictions_cache n'est pas encore documenté formellement. À documenter dans une prochaine Note Intelligence.

  5. update_paris_results.py : script de mise à jour des statuts paris (EN_ATTENTE → GAGNE/PERDU) à partir de pmu_rapports — dépendance critique pour le calcul du ROI réel.


9. Fichiers clés

Fichier Rôle
turf_saas.db Base de données principale SaaS
ml_feedback_saas.py Feedback loop ML (à créer — HRT-93)
api_v1/routes/roi.py Routes API ROI (à créer — HRT-92)
api_v1/routes/ml_feedback.py Routes API feedback (à créer — HRT-93)
api_v1/__init__.py Enregistrement des blueprints
dashboard_saas.html Dashboard SaaS avec section ROI
update_paris_results.py MAJ statuts paris depuis résultats PMU
scoring_v2.py Scoring engine (stratégie scoring_v2)

10. Références tickets

Ticket Description Statut
HRT-90 Orchestration ML SaaS (parent) blocked
HRT-92 Backend: API ROI par modèle in_progress
HRT-93 ML feedback loop ml_feedback_saas in_progress
HRT-94 Frontend: Dashboard ROI in_progress
HRT-95 QA: Tests end-to-end ML + ROI in_progress
HRT-96 Note Intelligence ML + documentation (ce ticket) in_progress