本文是作者前一段时间关注足球赛事时做的一点分析,内容涉及基于足球数据进行描述性统计分析、基于机器学习建模与传统的泊松模型建模三大部分,由于文章较长,将分两部分进行展现。
第一部分为前言与述性分析部分1 p) D6 T5 B; ?7 n( _1 p
1定义问题
如果数据科学,大数据,机器学习,预测分析,商业智能等是解决的方案,那么问题是什么?问题决定需求,需求决定方案,方案决定设计,设计决定机理。太多的时候,我们执迷于前沿技术的运用,而忽略了真正问题是否适用于其中。
足球是目前世界上最受欢迎的体育运动项目,但是对于足球分析相关的研究目前还没有达到与其他专业运动一样的分析水平。粗略的统计数据如进球、射门和助攻仍然是分析球员表现的最常用的方法。
对于本次项目来说,问题是如何利用已知的足球数据运用机器学习算法来预测一场足球的比赛结果——胜平负。2收集数据
约翰·奈斯比特(John Naisbitt)在1984年的“大趋势”一书中写道,我们正在“淹没在数据中,而对于发掘其中所蕴含的内容却一筹莫展”。所以,数据无处不在,它可能已经以某种形式而存在,或许是外部或内部的,结构化的或非结构化的,静态的或动态的,客观的或主观的等等。俗话说,你不必重新发明轮子(wheel),你只需知道在哪里找到它。本次数据集为2008-2009赛季英超联赛的所有比赛数据,比赛轮次共38轮,场次共380场,其数据内容为主客场球队的编号(team-api)、比赛时间、比赛编号、主客场进球数、比赛结果、主客场球队队员信息、阵容及各大博彩公司给出的赔率等99个属性。
下图为前10行部分数据信息。
Python 调用命令为:
部分数据结果如下:
3清洗数据
在步骤2中,我们已经获取了大部分的所需足球数据。因此,数据架构、数据管理、数据提取等不在此次正常流程之中,只有数据清理在其范围之中。
清洗数据是将“原始”数据转化为“可利用”数据所需的过程。数据清洗包括数据清理以识别异常,丢失或异常数据点等。3.1调包
对数据进行清理我们将以python语言执行,而python提供了许多可以用于简化工作量的库(library),下面我们将调用这些库,以用于后续的分析。
下图为调用常见的库如函数库,绘图库,调用SQL数据库等。
3.11调用数据模型库
在本问题中,我们将调用scikit-learn 库来进行机器学习分类算法的学习。在sklearn中,算法被称为估计器,并在他们自己划分的数据集中实现。为了实现数据可视化,我们将使用matplotlib和seaborn库。以下是常见的库的加载。
3.2数据初识
在数据初识这一步,我们将通过对数据中属性名和属性值的判断,了解数据的类型和数据的取值,属性是否是独立变量,目标变量的取值又是什么,从而初步建立起对数据的认识。
首先,我们将原数据集导入到程序中,然后我们将使用info()和sample()函数来对数据集中的变量有一个初步的认识情况。
1.RESULT为本次数据集中的结果标签。它的取值为1,0,-1。分别代表了主队胜(1),主队平(0),主队负(-1)。所有其他的属性为潜在的利用数据,我们将逐个进行考量。
2.在本数据集中,ID,COUNTRY-ID,LEAGUE-ID,SEASON,STAGE,TIME,MATCH-API等对结果没有实质性的影响,他们有的是随机变量(ID,API),有的不在本次考察范围之内(STAGE,TIME)。因此,稍后他们将会被剔除,以减少运算的工作量。
3.HOME_TEAM-API为主队的编号,他记录了2008年英超联赛的20支球队的编号;同理,AWAY_TEAM-API为客队的编号。
4.HOME_TEAM-GOAL和AWAY_TEAM-GOAL分别为主客队的进球数,HOME_PLAYx1-x11和AWAY_PLAYx1-x11分别为主客队11名球员在球场中的横坐标位置(初始阵容),HOME_PLAYy1-11和AWAY_PLAYy1-11分别为主客队11名球员在球场中的纵坐标位置(初始阵容)。
5.HOME_PLAYER1-11和AWAY_PLAYER1-11分别为主客场11名球员的编号。
6.余下指标为各大博彩公司的胜平负赔率,如B365H,B365D,B365A分别代表了主场球队获胜赔率,主场球队打平赔率,主场球队打输赔率。
部分结果如下:
3.21数据清理的4C准则:纠正(correcting),填补(complement),构建指标(creating)和转换格式(converting)
将数据导入后,我们将通过1)校正异常值,2)完成缺失信息,3)构建新的指标用于分析,4)将字段转换为正确的格式进行计算和表示四个步骤进行数据的清洗。
1校正异常值:遍览数据,观察是否存在数据的异常值,如进球数是否为负或超过10个。倘若数据异常,我们需要格外审视,判断其是否真实,后续的一系列分析都以此为前提而展开。
2填补缺失值:在主客场球员编号部分存在一些缺失值,我们需要自行填补。对于部分数据的缺失,虽然决策树提供了一种有力的分析工具,但是对于大多数算法来说,存在缺失意味着算法将不可操作。因而,填补的工作是必要的。
通常有两类方法用于填补缺失值:1)删除2)以一种合理的方式填补。通常我们不建议删除大量的数据,除非其丢失现象很严重。在本次数据集中,角球、传球、射正等数据全部丢失,故删去,而对于上场球员编号来说,丢失部分不到5%,我们采用填补的方式进行处理。我们通过统计该球队处于该位置的球员编号来获取其众数,倘若存在多组相同数据(如A球队B位置2人同一位置上场次数相同),我们将考虑距离缺失场次最近的那一场球员编号。
3构建新的指标用于分析:在本问题中,我们拟将角球、射正、控球等数据用于构建新指标,但由于其大量缺失,指标也无法建立。
4格式转换:原数据集中比赛结果是以字符格式存储,这增加了后续的分类的工作量,故我们采用数值型数据替代,原”home_win”,”tie”,”away_win”分别替代为‘1’,‘0’,‘-1’。3.22划分训练集和测试集
我们将使用sklearn的train_test_split函数将训练数据分成两个数据集:75%和25%,这么做是为了防止模型的过拟合。在后面的章节中,我们还将使用sklearn的交叉验证函数,将我们的数据集交叉验证以进行数据建模比较。
' r* g! L) _, T7 z& S5 a
程序结果如下:
7 W2 C+ h& ^6 s; H4.进行探索性分析
在清洗完数据后,我们将对数据进行探索性分析,主要运用描述性统计的一些方法来对数据有一定的认识。
部分程序如下:
1 z0 H" \. a! N+ `* P. A. w0 u
我们首先对主客队的进球数和主场胜率期望进行统计,箱线图结果如下:
! Z; k# A! u( H0 j" c4 h8 q
可以看到,主场球队进球数在0-6之间,均值在1.5左右,大多数进球集中在0-2之间。而客场球队进球数在0-5之间,均值在1左右,进球也多集中在0-2之间。第三幅箱线图则表明主场胜率期望总体来说在0.25附近,这表明在比赛中,球队的主客场次的确起到一定的作用。
接下来,我们对主客场进球数进行了统计,统计结果如下:
结果表明,对于主场球队,如果其在本次比赛中进球在2球及以上,该球队有很大可能获得比赛的胜利,而客场球队想要赢得比赛,则需要2球以上(3球)才能锁定比赛的胜利,对于平局,数据显示双方球队倘若各自进球粒数在2球以下的话,平局的可能性很大,如果双方进球粒数在1球及以下,本场比赛很大可能以平局结束。
我们通过下图也能清晰地得到如上结论。下图表明,在主场球队进球超过2个时,主队获胜的几率已经达到了90%以上,进球数在2球时,主队获胜几率在60%左右。再看客队数据,我们可以看到,当客队进球在3球及以上时,客队获胜(即主队失败)的概率在75%以上。
最后,我们再看一看主客队进球的分布曲线,结果如下:
主场球队进球分布曲线:
客场球队进球曲线:
总的来说,对于主场球队,球队获胜时的进球数近似服从正态分布,对应地就是客场球队失败时的进球数也近似服从正态分布。同时,我们对比两图可以发现,主客场进球数分布图是一一对应地,如主场获胜分布图与客场失败分布图类似,又如主场失败分布图与客场获胜分布图类似。
2 _7 E6 H9 @1 o9 o# t$ i4 \/ \+ u7 ` x$ N: ^; q