Exploratory Data Analysis
from pathlib import Path
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import polars as pl
import seaborn as sns
sns.set_theme(context="paper", style="ticks", palette="deep", color_codes=True)
plt.rcParams["figure.autolayout"] = True
plt.rcParams["figure.dpi"] = 300EDA of match_results¶
match_results = pl.read_csv(
Path("./../data/match_results.csv"),
).cast(
{
"DaysInPost": pl.Int64,
"Goals": pl.Int64,
"Date": pl.Date,
}
)
match_results.head()head_coach = pl.read_csv(Path("./../data/head_coach.csv")).cast(
{"Appointed": pl.Date, "EndDate": pl.Date}
)
head_coach.head()first_season = match_results.get_column("Date").dt.year().min() + 1
last_season = match_results.get_column("Date").dt.year().max()
leagues = ", ".join(match_results.get_column("League").unique())
n_match = round(len(match_results) / 2)
n_team = match_results.get_column("Team").n_unique()
n_team_no_coach = (
match_results.group_by("Team")
.agg(pl.col("HeadCoach").is_null().all().alias("all_null"))
.filter(pl.col("all_null"))
.height
)
perc_match_no_coach = match_results.get_column("HeadCoach").is_null().sum() / len(
match_results
)
n_coach = head_coach.get_column("HeadCoach").n_unique()
n_appointments = len(head_coach)Nous avons collecté les résultats des matchs et les mandats des entraîneurs sportif chef de la première division masculine de football pour les saisons Unexecuted inline expression for: first_season - Unexecuted inline expression for: last_season et pour les ligues suivantes : Premier League, La Liga, Ligue 1, Bundesliga, Serie A.
Cela correspond à un total de 14361 matchs joués par 161 équipes. Parmi ces 161 équipes, 95 équipes n’ont pas d’information sur les mandats des entraîneurs chefs pour tout ou partie des saisons 2015 à 2023. En proportion de match c’est Unexecuted inline expression for: f'{perc_match_no_coach:.2%}' des matchs qui ne comportent pas d’information sur l’entraîneur chef.
Les données des mandats des entraîneurs sportifs contiennent 381 mandat d’entraîneurs chefs parmi 249 entraîneurs uniques.
match_summary = (
match_results.group_by(["League", "Country"])
.agg(
[
pl.col("Team").n_unique().alias("Number of Teams"),
pl.col("Date").len().alias("Number of Matches"),
(
(pl.col("HeadCoach").is_null().sum() / pl.col("HeadCoach").len() * 100)
.round(2)
.cast(pl.String)
+ "%"
).alias("Percentage of Matches without Head Coach"),
]
)
.sort("Number of Matches", descending=True)
)
match_summary# Plot distribution of match
plt.figure()
sns.histplot(
match_results.get_column("Date").dt.month(),
stat="density",
discrete=True,
alpha=1,
)
plt.title("Monthly Distribution of Matches")
plt.xlabel("Month")
plt.ylabel("Density")
plt.gca().yaxis.set_major_formatter(mticker.PercentFormatter(xmax=1))
plt.gca().set_xticks(range(1, 13))
plt.gca().set_xticklabels(
["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
)
plt.show()
Effet du jeu à domicile ou à l’extérieur sur la performance des équipes¶
mean_home_goals = match_results.filter(pl.col("isHome")).get_column("Goals").mean()
mean_away_goals = match_results.filter(~pl.col("isHome")).get_column("Goals").mean()
diff_goal_perc = (mean_home_goals - mean_away_goals) / mean_away_goalsL’équipe qui joue à domicile marque en moyenne 1.50 but contre 1.18 but pour l’équipe jouant à l’extérieur (Unexecuted inline expression for: f'{diff_goal_perc:.2%}' moins de buts).
match_result_home_away = (
match_results.group_by(["isHome", "Result"])
.len()
.with_columns(proportion=pl.col("len") / pl.col("len").sum().over("isHome"))
.select(
pl.col("isHome")
.replace_strict({True: "Home", False: "Away"})
.alias("Team venue"),
pl.col("Result").str.to_titlecase(),
pl.format("{} %", (pl.col("proportion") * 100).round(1)).alias(
"Proportion (%)"
),
)
.sort("Team venue", "Result", descending=True)
)
match_result_home_awayhome_stats = match_result_home_away.filter(pl.col("Team venue") == "Home").get_column(
"Proportion (%)"
)
away_stats = match_result_home_away.filter(pl.col("Team venue") == "Away").get_column(
"Proportion (%)"
)
perc_home_win = home_stats.item(0)
perc_home_loss = home_stats.item(1)
perc_away_win = away_stats.item(0)
perc_away_loss = away_stats.item(1)
perc_draw = home_stats.item(2)Les équipes jouant à domicile remportent Unexecuted inline expression for: f'{perc_home_win}' de leurs matchs contre Unexecuted inline expression for: f'{perc_away_win}' pour les équipes jouant à l’extérieur. Les équipes perdent Unexecuted inline expression for: f'{perc_home_loss}' de leurs matchs contre Unexecuted inline expression for: f'{perc_away_loss}' pour les équipes jouant à l’extérieur. Les matchs nuls représentent Unexecuted inline expression for: f'{perc_draw}' des matchs.