FR EN

Optimisation de la sélection de l'équipe de Fantasy Premier League à l'aide de la Programmation Linéaire pour la saison 2024-2025

La Programmation Linéaire est une technique mathématique visant à maximiser ou minimiser une fonction objectif tout en respectant certaines contraintes. Comme son nom l'indique, cette méthode est applicable lorsque la fonction objectif et les contraintes sont exprimées sous forme d'équations et d'inégalités linéaires.

En savoir plus sur la linéarité ici.

Dans cet article, nous explorerons une application intéressante de la Programmation Linéaire : sélectionner l'équipe optimale de Fantasy Premier League pour la saison 2024-2025 en se basant sur les points des joueurs de la saison précédente.

Qu'est-ce que Fantasy Premier League ?

Fantasy Premier League (FPL) est le jeu officiel de football fantasy gratuit de la Premier League anglaise. Des millions de participants configurent leurs équipes de joueurs chaque saison, en compétition pour accumuler le plus de points. Les points sont attribués en fonction des performances des joueurs dans les matchs réels, notamment en marquant des buts, en réalisant des passes décisives ou en arrêtant des penalties.

Les participants disposent d'un budget limité pour acheter des joueurs, chacun ayant un prix. Une équipe est composée de 15 joueurs (2 gardiens de but, 5 défenseurs, 5 milieux de terrain et 3 attaquants). De plus, vous pouvez sélectionner un maximum de 3 joueurs de la même équipe de Premier League.

Consultez le site officiel de Fantasy Premier League.

Jeu de données

Pour créer la meilleure équipe, nous utiliserons les données sur les performances des joueurs de la saison dernière, en visant à maximiser le total des points marqués par notre équipe sélectionnée. Nous utiliserons ce jeu de données de Kaggle, qui inclut des informations sur tous les joueurs de la Premier League, leurs positions, équipes, coûts et points marqués la saison précédente.

Le code Python suivant extrait les données du fichier CSV et les convertit en un tableau :

import pandas as pd
players_data_path = 'players.csv'
players_data = pd.read_csv(players_data_path)
features = ['name', 'now_cost', 'position', 'team', 'total_points']
X = players_data[features].dropna().sort_values(by='total_points', ascending=False)
player_np_array = X.to_numpy()

Objet Joueur

Pour faciliter la manipulation des données, nous définissons une classe Joueur et convertissons nos données en un tableau d'objets Joueur :

# Définir l'objet Joueur
class Joueur:
    def __init__(self, name, now_cost, position, team, total_points):
        self.name = name
        self.now_cost = now_cost
        self.position = position
        self.team = team
        self.total_points = total_points

# Conversion en objets Joueur
players_array = [Joueur(player[0], player[1], player[2], player[3], player[4]) for player in player_np_array]

Modèle de Programmation Linéaire

Nous introduisons une variable binaire de décision \( x_p \) pour chaque joueur \( p \), où \( x_p = 1 \) si le joueur est sélectionné et \( x_p = 0 \) sinon. Notre objectif est de maximiser le total des points marqués par les joueurs sélectionnés :

Fonction Objectif : Maximiser \( \sum_{p} (x_p \cdot \text{points}_p) \) où \( p \) représente chaque joueur.

Nous imposons les contraintes suivantes :

Nous utilisons la bibliothèque mip en Python pour définir et résoudre ce modèle :

from mip import Model, xsum, maximize, BINARY

# Définir le modèle
model = Model(name="FPL", solver_name="CBC")
x = [model.add_var(name=f"x({player.name})", lb=0, ub=1, var_type=BINARY) for player in players_array]

# Fonction objectif (maximiser les points totaux)
model.objective = maximize(xsum(x[i] * players_array[i].total_points for i in range(len(players_array))))

# Contrainte de budget
BUDGET = 1000
model.add_constr(xsum(x[i] * players_array[i].now_cost for i in range(len(players_array))) <= BUDGET)

# Contrainte d'équipe
teams = {player.team for player in players_array}
max_team_players = 3
for t in teams:
    model.add_constr(xsum(x[i] * (players_array[i].team == t) for i in range(len(players_array))) <= max_team_players)

# Contraintes de position
position_limits = {'GKP': 2, 'DEF': 5, 'MID': 5, 'FWD': 3}
for pos, limit in position_limits.items():
    model.add_constr(xsum(x[i] * (players_array[i].position == pos) for i in range(len(players_array))) <= limit)

# Résoudre le problème
status = model.optimize(max_seconds=120)

Équipe Optimale

Après avoir ajouté quelques lignes pour afficher l'équipe sélectionnée et exécuté le code python, voici la Meilleure équipe de Fantasy Premier League:

Meilleure équipe de Fantasy Premier League

Conclusion

Bien que cette méthode permette de sélectionner une équipe de Fantasy Premier League basée sur les performances de la saison dernière, il est important de noter que les performances passées ne prédisent pas toujours les résultats futurs. Néanmoins, cela offre une approche précieuse pour la sélection initiale de l'équipe.

Cet exemple démontre comment la Programmation Linéaire peut être utilisée pour optimiser une fonction objectif linéaire sous contraintes linéaires. La bibliothèque mip en Python offre un moyen simple de définir et résoudre de tels problèmes d'optimisation. D'autres bibliothèques Python pour résoudre des problèmes de Programmation Linéaire incluent SciPy et PuLP.