Aller au contenu
MéthodologieDataIA

Comment fonctionne Elofoot : la méthodologie complète, de la donnée brute au scénario IA

De l'ingestion API-Football à la calibration finale des probabilités : la chaîne complète qui sort un pronostic Elofoot, expliquée sans détour ni bullshit marketing.

Sarah MercierLead Data Science12 min de lecture
Dashboard d'analyse de données avec graphiques et tableaux

On nous pose souvent la même question : "Concrètement, comment vous prédisez un match ?" La réponse honnête tient en cinq étapes — ingestion, features, modèle, scénarios, validation — et en autant de garde-fous qu'on s'impose pour ne pas glisser vers le site de pronos vite fait. Voici la chaîne complète, telle qu'elle tourne aujourd'hui, sans simplifier les zones grises.

Vue d'ensemble : la chaîne en cinq étapes

Avant le détail, le pipeline complet tient sur un schéma simple :

  1. Ingestion — on récupère les données brutes depuis API-Football et nos sources annexes.
  2. Preprocessing — on nettoie, normalise, dédoublonne, on impute les manquants.
  3. Features engineering — on construit les variables qui ont du sens football (xG ajusté, forme pondérée, fatigue contextuelle).
  4. Modèle prédictif + génération IA — on sort 4 scénarios calibrés, pas un pronostic unique.
  5. Validation et serving — on contrôle la cohérence avant d'envoyer au front.

Chacune de ces étapes a ses pièges, ses choix d'arbitrage, et son garde-fou. On déroule.

Étape 1 — Ingestion : API-Football comme socle, sources annexes pour le contexte

Tout part de la donnée. API-Football est notre fournisseur principal : 1100+ compétitions couvertes mondialement, données live, historique sur 15 ans, joueurs et compositions structurés en JSON propre. C'est la source qui nous coûte le plus cher et celle sur laquelle on peut le moins se permettre une panne.

Concrètement, on récupère par match :

  • Métadonnées : équipes, date, stade, arbitre, compétition, tour.
  • Stats équipes : possession, tirs, tirs cadrés, corners, fautes, cartons, xG fourni par API-Football.
  • Stats joueurs individuels : minutes jouées, tirs, passes clés, duels gagnés, distance parcourue (quand disponible).
  • Événements timeline : buts, cartons, changements à la minute près.

À côté d'API-Football, on agrège :

  • Données live : compositions probables croisées (Sofascore, L'Équipe, sources fédérales), blessés/suspendus (Transfermarkt + reports locaux), météo prévue à l'heure du coup d'envoi (OpenWeather, NOAA pour USA 2026 vu les chaleurs annoncées), état du terrain (capteurs sur les stades majeurs, sinon estimation modèle).
  • Historique : on archive nous-mêmes toutes les saisons depuis 2016 sur 45+ compétitions principales — championnats UEFA top 5, UCL, UEL, EFL, MLS, Liga MX, Brasileirão, sélections nationales.
  • Externes consolidées : cotes des principaux bookmakers (à titre comparatif, jamais comme input dans le modèle), sentiment Twitter/Reddit sur 72h précédant le match (sondage de "narration"), communications officielles (interviews coach, conférence d'avant-match).

Tout est stocké chez nous (Postgres + S3 pour les blobs), normalisé, horodaté. Pas de scraping en live pendant la génération — la latence serait insoutenable pour un utilisateur qui clique "analyser ce match".

Étape 2 — Preprocessing : la moitié invisible du travail

Les données brutes, même d'API-Football, ne sont pas utilisables telles quelles. Le preprocessing fait trois choses :

Déduplication et résolution d'entités

Un même joueur peut apparaître sous trois orthographes différentes selon la source (Vinicius Jr, Vinícius Júnior, V. Junior). On a une table de résolution d'entités entraînée à la main sur 8 000 joueurs avec un fallback fuzzy matching à 92 % de précision. Sans ça, on cumulerait des stats sous des identités fragmentées.

Imputation des manquants

Certaines compétitions (Ligue 2, championnats secondaires) n'ont pas l'xG ou la distance parcourue. On impute selon un modèle k-NN qui prend les variables disponibles (tirs, position du tir si on l'a, type d'action) et estime la valeur manquante. La règle : si on impute plus de 30 % d'une stat, on dégrade le poids de cette feature dans le modèle final.

Détection d'outliers et erreurs de saisie

API-Football donne parfois des stats absurdes (un latéral à 0 km parcourus, un gardien à 8 buts marqués sur la saison). On a une couche de plausibility checks qui flag ces anomalies et déclenche une vérification croisée avec FBref ou Sofascore. Coût : ~2 % des matchs ingérés requièrent une correction manuelle.

Garde-fou #1 : aucune analyse n'est servie sur un match dont plus de 20 % des features ont été imputées ou flagées. On préfère retourner "données insuffisantes" plutôt qu'un pronostic bruité.

Étape 3 — Features engineering : transformer la donnée en signal

Le modèle ne mange pas des chiffres bruts. Avant d'envoyer quoi que ce soit à la couche prédictive, on construit des features qui ont du sens footballistique :

FeatureConstructionPourquoi elle compte
xG ajusté contextuelxG normalisé par adversaire et compétitionUn xG de 1.8 en Ligue 1 ≠ un xG de 1.8 en Conference League
Indice de formePondération exponentielle décroissante sur 10 matchs (demi-vie ~5 matchs)Le dernier match compte plus, mais pas dix fois plus
Stabilité tactiqueVariabilité du schéma sur 5 derniers matchs (entropie de Shannon sur les formations)Une équipe qui change de système est moins prédictible
Force domicile / extérieurSéparée sur la saison en cours, lissée BayesienLe PSG à Paris ≠ le PSG à Brest
Fatigue contextuelleMatchs joués + minutes des cadres + distances + qualité adversaire récentUne demi-finale UCL 3 jours avant a un coût mesurable
Effet voyageDistance parcourue dans la semaine, fuseaux horaires traversésCritique en CDM 2026 (USA/Canada/Mexique)
Météo + pelouseTempérature ressentie, humidité, type de pelouseUn match à 35 °C n'est pas le même match

Le tout est passé dans une normalisation Z-score par compétition, pour qu'un xG et un PPDA pèsent de manière comparable dans l'équation finale. Si tu veux creuser un détail de cette étape, on a écrit un explainer dédié sur l'xG et comment on le calcule en 2026.

Étape 4 — Modèle prédictif : pourquoi 4 scénarios plutôt qu'un seul

C'est le cœur du système, et probablement le point qui nous différencie le plus des "tipsters" classiques. On utilise un modèle hybride à deux étages :

Étage 1 — Probabilités 1N2 cohérentes

Un modèle bayésien prend toutes les features et sort une distribution sur les trois issues (victoire domicile / nul / victoire extérieur). Sortie brute, ensuite :

  1. Calibration isotonique post-modèle : on s'assure que nos probabilités à 70 % correspondent bien à ~70 % de succès observé sur notre backtest (rolling window de 2 saisons).
  2. Règle de cohérence : si la somme n'est pas exactement 100 % après calibration (ça arrive à cause des arrondis), on redistribue proportionnellement. Pas de marge cachée, pas de bouillie de chiffres impossibles à interpréter.

Étage 2 — Génération des 4 scénarios IA

Pour chaque match, on génère 4 scénarios tactiques distincts via un LLM contraint (Claude Sonnet 4.5 avec output JSON forcé) :

  1. Scénario le plus probable : ce qui se passe dans 60-70 % des cas selon le modèle.
  2. Scénario "upset" : ce qui se passe si l'outsider passe.
  3. Scénario high-scoring : ce qui se passe si le match s'ouvre (>3,5 buts).
  4. Scénario clean-sheet / verrouillé : ce qui se passe si une équipe garde sa cage inviolée.

Chaque scénario contient :

  • Une probabilité (sans contrainte de somme — ils ne sont pas exclusifs).
  • Un score prédit au format X-Y.
  • Un indice de confiance (low / medium / high).
  • Une narrative tactique de 150 mots maximum qui doit citer au moins 3 stats du dataset.

Garde-fou #2 : la narrative est validée par regex + un second appel LLM qui vérifie la présence des stats. Si l'IA hallucine ou génère du jargon vide, on rejette et on retry une fois. Au-delà, on flag l'analyse comme "narrative dégradée" et on affiche un avertissement.

Pourquoi pas un pronostic unique ?

Question légitime. La réponse tient en une phrase : le football est trop variable pour qu'un seul pronostic soit honnêtement défendable.

Donner un pronostic unique ("Real victoire") c'est dire au lecteur "j'ai la vérité". Donner 4 scénarios, c'est dire "voici les 4 lectures les plus crédibles, à toi de pondérer selon ton contexte et ta tolérance au risque". C'est la différence entre un astrologue et un prévisionniste météo.

Étape 5 — Calibration, validation, serving

Avant qu'une analyse n'arrive sur ton écran :

  • Validation Zod stricte sur le schéma JSON (somme = 100 %, pas de NaN, pas de score impossible type "5-1" sur un match donné comme 0-0 par le scénario clean-sheet, etc.).
  • Calibration croisée : on compare les probabilités sortantes à un modèle de référence (Poisson bivarié basique). Si l'écart dépasse 25 % sur l'une des trois issues, on retry. Si ça persiste, on dégrade l'analyse en "confiance modérée".
  • Cache narrative : la couche descriptive (qui ne dépend pas de l'utilisateur) est mise en cache par (matchId, locale). Les scénarios, eux, sont toujours frais (les probabilités peuvent bouger jusqu'au coup d'envoi).

Garde-fou #3 : si une variable critique manque (composition non communiquée 2h avant le match, blessure non confirmée), on affiche un avertissement explicite dans l'analyse. Pas de masquage. Pas de "le modèle a décidé que ça vaut tant" — on dit ce qu'on ne sait pas.

Le backtest : ce que valent vraiment nos sorties

On backteste en permanence sur les 200 derniers matchs analysés :

Type de scénarioPrécision réalisée
Most likely64 % (le score exact prédit se réalise dans ±1 but près)
Upset18 % (déclenché à raison sur les matchs où il se produit)
High scoring9 % (déclenché à raison)
Clean sheet9 % (déclenché à raison)

Précision globale du scénario le plus probable (issue 1N2) : 71 %. Honorable, pas miraculeux. Et c'est exactement ce qu'on veut afficher — pas une promesse à 90 % qui ferait fuir tout statisticien sérieux.

Sur la calibration des probabilités : nos prédictions à 70 % se réalisent dans 68,4 % des cas (sur 1 200 matchs backtestés). L'écart de calibration est sous les 2,5 points, soit dans la marge de bruit statistique attendu sur cet échantillon.

Ce qu'on refuse de faire

  • Garantir un gain. Aucun service de prédiction sérieux ne le fait. Si tu vois "98 % de winrate" quelque part, fuis.
  • Donner une "cote value". On n'est pas un site de paris affiliés. Nos analyses parlent de scénarios et de probabilités, pas de cotes ni de stake.
  • Effacer les ratés. Chaque analyse est horodatée et conservée. Si on s'est planté sur un match il y a 3 mois, il est encore consultable. C'est la base de la confiance.
  • Promettre 90 % de précision. On vise 70 % réalistes. Quiconque promet plus ment ou n'a pas backtesté correctement. Notre article sur les erreurs courantes en pronostic détaille les biais qui produisent ces illusions.

Les limites qu'on assume publiquement

  • Sample size sur les nouvelles compétitions (MLS 2026, championnats africains) : moins de profondeur historique = moins de fiabilité.
  • Premiers matchs de saison : nos features se basent sur les 10 derniers matchs, donc la première journée d'une saison est mécaniquement plus bruitée.
  • Matchs amicaux : on ne les analyse pas. Pas assez d'enjeu, donc pas assez de signal.
  • Penaltys et CSC : événements rares, mal capturés par xG, qui peuvent dévier un résultat très fortement.

Et ensuite ?

Si tu veux voir tout ça en action, lance une analyse depuis le dashboard — la première est offerte. Tu verras les 4 scénarios, les probabilités cohérentes, les stats sourcées, et tu pourras juger par toi-même.

Pour aller plus loin sur les choix méthodologiques, on a écrit un papier dédié aux erreurs courantes en pronostic foot qui montre comment chaque garde-fou de cette chaîne neutralise un biais cognitif spécifique.

On accepte les retours critiques. Notre objectif n'est pas d'avoir raison à 100 % — c'est d'être plus utile, plus transparent et plus défendable que les alternatives. Le reste, c'est entre toi et le modèle.