Algorithme de prédiction

Vue d'ensemble

Le moteur de prédiction estime le temps de course trail à partir des données d'entraînement récentes (180 jours). Il calcule des métriques dérivées pour chaque activité, les agrège en sous-scores, puis simule la course segment par segment en appliquant des facteurs de pente, technicité, altitude, fatigue et température (météo).

1. Traitement des activités

Synchronisation

  1. Première sync : récupère les activités des 180 derniers jours
  2. Sync incrémentale : récupère uniquement les activités postérieures à la plus récente en base
  3. Les activités sont filtrées par type (Run, TrailRun)
  4. Pour chaque activité, les streams (données seconde par seconde) sont récupérés
  5. Détection de doublons : même utilisateur, date ±2 min, distance ±10%

Grade Adjusted Pace (GAP)

Utilise le polynôme de coût métabolique de Minetti et al. (2002) pour convertir la vitesse réelle en vitesse équivalente à plat :

C(g) = 155.4·g&sup5; - 30.4·g&sup4; - 43.3·g³ + 46.3·g² + 19.5·g + 3.6

GAP = vitesse × C(0) / C(grade)

Meilleures performances (Best Effort)

Fenêtres glissantes sur les streams pour trouver la meilleure vitesse GAP moyenne sur :

  • v30 : 30 minutes
  • v60 : 60 minutes
  • v120 : 120 minutes

Autres métriques dérivées

  • Vitesse ascensionnelle : D+/h sur les sections à plus de 2% de pente
  • Dérive cardiaque : variation de FC entre 1ère et 2ème moitié
  • Déclin de vitesse : variation de vitesse entre 1ère et 2ème moitié
  • Index d'endurance : 1.0 + speed_decay - HR_drift × 0.5, borné [0, 1]

Charge d'entraînement (TRIMP)

Formule de Banister (1991) avec réserve cardiaque :

TRIMP = durée × ΔFC × k

ΔFC = (FC_exercice - FC_repos) / (FC_max - FC_repos) et k = 0.64 × e^(1.92 × ΔFC) (hommes), 0.86 × e^(1.67 × ΔFC) (femmes).

Note : la valeur retournée est le TRIMP brut (non normalisé). À titre d'ordre de grandeur, 1 h au seuil ≈ 145, 1 h en endurance facile ≈ 60, une longue sortie trail de 5 h ≈ 400–500, un ultra de 12 h ≈ 1000–1200. Cette échelle diffère du TSS de TrainingPeaks / hrTSS d'intervals.icu, qui normalise à 100 pour 1 h au seuil : multipliez le TRIMP par ≈ 0,6 pour obtenir un équivalent TSS.

2. Modèle Forme / Fatigue / Fraîcheur

Implémentation du Performance Management Chart (PMC) de Banister (1991) avec EWMA :

MétriqueConstanteInterprétation
Forme (CTL)42 joursCondition physique accumulée
Fatigue (ATL)7 joursFatigue récente
Fraîcheur (TSB)CTL - ATLBalance entraînement/récupération

Poids de récence

Décroissance exponentielle composite avec trois demi-vies (21, 45 et 90 jours) capturant respectivement la forme récente, l'adaptation moyenne et la base aérobie profonde.

Zones de fraîcheur (TSB)

Six zones qualitatives, inspirées de Joe Friel, sont superposées au graphe TSB. Les seuils sont calibrés pour le TRIMP brut (environ × 2 par rapport au TSS classique) :

ZoneSeuil TSBLecture
Surentraînement< -50Fatigue qui dépasse largement la capacité d'absorption. Récupération prioritaire.
Charge lourde-50 à -25Bloc d'entraînement intense. Soutenable sur quelques jours, surveiller la récupération.
Entraînement productif-25 à 0Stress d'entraînement constructif. C'est ici qu'on gagne en condition.
Fraîcheur optimale0 à 15Fenêtre idéale pour une course ou une séance clé.
Prêt à courir15 à 35Affutage : forme maximale mais charge en train de retomber.
Désentraînement> 35Charge trop basse trop longtemps : risque de perte de condition.

3. Sous-scores d'entraînement

Chaque sous-score est la moyenne pondérée par récence, normalisée par une référence élite :

Sous-scoreSourceRéférencePoids
Seuilv30 (GAP)5.0 m/s35%
Base aérobiev60 (GAP)4.5 m/s25%
MontéeVitesse ascensionnelle1200 m D+/h25%
EnduranceIndex d'endurance0.9515%

4. Prédiction de course

Vitesse de base

La vitesse de base agrège les meilleurs efforts soutenus sur 30, 60 et 120 min. Les poids varient avec la durée estimée de la course : une course courte s'appuie sur les efforts plus intenses (v30, v60), un ultra glisse vers v120 qui reflète mieux la cadence soutenable plusieurs heures.

Une première passe estime grossièrement le temps total : un facteur de mélange interpole alors entre une pondération « effort court » qui privilégie v30 et v60 et une pondération « ultra » qui glisse vers v120. Plus la course est longue, plus la cadence soutenable sur deux heures pèse dans le total.

Simulation segment par segment

Pour chaque segment :

vitesse = v_base × A(pente) × B(technicité) × C(altitude) × D(fatigue) × E(fraîcheur) × F(départ) × W(température)

FacteurDescription
A (pente)Coût métabolique de Minetti, avec un adoucissement empirique sur les montées calibré sur les données historiques de courses (source : LiveTrail).
B (technicité)1.00 (facile) → 0.65 (très technique), modulé par le facteur de fatigue D ci-dessous (un terrain technique pèse davantage quand le coureur fatigue).
C (altitude)-3%/1000m au-dessus de 1500m, plancher 0.80
D (fatigue)D(t) = max(0.70, 1 − rate × t1.5), rate calibré par l'endurance (0.02 endurant ↔ 0.06 fragile)
E (fraîcheur)Modulation ±10% selon la balance CTL/ATL
F (départ)Réserve de fraîcheur en début de course, décroissance exponentielle vers 1.0 (cf. ci-dessous)
W (température)Ralentissement à la chaleur, sur la température ressentie : W = 1 jusqu'à 15 °C, puis −0,6 %/°C, plancher 0,85 (cf. ci-dessous)

Réserve de fraîcheur en début de course

v_base représente le rythme durable du coureur, agrégé sur ses meilleurs efforts 30/60/120 min. Or les premières heures d'une course longue se courent au-dessus de ce seuil : la capacité anaérobie (modèle W'/D') autorise un sur-régime qui se résorbe progressivement. Sans terme correctif, le modèle sous-estimait la vitesse pendant la première heure et survalorisait ainsi le temps de passage aux premiers points de contrôle.

Le facteur est calibré empiriquement sur les données LiveTrail de coureurs d'index UTMB équivalents. Exemple concret : sur l'édition 2025 du Tour des Lacs (GRP 80 km), les coureurs d'index UTMB ~500 traversent le premier ravitaillement (15,5 km / +1547 m D+) en 2 h 25 en moyenne. Sans ce terme, le modèle prédisait près de 4 h pour le même profil, soit plus lent que le tout dernier finisseur.

Prise en charge de la météo (température ressentie)

Quand l'heure de départ et la trace GPX sont renseignées, le moteur récupère la prévision horaire (Open-Meteo : prévision à < 16 jours, normales saisonnières au-delà, relevé réel pour une course passée) et applique un facteur W(température ressentie) à la vitesse de chaque segment.

Le facteur agit sur la température ressentie (formule de Steadman : température sèche, humidité et vent), et non sur la seule température au thermomètre — c'est l'humidité qui transforme 28 °C en effort éprouvant. AT = T + 0,33·e − 0,70·vent − 4, où e est la pression de vapeur dérivée de l'humidité. Cela rapproche le modèle des indices environnementaux (WBGT) sur lesquels reposent les études citées.

La température sèche est d'abord prise à l'altitude du segment (correction par le gradient adiabatique, −6,5 °C/1000 m depuis l'altitude de référence du modèle) et à l'heure de passage estimée du coureur, puis combinée à l'humidité et au vent. Comme la simulation cumule le temps segment après segment, un coureur lent qui atteint un col en pleine chaleur de mi-journée est pénalisé au bon endroit, en une seule passe.

W = 1 jusqu'à 15 °C (ressenti), puis perte de 0,6 %/°C, plancher 0,85. Le facteur est appliqué après le plancher de vitesse critique : en conditions chaudes, l'allure soutenable (CS comprise) baisse réellement. La bande météo du graphe affiche la température réelle, l'humidité et le vent ; le facteur W, lui, utilise la ressentie qui combine les trois.

Base scientifique. La dégradation de la performance d'endurance au-delà d'une température optimale — et son amplification chez les coureurs les plus lents — est documentée par : Ely MR, Cheuvront SN, Roberts WO, Montain SJ. « Impact of weather on marathon-running performance », Med Sci Sports Exerc 2007;39(3):487-493 ; et El Helou N et al. « Impact of environmental parameters on marathon running performance », PLoS ONE 2012;7(5):e37407 (~1,8 million de coureurs). Nos coefficients sont une approximation inspirée de ces travaux, et non une transcription directe ; ils sont destinés à être recalés sur les courses passées au fil des données.

Estimation énergétique

Basée sur le modèle de Minetti : énergie = Σ C(grade) × poids × distance

5. Vitesse Critique / D' (CS/D')

Le moteur estime les paramètres du modèle linéaire distance-temps :

d = CS × t + D'

  • CS (Critical Speed) : vitesse maximale soutenable asymptotiquement
  • D' : réserve de distance au-dessus de CS (capacité anaérobie)

Estimé par régression linéaire sur les meilleurs efforts GAP (v30, v60, v120).

Plancher de vitesse (CS)

Après 2 h de course cumulées, la vitesse par segment ne descend plus en dessous de CS ajusté au terrain (pente / technicité / altitude). Cela empêche des prédictions excessivement pessimistes sur les ultras.

Au-delà de 8 h de course cumulée, ce plancher est lui-même réduit progressivement (-4 %/h, minimum 65 % de CS) pour refléter le fait que CS n'est tenable indéfiniment qu'en théorie. Calibration empirique : un ultra à 14 h converge vers ~76 % de CS, ratio soutenu observé sur les courses liées.

D' pour l'estimation optimiste

Le scénario optimiste simule la dépense et la régénération de D' segment par segment : dépense au-dessus de CS, récupération partielle en dessous (τ = 5 min), et boost sur les segments courts en montée.

Réf. : Monod & Scherrer (1965), Morton (2006), Skiba et al. (2012)

6. Ajustements physiologiques

Si la VMA est renseignée dans le profil physiologique, elle sert de plafond : vitesse de course ≤ 70 % VMA (60 % pour les ultras > 50 km). FC repos et FC max alimentent le calcul des zones cardiaques et de la charge d'entraînement (formule de Karvonen quand les deux sont connues).

7. Fourchette de confiance

Bornes heuristiques par défaut

Pour un coureur sans historique de course liée :

incertitude = 25 % − 15 % × score_confiance

Le score de confiance (0–1) agrège le volume de données, la qualité des streams, les données d'endurance et physiologiques. Plancher d'incertitude : 10 % (aléa irréductible lié aux conditions de course).

Calibration empirique sur l'historique

Dès qu'au moins une course passée est liée à une activité, les bornes sont calibrées sur l'écart prédit/réalisé observé. Pour chaque course liée (hors course courante), on re-prédit à sa propre date (pas de fuite d'information) et on relève r = temps_réel / temps_prédit.

  • N ≥ 3 courses liées : percentile 10 % (optimiste) et 90 % (prudent) des ratios observés
  • N < 3 : approximation normale mean ± 1.282·σ avec un plancher σ ≥ 0.05

Mélange Bayésien avec les bornes heuristiques : w = min(1, N/3). Le central est lui-même décalé proportionnellement par w × mean(r), de sorte qu'une seule course outlier ne peut pas dominer.

8. Comparaison prédiction vs réalisé

Quand une activité est associée à une course, les temps réels par segment sont interpolés depuis les streams GPS. Un facteur d'échelle compense la différence GPS/course. L'écart est coloré par segment (vert/bleu = plus rapide, orange/rouge = plus lent).

9. Segmentation GPX

Le fichier GPX est découpé en segments homogènes de ~500 m par la formule de Haversine, classifiés par pente moyenne :

PenteType
> 15 %Montée raide
> 5 %Montée
> 1 %Faux-plat montant
-1 % à 1 %Roulant
-10 % à -1 %Descente
< -10 %Descente raide

Classification de technicité via OpenStreetMap

À l'import GPX, chaque segment reçoit une cote de technicité (1 à 4) dérivée des données OpenStreetMap. Cette cote détermine le facteur B (technicité) appliqué à la vitesse.

  1. Bounding box englobant la trace, arrondie au 0,01°.
  2. Cache local des réponses Overpass par BBox : aucun appel réseau à chaque ré-import d'un GPX déjà connu.
  3. Requête Overpass (fallback sur trois endpoints) récupérant les way[highway] avec les tags highway, sac_scale, trail_visibility, surface, mtb:scale.
  4. Échantillonnage : pour chaque segment, 3 points (début / milieu / fin) sont réassociés au way le plus proche, et le niveau 1–4 est déduit par vote majoritaire des tags.
NiveauSources OSM typiques
1 — route / facilehighway=residential, surface=paved
2 — sentier modéréhighway=path, sac_scale=hiking
3 — techniquesac_scale=mountain_hiking, trail_visibility=intermediate
4 — très techniquesac_scale=demanding_mountain_hiking+, trail_visibility=bad+

Si Overpass est inaccessible ou si la trace sort de la couverture OSM, tous les segments retombent sur le niveau 2 (sentier modéré).

10. Calibration de la fatigue : ce que nous avons essayé et pourquoi

Tentative : modèle multifactoriel per-coureur

Sur les ultras longs (> 8 h, > 3000 m D+), la fatigue mono-axe f(t) = 1 - rate·t plafonne et sous-estime structurellement la décélération réelle. Nous avons exploré une décomposition multifactorielle distinguant des mécanismes physiologiquement séparés :

AxeMécanismeDynamique
Temps tDéplétion glycogène, hydratation, mentalLente, monotone
D+ cumuléCharge concentrique quadriceps/mollets, dérive cardiaqueRapide, partiellement réversible
D- cumuléDommages excentriques (microlésions) → quad lockCumulatif, irréversible

Forme testée : f = max(plancher, 1 - α·t - β·D+ - γ·D-), éventuellement étendue à 6 axes (intensité, altitude cumulée, technicité cumulée).

Protocole : pour chaque segment d'une course observée, on extrait f_observed = v_actual / (v_base × A × B × C), puis on fit (α, β, γ) par OLS. Validation croisée Leave-One-Out sur l'historique du coureur.

Résultat : approche non fiable à faible volume

Avec moins d'une demi-douzaine de courses comparables, les coefficients fittés sont extrêmement instables : d'un ordre de grandeur d'une course held-out à l'autre, parfois même de signe opposé (impliquant une accélération avec la fatigue cumulée). Le LOO donne une RMSE comparable, voire pire, que la baseline mono-axe. Les corrélations résiduelles r ∼ t, r ∼ D+, r ∼ D- restent fortes, signe que la forme ne capte pas la dynamique sur ce régime de données.

Pourquoi : le bruit domine le signal

  • Confound intensité : un jour de pointe et un jour de survie produisent des trajectoires f(t) radicalement différentes pour la même charge cumulée
  • Confound stratégie : départ rapide vs negative split contamine la corrélation entre t et f_observed
  • Bruit course : ravitaillements, météo, gestion mentale > signal physiologique sur 4 ou 5 courses
  • Colinéarité : t, D+, D- sont fortement corrélés au sein d'une même course (montée et descente s'enchainent), rendant les axes non identifiables individuellement

Conclusion : la masse de données nécessaire pour qualifier une fonction de fatigue multifactorielle per-coureur dépasse largement ce qu'un coureur amateur produit en une saison.

Approche retenue : aucune ou peu de courses dans l'historique

Fatigue mono-axe globale, calibrée sur la littérature :

f(t) = max(0.70, 1 - rate × t)

rate est modulé par l'index d'endurance du coureur, lui-même dérivé des sorties d'entraînement et non des courses (signal beaucoup plus dense). Complétée par un plancher CS mis à l'échelle de la durée (CSScaleStart = 8 h, CSScaleSlope = 0.04/h, CSScaleMin = 0.65) pour éviter la sous-estimation sur les ultras longs. Les paramètres ne dérivent pas faute de données : le modèle reste stable et explicable.

Approche retenue : historique de courses disponible

Plutôt que de réécrire la fonction de fatigue, on calibre les bornes empiriques de la fourchette de prédiction à partir de l'écart prédit/réalisé sur les courses passées du coureur :

  • N ≥ 3 courses liées : percentiles 10/90 des erreurs relatives observées
  • N < 3 : approximation normale, mélange Bayésien w = min(1, N/3) avec un prior par défaut

L'incertitude reflète ainsi la vraie dispersion historique du coureur, sans toucher au cœur du modèle physiologique. Les paramètres globaux restent inchangés ; seules les bornes optimiste/conservatrice sont déplacées.

Index UTMB comme proxy de performance

L'index UTMB est un signal externe précieux : il condense, en un scalaire calibré sur des milliers de courses, l'information que nous échouons à extraire d'un faible volume de courses individuel.

État actuel : l'index UTMB de la course (0–1000) est désormais saisissable sur la page comparaison et stocké sur la course. Il n'est pas encore consommé par le moteur de prédiction ; le stockage prépare son usage futur comme signal de cohérence sur la difficulté globale (complément des facteurs A/B/C lorsque la course est trop atypique) et pour informer le central de la prédiction quand l'historique du coureur est trop pauvre.

L'index de performance du coureur (cotation UTMB globale) n'est pas encore intégré. Il constituerait un prior naturel sur le niveau du coureur quand les données récentes sont insuffisantes pour stabiliser les sous-scores.