2018俄罗斯世界杯小组抽签出炉,几家欢喜几家愁。世界杯从来就不乏看点,东道主俄罗斯能走多远、德国能否卫冕、西班牙是否有望东山再起、两位球王谁更接近大力神杯...距世界杯开幕还有半年时间,一切都是未知数,不过整个赛程已定,我完全按照赛程模拟了所有64场比赛比分1000次,得出了A~H组各自的出线形势、每支队伍进四强的概率、以及最终的夺冠概率。一切结果,先卖个关子。
做这件事分四个步骤:爬数据计算球队进球、失球均值,构建泊松模型模拟1000次世界杯赛事统计出线概率、夺冠概率、四强概率
上一篇文章用Python分析本赛季英超争四形势提到从OPTA抓取数据,由于接口权限不对外公开,现在我改用公开的免费数据,方便大家自行抓取。这次所有比赛数据、赛程数据是我从球探网上抓的。利用selenium库,我将每只参赛国家队最近一年的比赛数据都抓取下来,保存成Pandas库的数据框。举个例子,这是葡萄牙国家队的页面,以及下面一张截图是抓下来存储的干净数据框。葡萄牙国家队葡萄牙国家队的Pandas数据框
泊松模型是模拟比赛的核心算法,理论在用Python分析本赛季英超争四形势文章中介绍过。针对国家队,我做了以下修改:若进球数 ,强制 。这是因为热身赛双方实力差距过大,德国8:0马来西亚,这种差距在世界杯决赛圈几乎不存在。亚洲球队与欧洲球队水平存在一个差异值,需要整体乘以一个系数。韩国场均进2球,相比德国场均1.5球,韩国的对手亚洲球队居多,德国打过欧洲杯对手实力不俗,韩国的场均2球必须打折扣。
得到计算结果,按进攻实力排序,欧洲豪强与南美双雄占据前列。(尾部的球队没有列出来)
先解决如何模拟一场比赛。淘汰赛与小组赛不同,如果打成平局必须进行点球大战,决出胜负。点球大战就设定各自50%概率晋级,下面这个simulate_match函数传入knockout参数为True时,就会激发这个机制,返回晋级的球队名。如果不是knockout,就是小组赛,就是输出模拟的比分。
接下来是赛程,小组赛有6场每个组,8组共48场。按照赛程我手动写入列表里,比如A组的比赛按顺序,对战双方分别是这样:
然后建了一个类,每个组分别各自初始化自己的类,传入参数fixture就是上面创建的赛程,只需调用play函数就可以模拟该小组6场比赛比分。self.table是小组积分榜,保存下来每次模拟的小组头两名球队名,后面统计每支队在1000次模拟里出线的次数,即出线概率。
随后淘汰赛,16进8、8进4、半决赛和决赛。赛程球探网给出了,包括进入16强的对阵形势,每场由哪组第一对阵哪组第二都写清楚了,只要继续用上面模拟比赛的方式继续按照赛程模拟就行。
至此,我可以完整模拟一届世界杯的所有64场比赛的比分。最重要的,我记录下每组的出线球队、以及冠亚军、季军、殿军分别是哪个国家。接下来就可以轻松循环1000次,并进行统计。
A~H组各自的出线概率我已经统计完成,东道主俄罗斯的FIFA世界排名已跌至65位,不过俄罗斯抽签抽到上上签,有望小组出线进入下一轮。(由于32球队太多,图片拆分4波展示。)A组B组出线形势C组D组出线形势E组F组出线形势G组H组出线形势
以下是夺冠概率、及打进四强的概率。列出了所有夺冠热门球队。
最后,韩国队在1000次模拟中11次进入四强,并有1次夺冠。这种小概率事件不禁让我想起2015/16赛季英超,以赛季前1赔5000逆天夺冠的莱斯特城。所以,足球是圆的,任何事情都有它的可能性存在,中国国足什么时候再进世界杯呢?