361 lines
11 KiB
Markdown
361 lines
11 KiB
Markdown
# Analyse du Modèle Prédictif Turf - Documentation Technique
|
|
|
|
## 1. Vue d'Ensemble du Système
|
|
|
|
### 1.1 Architecture Actuelle
|
|
|
|
Le système de prédiction turf repose sur plusieurs composants:
|
|
|
|
- **Collecte de données**: Scraping PMU (courses, cotes, résultats)
|
|
- **Calcul de scoring**: Agrégation de multiples features par cheval
|
|
- **Génération de recommandations**: Types de paris recommandés avec confiance
|
|
- **Suivi de performance**: Comparaison prédictions vs résultats réels
|
|
|
|
### 1.2 Sources de Données
|
|
|
|
| Source | Tables | Description |
|
|
|--------|--------|-------------|
|
|
| Canalturf | `predictions`, `odds_history` | Cotes et prédictions externes |
|
|
| PMU | `pmu_courses`, `pmu_reunions` | Courses et réunions officielles |
|
|
| Interne | `scoring`, `recommendations` | Scores calculés et recommandations |
|
|
|
|
---
|
|
|
|
## 2. Analyse des Performances Actuelles
|
|
|
|
### 2.1 Métriques Globales
|
|
|
|
| Métrique | Valeur | Interprétation |
|
|
|----------|--------|-----------------|
|
|
| Total prédictions evaluées | 96 | Échantillon encore réduit |
|
|
| Prédictions réussies (hit) | 20 | - |
|
|
| **Taux de réussite global** | **20.83%** | En dessous du aléatoire (25% pour top 4) |
|
|
| 1er prédit = 1er réel | 1 | 42.86% de précision pour le favori |
|
|
| Chevaux dans le top 3 | 14 | 14.58% dans le top 3 |
|
|
|
|
### 2.2 Analyse par Rang Prédit
|
|
|
|
| Rang prédit | Total | Hits | Taux de réussite |
|
|
|-------------|-------|------|-------------------|
|
|
| 0 (non classé) | 69 | 9 | 13.04% |
|
|
| 1 (favori) | 7 | 3 | **42.86%** |
|
|
| 2 | 10 | 3 | 30.00% |
|
|
| 3 | 10 | 5 | **50.00%** |
|
|
|
|
**Observations:**
|
|
- Le rang 3 a le meilleur taux (50%) - possible sur-optimisation
|
|
- Les favoris (rang 1) ont 42.86% de réussite
|
|
- La catégorie "non classé" (rang 0) représente 71.8% des prédictions
|
|
|
|
### 2.3 Problemes Identifiés
|
|
|
|
1. **Volume insuffisant**: Seulement 96 prédictions evaluées
|
|
2. **Catégorie 0 trop large**: 69 prédictions non classifiées
|
|
3. **Pas de suivi des résultats**: Table `recommendations` n'avait pas de résultats (0/32) → **CORRIGÉ**
|
|
4. **Déséquilibre des données**: Majorité de prédictions en rang 0
|
|
|
|
### 2.4 Analyse du Rang 0 (Résolu)
|
|
|
|
**Cause racine identifié:**
|
|
- `canalturf_partants`: 356 prédictions (tous les partants, rank 0 par défaut)
|
|
- `canalturf_selections`: 165 prédictions (sélections supplémentaires, rank 0)
|
|
- `canalturf_prono_*`: 198 prédictions avec rank 1/2/3 (vraies prédictions)
|
|
|
|
**Solution:** Les prédictions avec rank 0 ne doivent PAS être incluses dans l'évaluation de performance.
|
|
Seuls les ranks 1 (bases), 2 (chances), 3 (outsiders) constituent les vraie prédictions.
|
|
|
|
### 2.5 Résultats des Recommandations (Mise à jour)
|
|
|
|
Après mise à jour automatique:
|
|
| Résultat | Count |
|
|
|----------|-------|
|
|
| GAGNE | 6 |
|
|
| PERDU | 14 |
|
|
|
|
**Taux de réussite: 30%**
|
|
**ROI: -70%** (à affiner avec analyse des cotes)
|
|
|
|
### 2.6 Modèle XGBoost - Résultats
|
|
|
|
Après entraînement sur 4 902 lignes de données historiques:
|
|
|
|
| Modèle | CV AUC | Amélioration vs random |
|
|
|--------|--------|----------------------|
|
|
| Top 1 (gagnant) | **0.697** | +19.7% |
|
|
| Top 3 (placé) | **0.715** | +21.5% |
|
|
|
|
**Top Features (par importance):**
|
|
1. `cote_directe` - La cote est le predictor le plus important
|
|
2. `rang_cote` - Classement par cote
|
|
3. `implied_prob` - Probabilité implicite (1/cote)
|
|
4. `ratio_cote_field` - Ratio cote vs moyenne du field
|
|
5. `tx_victoire` - Taux de victoire historique
|
|
6. `forme_recente` - Forme récente du cheval
|
|
|
|
**Fichiers générés:**
|
|
- `xgboost_models.pkl` - Modèles entraînés
|
|
- `feature_importance_top1.csv` - Importance des features pour top1
|
|
- `feature_importance_top3.csv` - Importance des features pour top3
|
|
|
|
---
|
|
|
|
## 3. Structure des Données
|
|
|
|
### 3.1 Tables Principales
|
|
|
|
#### `predictions` (739 lignes)
|
|
```sql
|
|
-- Prédictions brutes avant scoring
|
|
date, race_name, race_hippodrome, race_time,
|
|
horse_number, horse_name, odds, prediction_rank, source
|
|
```
|
|
|
|
#### `scoring` (123 lignes)
|
|
```sql
|
|
-- Score composite calculé par cheval
|
|
score = f(score_cote, score_forme, score_victoire, score_place,
|
|
score_rk, score_tendance, score_avis)
|
|
|
|
-- Features individuelles:
|
|
score_cote -- Score basé sur la cote
|
|
score_forme -- Score basé sur la forme récente
|
|
score_victoire -- Taux de victoire historique
|
|
score_place -- Taux de placé historique
|
|
score_rk -- Classement rank
|
|
score_tendance -- Tendance de la cote
|
|
score_avis -- Avis de l'entraîneur
|
|
```
|
|
|
|
#### `historical_data` (5 536 lignes)
|
|
```sql
|
|
-- Données historiques enrichies
|
|
date, hippodrome, distance, discipline, allocation
|
|
horse_name, horse_number, driver, age, sexe
|
|
musique, nb_courses, nb_victoires, nb_places
|
|
gains_carriere, gains_annee, reduction_km
|
|
avis_entraineur, oeilleres, deferre
|
|
cote_directe, cote_reference, est_favori
|
|
tx_victoire, tx_place, forme_recente, tendance_forme
|
|
ordre_arrivee, top1, top3, top5 -- Variables cibles
|
|
```
|
|
|
|
#### `recommendations` (32 lignes)
|
|
```sql
|
|
-- Recommandations de paris
|
|
type_pari: simple_gagnant, simple_place, couple_gagnant, couple_place
|
|
cheval1, numero1, cheval2, numero2
|
|
cote, mise, gain_potentiel, confiance, justification
|
|
```
|
|
|
|
### 3.2 Couverture des Données
|
|
|
|
| Métrique | Valeur |
|
|
|----------|--------|
|
|
| Période couverte | 2025-03-19 à 2026-03-18 |
|
|
| Nombre de jours de courses | 364 |
|
|
| Hippodromes différents | 45 |
|
|
| Disciplines | 5 (PLAT, TROT, MONTE, HAIES, STEEPLE) |
|
|
|
|
---
|
|
|
|
## 4. Modèle de Scoring Actuel
|
|
|
|
### 4.1 Formule de Scoring
|
|
|
|
Le score composite est calculé selon:
|
|
|
|
```
|
|
score = score_cote + score_forme + score_victoire + score_place
|
|
+ score_rk + score_tendance + score_avis
|
|
```
|
|
|
|
**Features utilisées:**
|
|
- `score_cote`: Pondération inverse de la cote (plus petit = plus haut)
|
|
- `score_forme`: Basé sur `forme_recente` (0-25 scale)
|
|
- `score_victoire`: `tx_victoire` du cheval
|
|
- `score_place`: `tx_place` du cheval
|
|
- `score_rk`: Classement relatif dans la course
|
|
- `score_tendance`: Variation de la cote
|
|
- `score_avis`: Valeur textuelle convertie (POSITIF/NEUTRE/NEGATIF)
|
|
|
|
### 4.2 Limites du Modèle Actuel
|
|
|
|
1. **Pas depondération apprentissage**: Les poids sont-ils optimaux?
|
|
2. **Features statiques**: Pas de features dynamiques (météo, forme vs竞争对手)
|
|
3. **Pas de cross-validation**: Pas de validation robuste
|
|
4. **Ignorer les correlations**: Interactions entre features non capturées
|
|
5. **Pas de feature engineering**: Variables dérivées limitées
|
|
|
|
---
|
|
|
|
## 5. Améliorations Proposées
|
|
|
|
### 5.1 Court Terme (Quick Wins)
|
|
|
|
#### 5.1.1 Améliorer le Suivi des Résultats
|
|
```python
|
|
# Ajouter le remplissage automatique des résultats
|
|
def update_recommendation_results():
|
|
"""Récupérer les résultats officiels et mettre à jour recommendations"""
|
|
# 1. Scraping des résultats PMU
|
|
# 2. Matching avec recommandations
|
|
# 3. Mise à jour du champ resultat
|
|
```
|
|
|
|
#### 5.1.2 Réduire la Catégorie "Non Classé"
|
|
- Analyser pourquoi 71.8% des prédictions ont `predicted_rank = 0`
|
|
- Implémenter un seuil minimum de confiance
|
|
|
|
#### 5.1.3 Ajouter Plus de Prédictions
|
|
- Automatiser le scraping quotidien
|
|
- Cible: minimum 500 prédictions avant analyse
|
|
|
|
### 5.2 Moyen Terme (Amélioration du Modèle)
|
|
|
|
#### 5.2.1 Feature Engineering
|
|
|
|
**Nouvelles features à créer:**
|
|
|
|
```python
|
|
# Features basées sur l'historique
|
|
- forme_vs_favori = forme_recente / forme_favori_moyen
|
|
- performance_par_distance = tx_victoire_par_distance[dist]
|
|
- performance_par_discipline = tx_victoire_par_discipline[disc]
|
|
- performance_par_hippodrome = tx_victoire_par_hippodrome[hippo]
|
|
- forme_tendance = forme_3_der courses vs forme_10_dernières
|
|
|
|
# Features dynamiques
|
|
- ecart_cote = cote_directe - cote_reference
|
|
- momentum = indicateur_tendance * volume_paris
|
|
- valeur = (cote - cote_juste_estimee) / cote_juste_estimee
|
|
|
|
# Features d'interaction
|
|
- forme_x_cote = forme_recente * (1/cote)
|
|
- age_x_performance = age * tx_victoire
|
|
```
|
|
|
|
#### 5.2.2 Modèle de Machine Learning
|
|
|
|
**Approche recommandée: XGBoost avec validation croisée**
|
|
|
|
```python
|
|
# Structure de données pour ML
|
|
features_ml = [
|
|
'tx_victoire', 'tx_place', 'forme_recente',
|
|
'age', 'nb_courses', 'cote_directe',
|
|
'distance', 'nb_partants', 'est_favori',
|
|
'reduction_km', 'gains_annee'
|
|
]
|
|
|
|
target_top1 = 'top1' # 1 si cheval gagné
|
|
target_top3 = 'top3' # 1 si cheval placé top 3
|
|
|
|
# Pipeline ML
|
|
1. Séparation train/test (80/20)
|
|
2. Cross-validation 5-fold
|
|
3. Hyperparameter tuning
|
|
4. Feature importance analysis
|
|
5. Backtest sur données historiques
|
|
```
|
|
|
|
#### 5.2.3 pondérations Optimales
|
|
|
|
**Analyse des poids actuels vs optimaux:**
|
|
|
|
| Feature | Poids actuel | Importance suggèree |
|
|
|---------|-------------|---------------------|
|
|
| score_cote | 14.7 | Haute (mais non-linéaire) |
|
|
| score_forme | 25.0 | Très haute |
|
|
| score_victoire | 15.0 | Haute |
|
|
| score_place | 15.0 | Moyenne |
|
|
| score_rk | 7.0 | Basse |
|
|
| score_tendance | 9.3 | Moyenne |
|
|
| score_avis | 6.5 | Variable |
|
|
|
|
### 5.3 Long Terme (Système Avancé)
|
|
|
|
#### 5.3.1 Modèles Multi-Cibles
|
|
|
|
| Modèle | Cible | Type de pari |
|
|
|--------|-------|--------------|
|
|
| `model_top1` | top1 | Simple Gagnant |
|
|
| `model_top3` | top3 | Simple Placé |
|
|
| `model_quinte` | top5 | Couplé/Quinté |
|
|
|
|
#### 5.3.2 Système de Cotes Justes
|
|
|
|
```python
|
|
# Estimer la cote "juste" vs cote PMU
|
|
cote_juste = f(tx_victoire_model, tx_place_model, dispersion)
|
|
|
|
# Identifier les "value bets"
|
|
value = cote_PMU - cote_juste
|
|
if value > seuil:
|
|
recommander_pari()
|
|
```
|
|
|
|
#### 5.3.3 Intégration Météo (Non Implémentée)
|
|
|
|
La table `weather` existe mais contient seulement 4 lignes.
|
|
|
|
**À implémenter:**
|
|
- Scraping météo quotidien
|
|
- Impact sur performance (par course)
|
|
- Ajustement des prédictions selon conditions
|
|
|
|
---
|
|
|
|
## 6. Plan d'Action
|
|
|
|
### Phase 1: Collecte de Données (Semaine 1-2)
|
|
- [ ] Automatiser le scraping quotidien
|
|
- [ ] Compléter le remplissage des résultats
|
|
- [ ] Atteindre 500+ prédictions évaluées
|
|
|
|
### Phase 2: Analyse Exploratoire (Semaine 3)
|
|
- [ ] Analyse univariée des features
|
|
- [ ] Corrélations entre features
|
|
- [ ] Identification des patterns
|
|
|
|
### Phase 3: Modèle ML (Semaine 4-6)
|
|
- [ ] Feature engineering
|
|
- [ ] Entraînement XGBoost
|
|
- [ ] Validation croisée
|
|
- [ ] Comparaison avec modèle actuel
|
|
|
|
### Phase 4: Production (Semaine 7-8)
|
|
- [ ] Déploiement nouveau modèle
|
|
- [ ] Monitoring des performances
|
|
- [ ] Ajustements itératifs
|
|
|
|
---
|
|
|
|
## 7. KPIs à Suivre
|
|
|
|
| KPI | Cible Court Terme | Cible Long Terme |
|
|
|-----|-------------------|-------------------|
|
|
| Taux hit global | 25% | 35% |
|
|
| Précision favori | 45% | 50% |
|
|
| Précision top 3 | 40% | 55% |
|
|
| ROI recommandations | 0% | 10%+ |
|
|
| Volume predictions | 500+ | 2000+ |
|
|
|
|
---
|
|
|
|
## 8. Conclusion
|
|
|
|
Le système actuel montre des bases solides mais nécessite:
|
|
1. **Plus de données** pour une analyse statistique robuste
|
|
2. **Un suivi rigoureux** des résultats pour mesure de performance
|
|
3. **Une évolution vers le ML** pour optimiser les pondérations
|
|
|
|
Les recommandations immédiates:
|
|
1. Compléter le remplissage des résultats (0/32 actuellement)
|
|
2. Augmenter le volume de prédictions
|
|
3. Passer à un modèle XGBoost avec features enrichies
|
|
|
|
---
|
|
|
|
*Document généré le 2026-03-25*
|
|
*Source: Analyse de turf.db - turf_scraper*
|