2022世界杯冠军是谁?本文将为你揭晓一个利用简单AI模型得到的靠谱预测。
许多人称足球为“不可预测的比赛”,因为一场足球比赛有不同的因素可以改变最终比分。
这是真的……在某种程度上。
北大出版社,人工智能原理与实践 人工智能和数据科学从入门到精通 详解机器学习深度学习算法原理
人工智能原理与实践 全面涵盖人工智能和数据科学各个重要体系经典
很难预测最终比分或比赛的获胜者,但在预测比赛的获胜者时却并非如此。在过去的5年里,拜仁慕尼黑赢得了所有的德甲冠军,而曼城则赢得了4次英超联赛冠军。
巧合?我不这么认为。
我们将如何预测比赛?
有不同的预测方法。我可以构建一个复杂的机器学习模型并为其提供多个变量,但在阅读了一些论文后,我决定给泊松分布一个机会。
为什么?好吧,让我们看一下泊松分布的定义。
泊松分布是一种离散概率分布,描述了在固定时间间隔或机会区域内发生的事件数量。
如果我们将进球看作是一场足球比赛 90 分钟内可能发生的事件,那么我们可以计算 A 队和 B 队在一场比赛中进球数的概率。
但这还不够。我们仍然需要满足泊松分布的假设。
毫无疑问,假设 1 和 4 得到满足,但假设 2 和 3 部分成立。也就是说,让我们假设假设 2 和 3 始终为真。
过去我曾准确预测欧洲顶级联赛的获胜者,当时我绘制了前 4 大联赛过去 5 年每场比赛进球数的直方图。
如果你看一下任何联赛的拟合曲线,它看起来就像泊松分布。
现在我们可以说,可以使用泊松分布来计算一场比赛中进球数的概率。
下面是泊松分布的公式。
为了做出我考虑的预测:
要计算 lambda,我们需要每个国家队的平均进球数/失球数。这将我们带到下一点。
每个国家队的进球数/失球数
北大出版社,人工智能原理与实践 人工智能和数据科学从入门到精通 详解机器学习深度学习算法原理
人工智能原理与实践 全面涵盖人工智能和数据科学各个重要体系经典
在收集了 1930 年到 2018 年所有世界杯比赛的数据后,我可以计算出每个国家队的平均进球数和失球数。
在我对欧洲前 4 联赛的预测中,我考虑了主客场因素,但由于在世界杯上几乎所有球队都在中立场地比赛,因此我在分析时没有考虑这个因素。
一旦我获得了每支国家队的进球数/失球数,我就创建了一个函数来预测每支球队在小组赛阶段将获得的积分数。
预测小组赛阶段
下面是我用来预测每个国家队在小组赛阶段将获得多少分的代码。它看起来很吓人,但它只有我提到的很多东西,直到这一点被翻译成代码。
def predict_points(home, away):
if home in df_team_strength.index and away in df_team_strength.index:
lamb_home = df_team_strength.at[home,'GoalsScored'] * df_team_strength.at[away,'GoalsConceded']
lamb_away = df_team_strength.at[away,'GoalsScored'] * df_team_strength.at[home,'GoalsConceded']
prob_home, prob_away, prob_draw = 0, 0, 0
for x in range(0,11): #number of goals home team
for y in range(0, 11): #number of goals away team
p = poisson.pmf(x, lamb_home) * poisson.pmf(y, lamb_away)
if x == y:
prob_draw += p
elif x > y:
prob_home += p
else:
prob_away += p
points_home = 3 * prob_home + prob_draw
points_away = 3 * prob_away + prob_draw
return (points_home, points_away)
else:
return (0, 0)
上面代码解释一下就是,我们用predict_points计算主队和客队将获得多少分。为此,我使用公式 计算了每个团队的 lambda average_goals_scored * average_goals_conceded。
然后我模拟了一场比赛的所有可能比分,从 0-0 到 10-10(最后一个比分只是我目标范围的限制)。一旦我有了 lambda 和 x,我就使用泊松分布的公式来计算p。
如果比赛分别以 1–0(主场获胜)、1–1(平局)或 0–1(客场获胜)结束,则prob_home、prob_draw和prob_away将累积其值。p最后,使用以下公式计算分数。
points_home = 3 * prob_home + prob_draw
points_away = 3 * prob_away + prob_draw
如果我们predict_points用来预测英格兰对美国的比赛,我们会得到这个。
>>> predict_points('England', 'United States')
(2.2356147635326007, 0.5922397535606193)
这意味着英格兰将获得 2.23 分,而美国将获得 0.59 分。
如果我们将此predict_points函数应用于小组赛阶段的所有比赛,我们将获得每个小组的第 1 和第 2 名,从而在淘汰赛中获得以下比赛对抗阵容。
北大出版社,人工智能原理与实践 人工智能和数据科学从入门到精通 详解机器学习深度学习算法原理
人工智能原理与实践 全面涵盖人工智能和数据科学各个重要体系经典
预测淘汰赛
对于淘汰赛,我不需要预测积分,而是预测每组的胜者。这就是为什么我在get_winner以前的功能的基础上创建了一个新predict_points功能。
def get_winner(df_fixture_updated):
for index, row in df_fixture_updated.iterrows():
home, away = row['home'], row['away']
points_home, points_away = predict_points(home, away)
if points_home > points_away:
winner = home
else:
winner = away
df_fixture_updated.loc[index, 'winner'] = winner
return df_fixture_updated
简单来说,如果points_home大于points_away则为主队,否则为客队。
多亏了这个get_winner函数,我可以得到前面小组赛的结果。
预测四分之一决赛、半决赛和决赛
如果我get_winner再次使用我可以预测世界杯的获胜者。这是最终结果!
通过再次运行该函数,我知道赢家是….
巴西!
北大出版社,人工智能原理与实践 人工智能和数据科学从入门到精通 详解机器学习深度学习算法原理
人工智能原理与实践 全面涵盖人工智能和数据科学各个重要体系经典
链接文中github link
github link