Mohamed Rayen Sansa
ENFR
Tous les projets
Académique · En équipe2026

FootBallAnalysis

Combien vaut un joueur de football, d’après ses données ?

Plateforme d'aide au recrutement dans le football, construite selon CRISP-DM sur plus de 5,7 millions de lignes Transfermarkt. J'ai réalisé l'objectif 3 : estimer la valeur marchande d'un joueur. Préparation des données, comparaison de 5 modèles de régression, pipeline LightGBM déployé derrière une API FastAPI, et repérage des joueurs sous-évalués.

Mon rôle
Objectif 3 : estimation de la valeur marchande, de la préparation des données au modèle LightGBM déployé
Plateformes
IA, Web
Stack
  • Python
  • LightGBM
  • Scikit-learn
  • FastAPI
  • XGBoost
  • pandas
  • NumPy
  • SHAP
  • Machine learning
  • Groq API
  • Matplotlib
  • Seaborn
  • Jupyter
  • JavaScript
1:10 000

Situation

5,7 Mlignes Transfermarkt (92 671 joueurs, 2 175 clubs)

Projet académique en équipe (2026). Les clubs dépensent des milliards en transferts sans outil fiable pour estimer un joueur, repérer un talent ou anticiper un départ. Comment exploiter les données historiques des joueurs pour aider les recruteurs à décider plus vite, avec moins de risque ?

Le projet suit la méthode CRISP-DM en 6 phases. L’équipe a défini 8 objectifs métier et en a réalisé 4 : segmenter les joueurs par profil, repérer les jeunes à fort potentiel, estimer la valeur marchande, anticiper un transfert.

Ma partie : l’objectif 3, estimer combien vaut un joueur, pour aider un club à ne pas surpayer et à vendre au bon prix. Utilisateurs visés : recruteurs, directeurs sportifs, agents.

Données : le datalake Transfermarkt, 10 fichiers CSV, 5 673 773 lignes, 92 671 joueurs et 2 175 clubs.

1:1 000

Produit

  • Estimer la valeur d’un joueur : le recruteur saisit l’âge, la taille, le poste, le pied fort et les statistiques (matchs, buts, passes, minutes, cartons). L’API renvoie une valeur lisible, par exemple « 12.50 M€ » ou « 850 K€ ».
  • Repérer les joueurs sous-évalués : on compare valeur prédite et valeur actuelle. Les joueurs dont la valeur prédite dépasse le plus leur valeur actuelle sont des opportunités de recrutement.
  • Un agent IA de scouting (Llama 3.3 70B via Groq) lance les modèles de l’équipe et rédige un rapport ; il intègre l’estimation de valeur marchande.
  • La même interface web donne accès aux 4 objectifs : profil du joueur, potentiel, valeur marchande, probabilité de transfert.
Tester le modèle

Estimer la valeur d’un joueur

LightGBM · 864 arbres · calculé dans votre navigateur
Exemples
Poste
Pied fort
Valeur estimée

≈2,9 M€

probablement entre 710 k€ et 7,4 M€

LightGBM réentraîné pour cette démo sur 33 508 joueurs actifs des données du projet (dernière valeur Transfermarkt connue), à partir de leur profil, de leurs statistiques de carrière et de leur club. Sur 6 702 joueurs de test : R² 0,74 (échelle log), erreur médiane 45 %, 66 % des estimations à moins d’un facteur 2 ; la vraie valeur tombe dans la fourchette pour 78 % d’entre eux. Estimation indicative, calculée dans votre navigateur.

1:100

Système

Les notebooks entraînent les modèles, qui sont exportés (joblib) puis chargés au démarrage par une API FastAPI (Uvicorn). L’interface web (HTML, CSS, JavaScript) est servie par la même application. La clé Groq est lue dans le fichier .env.

Pour l’objectif 3, le prétraitement fait partie du même Pipeline que le modèle : il est appris sur le seul jeu d’entraînement (pas de fuite de données) et l’API le rejoue à l’identique.

Route Rôle
POST /predict_market_value Valeur marchande en euros (objectif 3)
POST /predict Profil du joueur (objectif 1)
POST /predict_potential Potentiel (objectif 2)
POST /predict_transfer Probabilité de transfert (objectif 4)
POST /football_agent_analysis Rapport de scouting rédigé par l’agent
GET /health API et modèles chargés
Transfermarkt (10 CSV), Jupyter (scikit-learn), Pipeline (LightGBM · joblib), FastAPI (Uvicorn), Web UI (HTML · CSS · JS), Llama 3.3 70B (Groq).data → notebooks : fit; notebooks → models : joblib; models → api : load; api → web : REST · JSON; api → llm : scoutingfitjoblibloadREST · JSONscoutingTransfermarkt10 CSVJupyterscikit-learnPipelineLightGBM · joblibFastAPIUvicornWeb UIHTML · CSS · JSLlama 3.3 70BGroq

Une requête de bout en bout

1:10

Modèle & données

Préparation des données

  1. Cible : la dernière valeur connue de chaque joueur, passée en log1p pour réduire l’asymétrie (beaucoup de petites valeurs, quelques stars à plus de 100 M€).
  2. Performances agrégées par joueur (matchs, buts, passes, minutes, cartons), jointes aux profils ; un joueur sans statistiques reçoit 0.
  3. Prétraitement (ColumnTransformer) : 8 variables numériques imputées par la médiane puis standardisées ; poste et pied fort encodés en one-hot.
  4. Découpage 80 % / 20 %.

5 modèles comparés, même prétraitement

Modèle Ce qu’il apporte
Régression linéaire Référence simple et lisible
Random Forest Robuste, capte les effets non linéaires
XGBoost Gradient boosting régularisé
LightGBM (retenu) Meilleur R² ; rapide et économe sur des dizaines de milliers de joueurs
MLP Réseau de neurones à 2 couches cachées

Le modèle au meilleur R² est retenu automatiquement, puis analysé : prédit vs réel, résidus, importance des variables. Une variante avec plus de variables (âge au carré, minutes par match, etc.) explique ses prédictions avec SHAP.

Résultats, sans arrondir la vérité

Le seul score enregistré est celui de la variante : R² = 0,641 (régression linéaire, MAE 2,850 et RMSE 3,835 sur l’échelle log). Le notebook principal n’a pas été exécuté jusqu’au bout : les scores des 5 modèles ne sont pas publiés, on sait seulement que LightGBM a eu le meilleur R², puisque c’est lui qui a été exporté. Un R² autour de 0,64 est réaliste : la valeur dépend aussi du contrat, du club, de la ligue et de la médiatisation, absents des données.

Limites et pistes

  • Statistiques sommées sur toute la carrière, et ligue absente : un but en 1re et en 2e division comptent pareil. Piste : stats des 1 à 2 dernières saisons, ratios par 90 minutes, niveau de compétition.
  • Une seule séparation entraînement / test. Piste : validation croisée et réglage des hyperparamètres (Optuna).
  • Métriques sur l’échelle log. Piste : MAE et MAPE en euros, par tranche de valeur, et SHAP dans l’API.

Le modèle de la démo

Pour la démo de la page, le modèle a été réentraîné à partir des données préparées du projet. En testant le modèle exporté, un défaut est apparu : entraîné aussi sur les joueurs retraités (dernière valeur souvent à 0 €), il avait appris à lire l’âge comme « retraité ou non », et estimait un joueur de 33 ans à quelques euros.

  • Données : seuls les 33 508 joueurs actifs dont la dernière valeur est connue et positive sont gardés.
  • Variables : celles du projet (âge, taille, poste, pied fort, buts, passes et minutes en carrière), plus le niveau du club actuel : la valeur moyenne lissée de ses joueurs. Les totaux de carrière ne disent pas à quel niveau un joueur joue ; le club, si. C’est un encodage par la cible : il est calculé hors pli sur l’entraînement et à partir de l’entraînement seul pour le test, pour qu’un joueur ne voie jamais sa propre valeur.
Sur 6 702 joueurs de test R² (log) À moins d’un facteur 2
Médiane par poste (référence) ≈ 0
Variables du projet seules 0,39 46 %
Ridge, avec le club 0,64 59 %
Random Forest, avec le club 0,74 65 %
XGBoost, avec le club 0,75 67 %
LightGBM, avec le club (retenu) 0,74 66 %
  • Réglages : recherche aléatoire (30 essais, validation croisée à 5 plis) ; une seconde recherche plus large (jusqu’à 2 500 arbres) n’a pas fait mieux. Des contraintes monotones garantissent que plus de buts ou de passes ne font jamais baisser l’estimation.
  • Résultat final : R² 0,74, erreur médiane de 45 % en euros, 66 % des estimations à moins d’un facteur 2.
  • Fourchette : deux modèles quantiles (10 % et 90 %) encadrent l’estimation ; la vraie valeur y tombe pour 78 % des joueurs de test, pour 80 % visés.
  • Garde-fous : au-delà de ce que montrent 99 % des joueurs d’entraînement (par âge et par poste), la démo signale un profil inhabituel. Un club absent des données reçoit le niveau moyen, et la démo le dit.
  • Le modèle est exporté en JSON et calculé dans le navigateur ; un contrôle vérifie sur 3 000 joueurs que les prédictions sont celles de Python (écart inférieur à 0,00001 sur l’échelle log).

Vous recrutez ? Comparez avec votre offre

Collez votre offre de stage. Vous verrez quelles technologies demandées sont prouvées par un de mes projets ou stages, et lesquelles ne le sont pas.

Le texte reste dans votre navigateur ; rien n’est envoyé.