Courses
预测足球比赛并不容易。这是一项低得分的运动,一次折射的射门就可能改写结果,而且比赛中相当一部分取决于运气。国际足球更难:国家队每年只打少量正式比赛,可供学习的数据远少于俱乐部联赛。
而且更雪上加霜的是,FIFA 今年又让这项任务变得更难了。扩军至 48 支球队的世界杯引入了新赛制:十二个小组中每组前二直接出线,外加十二个第三名中表现最好的八队,使得小组赛的命运更难预料。既然我喜欢挑战(也喜欢足球),这正是我想要预测的。
这篇文章是我欧洲杯 2024 预测项目的后续,几乎是从零重建。上一次我完全在 Jupyter 笔记本中工作,为每场比赛预测一个最可能的比分。这一次,我搭建了一条端到端的 MLOps 流水线,自动摄取最新赛果、自我再训练,并对整个锦标赛进行 10,000 次蒙特卡罗模拟,把比赛级别的预测转化为各队能走多远的概率。
本文将从高层引导您了解该项目:数据与特征、保障可复现性的 MLOps 实践、流水线架构,以及最终哪种模型更适合预测国家队足球。您可在项目仓库找到完整代码。当然,我也会告诉您模型认为谁会夺冠。(剧透:它看好西班牙和阿根廷,各约 16%,更有趣的是它是如何得出这个结论的。)
如果这勾起了您对赛事的兴趣,推荐关注我们的数据与 AI 世界杯周,一系列关于数据与 AI 如何重塑足球的分享,直播或点播均可免费观看。
要点速览
- 这是一条端到端的 MLOps 流水线,用于预测 2026 年 FIFA 世界杯;在赛事期间每两小时于 Google Cloud 上自动拉取最新国际赛结果并再训练。
- 来自 API-Football 与 Elo 评分的数据经由青铜-白银-黄金(三段式)勋章架构处理,并使用 DVC 进行版本管理以实现完全可复现。
- 来自五大家族的十种模型在 347 场保留集上比较;XGBoost 以微弱优势胜出,前五名几乎难分伯仲,而队伍间的 Elo 差异承担了大部分预测贡献。
- 蒙特卡罗模拟运行完整锦标赛 10,000 次,将比赛级别的进球预测转化为各队晋级与夺冠的概率。
- 截至 2026 年 6 月 10 日,模型最看好西班牙与阿根廷,各约 16%。可在配套的Streamlit 仪表板上每两小时查看实时预测。
支撑预测的数据
预测的好坏取决于输入的质量,因此从原材料讲起最合适。模型从两个实时数据源学习,并将其转化为一张整洁的特征表。
数据来源
一切来自两个地方。API-Football 提供赛程与逐场统计:谁与谁在何时何地交手、结果如何。eloratings.net 提供各国家队的 Elo 评分。
Elo 评分用一个数字概括一支球队的实力。每支球队都位于这条刻度上的某个位置,每场比赛后评分都会更新:击败更强的对手涨分多,输给更弱的对手降分多。这个理念源自国际象棋,并很好地适用于足球。如果您想要更完整的直觉解释,这篇早期的 DataCamp 文章在 2022 年世界杯背景下详细讲解了它。
两者结合后,得到约 2018 年以来约 6,900 场国际比赛的黄金数据集用于学习。
模型预测什么
这里有一个关键的设计选择。模型并非直接预测胜平负,而是更细粒度地预测:每支球队在一场比赛中打进的进球数。足球的进球数大致服从泊松分布,这是在固定时间窗口内建模罕见事件发生次数的标准方法。
预测进球而非结果,使得后续一切成为可能。一旦模型能为任意对阵给出一个合理的比分,大家真正关心的“谁能突围小组、谁能捧杯”,就能通过对这些比分进行成千上万次模拟来回答。
关键特征
每场比赛由一小组精心挑选的特征描述:
- Elo 差值:两队评分的差距。这是模型中迄今最重要的单一特征,其重要性大约比第二强特征高两个数量级。这也符合直觉:两队实力差距比几乎任何其他因素都更能说明潜在结果。
- Elo 总和:两队评分之和,代表这场对决的整体质量。仅靠差值无法区分阿根廷 vs 西班牙与圣马力诺 vs 安道尔——两场势均力敌但水平天差地别的比赛,而总和补回了这部分信息。
- 滚动 Elo 变化(近 5 场):两队评分近期的变动幅度。这在已考虑对手强弱的前提下捕捉“状态”。
- 滚动进失球(近 5 场):各队近期在绝对层面的进攻与防守输出。
- 比赛情境:赛事级别(世界杯正赛与预选赛或国家联赛的权重不同)、是否为淘汰赛、以及是否在中立场地。
所有特征都严格防止泄漏,即仅使用开球前可获得的信息。听起来理所当然,但这恰是最易无意中造出“测试惊艳、实战崩溃”模型的坑。
一个被淘汰的想法:我原计划根据比赛内统计对球队做聚类,构建一组“打法风格”特征,属于一次无监督学习。实际中,球队并未分出有意义的群组;为避免向模型喂噪声,我把它去掉了。负面结果也是结果。
让数据可复现
数据以滚动方式来自两个源,从原始文件到可训练特征的路径必须始终一致。这正是勋章架构(medallion architecture)的作用。它将数据组织为三层:
- 青铜(Bronze):原始数据,保持原样,不做改动。
- 白银(Silver):清洗并标准化。在此我会对齐两数据源间的队名(它们很少写法一致)、验证模式、将 Elo 评分合并入比赛记录,并处理缺失或异常。
- 黄金(Gold):建模层,每场比赛一行,所有特征都已计算完毕、可直接训练。
各层相互传递,这样当某处看起来不对劲时,我可以逐层回溯,而非一股脑拆解所有问题。为让整条路径可复现,我使用 DVC(数据版本控制)。一旦有新赛果到来,执行一次 dvc repro 就会从青铜重建白银与黄金,仅当输入改变时才重跑该步骤,并对结果数据集做版本管理,以便精确恢复任一先前状态。
甄选最佳模型
进球预测是个研究充分的问题,并无唯一显而易见的工具。因此我没有一开始就押注某一方法,而是构建了十个模型相互竞争。
参赛选手
十个模型涵盖五大家族,外加一个简单基线。您无需了解每个模型的内部;关键是它们对进球生成机制的假设截然不同。
| 家族 | 模型 | 核心理念 |
|---|---|---|
| 基线 | 平均速率泊松 | 假设每队仅以其长期平均进球率得分,忽略所有特征。为其他模型提供下限基准。 |
| 统计 | 双变量泊松、负二项 | 直接用适合计数事件的概率分布对双方进球数建模。 |
| 贝叶斯 | 贝叶斯泊松(MCMC) | 同样是计数思路,但返回每个估计值周围的完整不确定性范围。计算代价高得多:拟合速度大约比其他模型慢 100 倍。 |
| 时间序列 | SARIMAX | 将球队的比赛结果视作随时间演化的序列并向前预测。 |
| 机器学习 | Ridge、随机森林、XGBoost | 直接从特征中学习模式,而不预设固定方程。 |
| 深度学习 | LSTM、1D CNN | 寻找序列与局部模式的神经网络。 |
评分方式
有十个候选者,凭肉眼选赢家行不通。取而代之,每个模型都经历三个阶段,由代码决定是否晋级。这就是基于代码的部署:模型从一个环境向下一个环境的晋升依靠自动检查,而非人工微调,从而保证整个选择流程可复现、易审计。
- 实验。所有模型仅在 2022 年世界杯之前的国际比赛上训练。并非所有比赛权重相同:近期比赛与更高重要性的比赛被赋予更大权重(时间衰减与比赛重要性加权),因此近期的正式比赛对模型的影响大于较久远的友谊赛。随后,用 交叉验证调参以最小化泊松负对数似然(NLL)。NLL 衡量预测进球率与实际进球的匹配程度,越低越好。产出是各模型的最优调参版本。
- 质量保证。这些调好的模型随后在它们从未见过的比赛上测试:2022 年世界杯加上此后举行的六项大赛(欧洲杯、两届非洲杯、美洲杯、亚洲杯与金杯赛),共 347 场。此处度量切换为排序概率分(RPS),用于衡量当结果天然有序(负、平、胜)时概率预测的好坏,并奖励“大致方向上自信”的预测,同样越低越好。此处最强的模型成为挑战者。RPS 是合适的标尺,因为真正目标是预测球队能走多远,而不仅仅是进球总数。
- 部署。挑战者与在任冠军对比;若胜出,则晋升并在所有可用比赛上重拟合,确保入赛时已学习全部数据。
胜者
那么谁胜出?以下是按 RPS(越低越好)计分的完整保留集排行榜:
| 模型 | 保留集 RPS |
|---|---|
| XGBoost | 0.18289 |
| 贝叶斯泊松 | 0.18316 |
| 负二项 | 0.18373 |
| 双变量泊松 | 0.18389 |
| 随机森林 | 0.18392 |
| SARIMAX | 0.18583 |
| Ridge | 0.18813 |
| LSTM | 0.19299 |
| 1D CNN | 0.20916 |
| 平均速率泊松(基线) | 0.22872 |
这份结果有四点值得注意:
- XGBoost 获胜,但优势极小。前五名(XGBoost、贝叶斯泊松、负二项、双变量泊松与随机森林)彼此间仅约 0.0011 RPS 之差。当五种截然不同的方法如此接近时,通常意味着上限由数据与特征决定,而非模型本身。在此,Elo 差值完成了大量工作,以至于模型选择几乎不影响结果。
- 单一特征占据主导。Elo 差值以巨大优势成为最重要的预测因子,其影响力约为次强特征的一百倍。与其说惊讶,不如说令人安心:在单场比赛中,两队实力差距确实就是大部分故事。
- 深度学习垫底(基线除外)。1D CNN 与 LSTM 是除朴素基线外最弱的模型。仅约 7,000 场比赛可学,数据量不足以喂饱参数众多的网络;而经典方法更能应对小而结构化的数据集。
- 经典模型未见过拟合迹象。通常模型在未见数据上的表现会略逊于训练阶段。但此处几乎所有模型(LSTM 例外)在保留锦标赛上的得分优于交叉验证。很可能原因是杯赛比日常国际赛更可预测:更高的赌注、更强且更熟悉的球队以及中立场地,都削弱了随机性。
在实时锦标赛中,我不会运行全部十个模型。我保留一个小阵容:作为参考的平均速率基线,加上三名表现最佳者。XGBoost 与贝叶斯泊松稳居前二。
第三名实际上打成平手:负二项与双变量泊松仅相差 0.0002 RPS,并会随随机种子互换位置;在两者统计上难分高下的情况下,我选择了双变量泊松,因为其表述在足球预测文献中(Karlis 和 Ntzoufras,2004)基础更扎实。
最终阵容为 XGBoost(机器学习)、双变量泊松(经典统计)与贝叶斯泊松(贝叶斯推断)。下一节将介绍这些模型如何运行、再训练,并将单场预测汇总为完整的锦标赛预测。
投产落地
仅停留在笔记本里的模型只有您坐在电脑前时才有用。要在为期一个月的赛事中持续预测,整套系统必须自主运行:拉新结果、再训练、再模拟、刷新预测,无需人工干预。这正是流水线的职责。
GCP 上的双小时流水线
整个项目作为一个计划任务运行在 Google Cloud Run 上。赛前为每日一次;自 6 月 11 日揭幕战起每两小时运行一次。每次运行遵循同一循环:
- 检查新数据。若自上次运行后无比赛结束,则无需动作,任务即早退。
- 摄取与重建。若有新赛果,从数据源拉取,一次
dvc repro重建白银与黄金层,确保特征为最新。 - 再训练、预测、模拟。将阵容内模型更新至最新状态(稍后详述),预测所有即将到来的对阵,并运行完整锦标赛模拟。
- 评分。一旦某场比赛结束,就对之前给出的预测进行评分,并用于下文所述的监控。
由于每一步都按计划由代码触发,赛事期间无需手动点击。新赛果进,最新预测出。
两种模式:冻结 vs. 分轮
这里也兼作一次实验。赛事期间,阵容并行运行两种模式,我希望用数据回答的问题是:随赛事推进进行再训练,是否会让预测更好?
- 冻结。赛事开球时模型即被锁定,不再再训练。它们仍会对赛果作出响应,因为每次模拟都会从更新后的对阵表开始,但模型参数本身不变。
- 分轮。超参数(高层设置)保持固定,但模型学习到的参数会在每个小组赛轮次与每一轮淘汰赛结束后,用所有可用数据重新拟合,让模型一边比赛一边学习。
并行运行二者,赛后即可从两个方面比较:原始预测准确度,以及随着参赛队缩减各自不确定性收敛的速度。若分轮更优,则定期再训练物有所值;若冻结不落下风,则额外复杂度未必值得。
从预测到锦标赛:蒙特卡罗模拟
预测一场比赛是一回事,把它转化为“各队夺冠概率是多少”就要靠蒙特卡罗模拟。
首先是推断。模型不仅预测已知的赛程,还会预测 48 支球队间所有可能的对阵。听起来铺张,但在杯赛中,任何球队都可能在淘汰赛遇到任何对手,因此必须为每一对组合备好预测。
接下来要编码规则,而 2026 赛制尤其棘手。12 个小组中前二自动出线,同时还有八个成绩最好的第三名也出线;这八支队分配到 32 强签位取决于它们来自哪些小组。
从 12 个小组中选出 8 个共有 495 种方式(12 选 8),每一种都会产生不同的 32 强对阵组合。没有简洁公式;FIFA 仅公布了一张对照表。因此我(准确说是我非常能干的同事 Cursor)将 495 种组合全部硬编码成映射,依据官方表格。
"best_third_mappings": {
"EFGHIJKL": {
"74": "3F",
"77": "3G",
"79": "3E",
"80": "3K",
"81": "3I",
"82": "3H",
"85": "3J",
"87": "3L"
},
"DFGHIJKL": ...
每个键,例如 EFGHIJKL,列出进入淘汰赛的第三名来自哪些小组;对应的值把这些球队(3E、3F 等)分配到具体的 32 强比赛编号。这是一条记录;完整映射重复 495 次,每种组合各一条。
三支东道主(美国、加拿大、墨西哥)需要额外处理。当东道主在本国比赛时,模拟会为该场比赛施加主场优势调整,而其他比赛视为中立场地。
准备好预测与规则后,模拟将整个锦标赛运行 10,000 次。每次运行遵循以下流程:
- 通过从模型的预测分布采样主客进球,为每场比赛抽取一个比分
- 按真实的积分与决胜规则推进小组赛
- 决出最佳第三名表
- 根据上述映射填写淘汰赛对阵表
- 一路打到最终冠军。
在 10,000 次模拟中,一支球队打进决赛或捧杯的占比,即为该队的概率。一次运行是猜测;一万次运行才是预测。
用 MLflow 全程跟踪
上述每次运行(两种模式皆然)都会记录到 MLflow(托管于 DagsHub)。实验跟踪即系统性记录每次运行的输入、设置、结果与输出,以便相互比较或精确复现。以下几点值得一提:
- 可复现性。模拟使用由锦标赛轮次派生的固定随机种子,冻结与分轮模式共享同一种子。这意味着两者间的差异只来自模型本身,而非模拟内的采样运气。每次运行也会记录它看到的精确数据快照(黄金层行数与时间戳),以便结果可追溯至其输入。
- 实验属性。每次运行都带有模式标签(冻结或分轮)与其生命周期阶段标签,从实验、QA 到在线推断与重拟合,映射上一节的晋升流程。
- 对比。将保留集 RPS 作为选择指标记录,并附上当前冠军运行的引用以供溯源。也记录拟合时间,这里可清楚看到贝叶斯模型约慢 100 倍的训练成本。
训练好的模型与预测文件本身(锦标赛概率、小组排名、比赛预测)都作为运行工件保存,实时仪表板正是读取这些文件。至此闭环:从原始赛果,经训练与模拟,到您在线看到的数值。
监控漂移
最后一块在比赛结束后运行。随着真实结果到来,之前对其给出的预测会被评分,并与简单的平均速率基线比较。若完整模型开始不如一个“不了解任何球队信息”的模型,那就是漂移的警告信号:赛前学到的模式可能不再匹配场上发生的事情。
监测这一点是任何进行在线预测系统的标准做法,更多检测方法可参阅这份关于数据漂移与模型漂移的指南。
那么,谁能赢得世界杯?
说了这么多机制,下面是它们服务的目标。
热门球队
截至 2026 年 6 月 10 日(揭幕战前一日),模型在榜首给出了清晰结论,而其后则相当拥挤。西班牙与阿根廷并列领先,各约有 16% 的夺冠概率。现任世界冠军(阿根廷)与欧洲冠军(西班牙)居前,是对模型“落地现实”的良好校验。
其后是一支紧凑的追击群:法国、英格兰、巴西与哥伦比亚构成最有可能夺冠的阵列。这些都是实时数值,真实赛果一出就会变化,因此请将其视为 6 月 10 日的快照,而非定论。仪表板始终展示当前数据,最长延迟两小时。
实时仪表板
说到这里:本文所有数字均来自一个随流水线自动更新的实时 Streamlit 应用。您可以打开 wc2026-predictions.streamlit.app,在整个赛事期间随时查看。它包含四个主要视图:
- 锦标赛总览:各队预计能走多远,一目了然。
- 小组排名:每个小组中,各队拿到第 1、第 2、第 3(细分为第三出线与第三出局,得益于“最佳第三”规则)或第 4 的概率。
- 比赛预测:每场小组赛的主胜、平局、客胜概率,以及最可能的淘汰赛对阵。
- 最常见淘汰赛对阵:模拟中最常出现的配对。
比赛视图里有个需要提示的小“怪癖”:有些球队会同时出现在两种 32 强签位中。这不是 bug。当某个小组过于均衡时,模型无法有把握地判定一支球队将以哪种名次出线;叠加“最佳第三”的不确定性,这两种结果会对应不同的淘汰赛签位。以土耳其为例,甚至导致它在 16 强里出现两次。
下图展示了在开赛前,XGBoost 模型对最终几轮(四分之一决赛至决赛)的预测:

硬币队:美国
这类模型的乐趣在于那些挑战直觉的球队,最明显的例子是美国。若您打开仪表板的锦标赛总览,会立刻注意到美国的颜色与众不同。
作为东道主之一在主场球迷面前作战,您或许会以为开局轻松,但模型要谨慎得多:它仅给出约 54.6% 的小组出线概率,居 48 队中倒数第 13(别忘了有三分之二的球队能出线!),原因是他们与澳大利亚、巴拉圭、土耳其同组,整体极其均衡。
有趣的是接下来。即便侥幸过关,美国在之后每一轮都大致徘徊在“抛硬币”的胜率附近。把这些硬币一枚枚叠起来,他们的总体夺冠概率约 2%,在全部 48 队中排名第 13。
一支小组出线概率倒数第 13、却又总冠军概率正数第 13 的球队,几乎就是“硬币队”的完美定义:从不做热门,也从未出局。
结语
这个项目投入颇多,涵盖的内容远超一篇文章所能容纳。仓库里还有许多未纳入本文的部分:完整候选模型集、特征工程,以及保障一切稳定运行的编排,都是例子。
目前,模型已给出选择,赛事将给出评判。无论您是为 MLOps 而来,还是为足球而来,祝您与我一道尽享赛事进程。比赛滚动进行之际,您可以在实时预测上关注最新结果,检验预测的表现。
若您想更深入了解文中提到的一些概念,推荐我们的 MLOps Concepts 课程。