DOTA2先干掉中路一塔后有多大胜算?

上回数据冰山发布的《TI7伤害之王》《TI7小组赛英雄数据报告》收到冰友反馈:

  • 游戏数据接口API如何调用?我没有编程基础,感觉很难的样子。
  • 能不能给一些具体的例子,能一步一步学着操作的那种。
  • 内容可以再丰富一点吗?

我是过来人,道理我都懂。大家其实是希望我给一个故事完整、过程清晰、内容详实的DOTA2数据分析例子,这样学起来才会有顺藤摸瓜的感觉,比起摸着石头过河,能够少踩一些坑。

既然如此,我也只好收拾一下自己的懒癌,再满足大家一次。

本文叙述结构按照数据分析师的工作流程来:

  1. 提一个值得分析的问题(中路一塔到底有多重要?)
  2. 获取数据源(手把手演示如何使用python调用API获取需要的数据)
  3. 确定方法论(统计推断statistical inference),处理数据,得出结论

【注意:在数据分析师的实际工作过程中,顺序可能颠倒,也可能重复多次】

一、提一个好问题

会提问、提好问,是数据分析师最重要的技能之一。

大家平时听讲座,经常看到演讲者眼冒精光的对某个提问者说:“你这个问题提的非常好!很有水平!(加鸡腿)”。演讲者觉得问题好,是因为这个问题触及了事情的本质,回答好这个问题,就可以把事情说清楚。

和他问自答的演讲者相比,自问自答的数据分析师自由度更高,更需要借一双慧眼,在纷繁复杂的数据和千头万绪的可能性之中,找到最接近真相的那些问题。

本文提出的问题是:DOTA2这款免费游戏的中路一塔有多重要?

喜欢看比赛的朋友,对这个问题应该不陌生。主播解说比赛时经常讲:这个中路一塔绝对不能放!这个塔放了之后,视野黑一大片,活动范围减小,打钱空间被压缩...就不好打了!那么,主播们说的对吗?如何衡量中路一塔的重要性?

在DOTA2的世界里,所谓「重要」,只有两个字:能赢。比如刀塔中最重要的建筑毫无疑问是基地——因为基地一炸,比赛就结束了。如果我们可以把「先拆掉敌方中路一塔」和「比赛胜负」联系起来,就可以得出答案。按这个思路,对每场比赛,我们需要的数据是:

  1. 哪一方先拆掉敌方中路一塔
  2. 哪一方赢得了比赛

二、获取数据源

如何获取一场比赛的「拆塔信息」和「比赛胜负」?

上篇文章讲过,可以调用OPENDOTA提供的API来获取公开比赛数据。查阅API接口文档后,发现有一个名叫matches的api提供了一场比赛(match)的详细信息。我们需要的数据很可能在api返回的结果里。

我们不妨找一场比赛调用这个API试一下(反正又不要钱),看看它到底提供了哪些数据。以刚刚结束的长沙MDL MAJOR最后一场比赛为例(LGD夺冠那场),它的比赛编号(也就是调用api要传入的参数:match_id)是3903099199。

同学们不要紧张,现在还不用写代码。

这种webapi是可以在浏览器中调用的。只需要按API的接口说明构建出网址api.opendota.com/api/ma,然后把链接复制到你常用的浏览器中,按回车就可以得到结果:

为什么数据这么多?平时打完一局DOTA2,赛后统计数据没这么多啊?

同学们不要紧张。Opendota提供的matches接口,不仅返回了「基础赛后统计数据」,还包含了许多「通过解析录像得到的游戏中数据」。以防御塔数据为例,基础的赛后统计数据只能告诉你比赛结束时,双方队伍的防御塔存亡状态(哪些拆掉了,哪些还在);而解析录像得到的游戏中数据,可以告诉你每座塔是什么时候被谁拆掉的。

如果你愿意,你甚至可以通过解析录像知道拆塔的过程中,每一个英雄每一下A出了多少伤害。也就是说,DOTA2这款游戏的数据源很开放(其他类DOTA游戏没法比),这也正是我在市面上已经有非常多数据分析入门教程的前提下,执意要写「DOTA2数据分析入门」教程的原因——因为对大家来讲,那些教材使用的数据源都不对口,学起来很容易半途而废(特别是基础不好的朋友)。而DOTA2这款游戏内涵丰富,可以分析的维度很多,如果你本身是一名刀塔玩家,使用DOTA2数据源来学习数据分析,学习过程一定会很愉快。

比如,当你看到上图中的「"radiant_win":false」时,你一定会知道radiant表示天辉,所以radiant_win就是天辉胜利,合起来就是:天辉胜利为假,那就是夜魇(Dire)获胜咯!(如果不放心,你可以找第三方数据产品验证一下)

是不是很简单?

接下来我们在API返回的结果中寻找第二个数据「拆塔信息」。经过一番折腾(比如搜索关键字"tower"或者"building"),我们可以发现数据出现了一些奇怪的东西:

  • npc_dota_goodguys_tower1_mid
  • npc_dota_badguys_tower1_mid
  • npc_dota_goodguys_tower2_bot
  • npc_dota_goodguys_tower3_top

tower1是什么鬼?一塔?mid\bot\top是中塔\下塔\上塔?那goodguys和badguys是不是天辉和夜魇???

是的,上面的猜测都是对的,V社就是这么任性(不好好用radiant,还要搞个goodguys...)。

所以,上图中的两条拆塔信息是:

  1. 名叫npc_dota_hero_gyrocopter(矮人直升机)的单位,于20分10秒,拆掉(反补)了天辉方的中路一塔。
  2. 名叫npc_dota_hero_gyrocopter(矮人直升机)的单位,于20分37秒,拆掉了夜魇方的中路一塔。

如果你不放心,仍然可以用第三方数据产品(DOTABUFF、OPENDOTA、刀魔数据等)来验证数据的准确性:

OK,到现在为止,我们终于获取了LGD对阵VGJ.S的第三局所有想要的信息:夜魇方先拆掉天辉方的中路一塔,夜魇获胜。

但是,使用浏览器调用接口,人工统计信息的操作会很麻烦(比如你想查询100场比赛的信息,估计眼睛都要看瞎)。

接下来我们必须开始写代码了。关于代码有两点说明:

  • 本系列教程不会教大家写代码,请自行学习python、requests、notebook等编程知识(自律且时间充裕的朋友,可以Google搜关键字自学;基础太差或者想有人一起学的朋友,可以考虑报网课,比如「优达学城(Udacity)」)
  • 文中用到的所有代码,都会放在GitHub上(repository叫dota2_analysis_tutorial)。给大家作为参考~

写代码的时候,我们可以再简化一下,把「拆塔和比赛胜负的联系」用一个bool类型表示。比如我们可以写一个名叫is_destroy_mid_tower_induce_win的函数,对每一场比赛(用match_id标识)返回:

  • True,表示先拆掉敌方中路一塔的队伍,取得了胜利
  • False,表示先拆掉地方中路一塔的队伍,遭受了失败
  • None,表示获取不到数据(录像损坏或者解析出错)

三、处理数据,得出结论

孤证不立,一场比赛的情况不足以反映规律,我们需要看更多比赛的数据。DOTA2进入7.0时代以来,一共打了13574场职业比赛(可用下图的SQL在OpenDota - Dota 2 Statistics上查询)。

难道我们要把1万3千多场比赛的信息都弄下来?这样做确实可以,但是太耗时间了——OpenDota提供的API限制访问速度是1分钟60次,也就是需要4个小时才能获取这些比赛的信息(而且代码没有处理网络异常,很有可能跑到一半就GG了,重来又是4小时...)

怎么办?这个时候就需要一些统计学知识了。我们先随机抽取200场比赛看看情况。

200场比赛的结果是这样的:

  • 93场比赛无法获得「拆塔信息」数据,属于无效样本。
  • 剩下的107场比赛中,先拆掉敌方中一塔获胜的场次是67场,67/107=62.6%。

62.6%!意思是只要先拆掉敌方中一塔,就有6成以上的胜率?不好说,因为这只是107场比赛的数据(总共有1万多场比赛),比如我们再重新抽107场比赛,结果很可能会不一样。那么问题来了,这个62.6%的可信度有多高?

这需要用到「统计推断」的知识(推荐一本书《OpenIntro Statistics》)。我们采样的每场比赛之间相互独立,同时正负样本的数量都大于10(说明采样结果的分布没有严重偏曲)。根据「中心极限定理」,采样结果的分布近似服从正态分布。

先算出标准差为0.047,然后算出95%置信区间为[53.4%, 71.8%]。也就是说,根据107场抽样比赛来看,我们有95%的把握:先拆掉敌方中路一塔的队伍,获胜概率在53.4%~71.8%之间。

但是这个结论太粗糙了,只能说明先拆掉中路一塔是件好事(获胜概率>50%),但无法说清楚这件事到底有多好(53%和71%的差距还是很大的)。

为了缩小置信区间的宽度使估计值更精确,我们可以增加样本数量:

  • 随机抽取223场比赛(先拆掉中路一塔的队伍获胜场次为142,142/223=63.7%),获胜概率的95%置信区间为[57.4%, 70%]
  • 随机抽取528场比赛(先拆掉中路一塔的队伍获胜场次为347,347/528=65.7%),获胜概率的95%置信区间为[61.7%, 69.8%]
  • 随机抽取1979场比赛(先拆掉中路一塔的队伍获胜场次为1280,1280/1979=64.7%),获胜概率的95%置信区间为[62.6%, 66.8%]
  • ...

不需要更多的样本了——当样本数量为2000场时,我们已经可以很自信的说(95%的概率):先拆掉中路一塔的队伍,具有一定的优势,获胜概率在62.6%~66.8%之间。

那么问题又来了,这64.7%左右的胜率算高吗?(老队长:我就问你有什么影响?)到目前为止,我们可以用于比较的参考值只有「先拆掉基地的胜率为100%」,没啥意义,但我们完全可以用相同的方法论给出更多、更有意义的benchmark(基准):【以下都是95%置信区间】

  • 拿到第一个肉山盾的队伍,获胜概率是[73.5%,77.3%]
  • 拿到一血的队伍,获胜概率是[52.7%, 57.1%]
  • 先拆掉第一座防御塔(上\中\下任意一座)的队伍,获胜概率是[59.4%,63.7%]

有了对比,我们就可以得出结论:中路一塔的战略地位确实高于边路一塔(只要先于敌方拆掉中一塔,就能建立优势,提升胜率),但也没有特别重要(不如第一个肉山盾)。

写到这里,一个完整的数据分析例子就算完成了。但「完整」并不代表「完结」:

  1. 从深度上来讲:大家可以对比分析中一塔被拆掉前后,有没有影响队伍的打钱速度、活动范围?找出中一塔具体的影响因素,从而在实战中调整策略。
  2. 从广度上来讲:大家可以加入战队、版本号等维度,对样本进行拆分,描述中一塔战略地位的变化和队伍风格。

当然,我觉得更好的学习方法是:从兴趣出发,找到自己认为有意义问题,用相同的方法论处理数据,得出结论。

特别鸣谢:何求知

原文发布于微信公众号 - 数据冰山(shujubingshan)

原文发表时间:2018-05-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AI研习社

博客 | 对学习/理解 Word2Vec 有帮助的材料

之前面试被面到了,加上一直不是很理解词嵌入的工作方式,所以这段时间找了不少相关的资料想把这玩意儿搞明白。理解还是有限,就不自不量力自己写一篇了(就算写也是把已有...

15940
来自专栏量子位

想象力惊人!只凭一句话,AI就能脑补出动漫小片

安妮薇,《摩登原始人》是一部首播于1960年的喜剧动画片。第一季在豆瓣上被2.2万用户打出8.7分的评价。

11730
来自专栏企鹅号快讯

Apache顶级开源项目——机器学习库MADlib简介与应用实例

内容来源:2017年11月4日,Pivotal Greenplum Madlib研发工程师梅靖怡在“Greenplum和机器 学习客户研讨会”进行《Machin...

427100
来自专栏程序员的碎碎念

翻译 | 深度学习机器72小时自学国际象棋达到大师水平

本文在腾讯云+社区人工智能专栏首发, 为原创翻译文章. 文章正文部分以引用格式给出原文 导读 英文原文发布于2015年9月, 当时 Google 旗下 Dee...

46160
来自专栏媒矿工厂

【视频编码】 Content Aware ABR技术(十二)

在本系列前面的帖子中,我们连续梳理了Netflix、YouTube、Beamr、EuclidIQ、Bitmovin、Harmonic、V-Nova、Cisco、...

19810
来自专栏IT大咖说

Apache顶级开源项目——机器学习库MADlib简介与应用实例

摘要 Apache MADlib是Pivotal与UCBerkeley合作的一个开源机器学习库,提供了精确的数据并行实现、统计和机器学习方法对结构化和非结构化数...

38180
来自专栏CDA数据分析师

资源 | 工程师必备!最好的九张机器学习;深度学习代码速查

作者在 Github 上建立了一个代码速查表,对机器学习初学者来说是不可多得的一个资源。文章中的高清图片附加百度网盘,读者可从中浏览,也可以点击项目地址或文后的...

24090
来自专栏机器学习原理

NLP(6)——命名实体识别

普通的工具如hanlp,htp,不能识别特定领域的专有名词,所以需要实体识别的算法。下面就以医疗专业为例子来谈一下医疗专业的命名实体识别。

31230
来自专栏ATYUN订阅号

谷歌开发AI系统Piano Genie,按几个按钮就能即兴创作音乐

谷歌研究人员开发了一种新的基于深度学习的系统,任何人都可以像训练有素的音乐家一样弹钢琴。该系统名为Piano Genie,自动预测歌曲中下一个最可能的音符,使非...

13830
来自专栏新智元

【NIPS 2018重大漏洞】审稿信息泄露,1000多学术会议双盲评审受牵连

【新智元导读】NIPS 2018又出事了:审稿信息泄露,由于论文提交CMT系统的重大漏洞,审稿人可以判断出单篇论文的姓名和机构,让双盲评审失效!不仅如此,本届N...

17320

扫码关注云+社区

领取腾讯云代金券