采用 Python 机器学习预测足球比赛结果

采用 Python 机器学习预测足球比赛结果

足球是世界上最火爆的运动之一,世界杯期间也往往是球迷们最亢奋的时刻。比赛狂欢季除了炸出了熬夜看球的铁杆粉丝,也让足球竞猜也成了大家茶余饭后最热衷的话题。甚至连原来不怎么看足球的人,也是暗中努力恶补了很多足球相关知识,想通过赛事竞猜先赚一个小目标。今天我们将介绍如何用机器学习来预测足球比赛结果!

本 Chat 采用 Python 编程语言,使用 人工智能建模平台 Mo 作为在线开发环境进行编程,通过获取 2000 年到 2018 年共 19 年英超的比赛数据,然后基于监督学习中逻辑回归模型、支持向量机模型和 XGBoost 模型,对英超比赛结果进行预测。

下面我们一起来看看预测英超比赛结果的机器学习步骤:

主要流程步骤

  1. 获取数据和读取数据的信息
  2. 数据清洗和预处理
  3. 特征工程
  4. 建立机器学习模型并进行预测
  5. 总结与展望

1. 获取数据和读取数据的信息

首先我们进入 Mo 工作台,创建一个空白项目,点击 开始开发 进入内嵌 JupyterLab 的 Notebook 开发环境。

接着我们需要在项目中上传数据集

英超每年举办一个赛季,在每年的 8 月到第二年的 5 月进行,共有 20 支球队,实行主客场双循环赛制,每个赛季共 38 轮比赛(其中 19 场主场比赛,19 场客场比赛),每轮比赛共计 10 场比赛,所以每个赛季,英超共有 380 场比赛。

如果您已经在 MO 平台新建项目,可以在平台直接导入数据集,流程如下:

1.1 读取 csv 数据接口解释
  • 采用 Pandas 读取、写入数据 API 汇总网址
    读取 csv 数据一般采用 pandas.read_csv():
    pandas.read_csv(filepath_or_buffer, sep =',' , delimiter = None)
    • filepath_or_buffer:文件路径
    • sep:指定分隔符,默认是逗号
    • delimiter:定界符,备选分隔符(如果指定改参数,则sep失效)
    • usecols: 指定读取的列名,列表形式
# 导入必须的包
import warnings
warnings.filterwarnings('ignore')  # 防止警告文件的包
import pandas as pd  # 数据分析包
import os
import matplotlib.pyplot as plt # 可视化包
import matplotlib
%matplotlib inline
import seaborn as sns  # 可视化包
from time import time
from sklearn.preprocessing import scale  # 标准化操作
from sklearn.model_selection import train_test_split  # 将数据集分成测试集和训练集
from sklearn.metrics import f1_score  # F1得分
import xgboost as xgb  # XGBoost模型
from sklearn.svm import SVC  ## 支持向量机分类模型
from sklearn.linear_model import LogisticRegression  # 逻辑回归模型
from sklearn.model_selection import GridSearchCV  # 超参数调参模块
from sklearn.metrics import make_scorer  # 模型评估
import joblib  # 模型的保存与加载模块
复制代码

下面开始我们的表演:

# 获取地址中的所有文件
loc = './/football//' # 存放数据的路径
res_name = []  # 存放数据名的列表
filecsv_list = []  # 获取数据名后存放的列表
def file_name(file_name):
    # root:当前目录路径   dirs:当前目录下所有子目录   files:当前路径下所有非目录文件
    for root,dirs,files in os.walk(file_name):
        files.sort() # 排序,让列表里面的元素有顺序
        for i,file in enumerate(files):
            if os.path.splitext(file)[1] == '.csv':
                filecsv_list.append(file)
                res_name.append('raw_data_'+str(i+1))
    print(res_name)
    print(filecsv_list)
file_name(loc)
复制代码
['raw_data_1', 'raw_data_2', 'raw_data_3', 'raw_data_4', 'raw_data_5', 'raw_data_6', 'raw_data_7', 'raw_data_8', 'raw_data_9', 'raw_data_10', 'raw_data_11', 'raw_data_12', 'raw_data_13', 'raw_data_14', 'raw_data_15', 'raw_data_16', 'raw_data_17', 'raw_data_18', 'raw_data_19']

['2000-01.csv', '2001-02.csv', '2002-03.csv', '2003-04.csv', '2004-05.csv', '2005-06.csv', '2006-07.csv', '2007-08.csv', '2008-09.csv', '2009-10.csv', '2010-11.csv', '2011-12.csv', '2012-13.csv', '2013-14.csv', '2014-15.csv', '2015-16.csv', '2016-17.csv', '2017-18.csv', '2018-19.csv']
复制代码
1.2 时间列表

获取每一年的数据后,将每一年的年份放入到 time_list 列表中:

time_list = [filecsv_list[i][0:4]  for i in range(len(filecsv_list))]
time_list
复制代码

['2000','2001','2002','2003','2004','2005','2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016','2017','2018']

1.3 用 Pandas.read_csv()  接口读取数据

读取时将数据与 res_name 中的元素名一一对应。

for i in range(len(res_name)):
    res_name[i] = pd.read_csv(loc+filecsv_list[i],error_bad_lines=False)
    print('第%2s个文件是%s,数据大小为%s'%(i+1,filecsv_list[i],res_name[i].shape))
复制代码
第 1个文件是2000-01.csv,数据大小为(380, 45)
第 2个文件是2001-02.csv,数据大小为(380, 48)
第 3个文件是2002-03.csv,数据大小为(316, 48)
第 4个文件是2003-04.csv,数据大小为(335, 57)
第 5个文件是2004-05.csv,数据大小为(335, 57)
第 6个文件是2005-06.csv,数据大小为(380, 68)
第 7个文件是2006-07.csv,数据大小为(380, 68)
第 8个文件是2007-08.csv,数据大小为(380, 71)
第 9个文件是2008-09.csv,数据大小为(380, 71)
第10个文件是2009-10.csv,数据大小为(380, 71)
第11个文件是2010-11.csv,数据大小为(380, 71)
第12个文件是2011-12.csv,数据大小为(380, 71)
第13个文件是2012-13.csv,数据大小为(380, 74)
第14个文件是2013-14.csv,数据大小为(380, 68)
第15个文件是2014-15.csv,数据大小为(381, 68)
第16个文件是2015-16.csv,数据大小为(380, 65)
第17个文件是2016-17.csv,数据大小为(380, 65)
第18个文件是2017-18.csv,数据大小为(380, 65)
第19个文件是2018-19.csv,数据大小为(304, 62)
复制代码
1.4 删除特定文件的空值

经过查看第 15 个文件读取的第 381 行为空值,故采取删除行空值操作。

1.4.1 删除空值的接口
  • Pandas.dropna(axis=0,how='any')
    • axis: 0 表示是行;1表示是列
    • how:'all'表示只去掉所有值均缺失的行、列;any表示只去掉有缺失值的行、列
1.4.2 接口运用
res_name[14] = res_name[14].dropna(axis=0,how='all')
res_name[14].tail()
复制代码
Div Date HomeTeam AwayTeam FTHG FTAG FTR HTHG HTAG HTR ... BbAv<2.5 BbAH BbAHh BbMxAHH BbAvAHH BbMxAHA BbAvAHA PSCH PSCD PSCA
375 E0 24/05/15 Hull Man United 0.0 0.0 D 0.0 0.0 D ... 1.99 25.0 0.50 1.76 1.71 2.27 2.19 3.20 3.76 2.27
376 E0 24/05/15 Leicester QPR 5.0 1.0 H 2.0 0.0 H ... 2.41 28.0 -1.00 1.98 1.93 1.98 1.93 1.53 4.94 6.13
377 E0 24/05/15 Man City Southampton 2.0 0.0 H 1.0 0.0 H ... 2.66 28.0 -1.00 2.00 1.94 2.03 1.93 1.60 4.35 6.00
378 E0 24/05/15 Newcastle West Ham 2.0 0.0 H 0.0 0.0 D ... 2.25 25.0 -0.50 1.82 1.78 2.20 2.10 1.76 4.01 4.98
379 E0 24/05/15 Stoke Liverpool 6.0 1.0 H 5.0 0.0 H ... 1.99 25.0 0.25 2.07 2.02 1.88 1.85 3.56 3.60 2.17

5 rows × 68 columns

1.5 删除行数不是 380 的文件名

考虑到英超一般是 19 个球队,每个球队需要打 20 场球,故把行数不是 380 的数据删除掉,并找到器原 CSV 文件一一对应。

for i in range(len(res_name),0,-1): 
    # 采用从大到小的遍历方式,然后进行删除不满足条件的。
    if res_name[i-1].shape[0] != 380:
        key = 'res_name[' + str(i) + ']'
        print('删除的数据是:%s年的数据,文件名:%s大小是:%s'%(time_list[i-1],key,res_name[i-1].shape))
        res_name.pop(i-1)
        time_list.pop(i-1)
        continue
复制代码
删除的数据是:2018年的数据,文件名:res_name[19]大小是:(304, 62)
删除的数据是:2004年的数据,文件名:res_name[5]大小是:(335, 57)
删除的数据是:2003年的数据,文件名:res_name[4]大小是:(335, 57)
删除的数据是:2002年的数据,文件名:res_name[3]大小是:(316, 48)
复制代码
1.6 查看某一个数据集前n行数据
  • 文件名.head(n)
    • n:默认是5,想获取多少行数据就填写数字值。

读取数据前五行操作:

res_name[0].head()
复制代码
Div Date HomeTeam AwayTeam FTHG FTAG FTR HTHG HTAG HTR ... IWA LBH LBD LBA SBH SBD SBA WHH WHD WHA
0 E0 19/08/00 Charlton Man City 4 0 H 2 0 H ... 2.7 2.20 3.25 2.75 2.20 3.25 2.88 2.10 3.2 3.10
1 E0 19/08/00 Chelsea West Ham 4 2 H 1 0 H ... 4.2 1.50 3.40 6.00 1.50 3.60 6.00 1.44 3.6 6.50
2 E0 19/08/00 Coventry Middlesbrough 1 3 A 1 1 D ... 2.7 2.25 3.20 2.75 2.30 3.20 2.75 2.30 3.2 2.62
3 E0 19/08/00 Derby Southampton 2 2 D 1 2 A ... 3.5 2.20 3.25 2.75 2.05 3.20 3.20 2.00 3.2 3.20
4 E0 19/08/00 Leeds Everton 2 0 H 2 0 H ... 4.5 1.55 3.50 5.00 1.57 3.60 5.00 1.61 3.5 4.50

5 rows × 45 columns

读取数据前10行:

res_name[0].head(10)
复制代码
Div Date HomeTeam AwayTeam FTHG FTAG FTR HTHG HTAG HTR ... IWA LBH LBD LBA SBH SBD SBA WHH WHD WHA
0 E0 19/08/00 Charlton Man City 4 0 H 2 0 H ... 2.7 2.20 3.25 2.75 2.20 3.25 2.88 2.10 3.20 3.10
1 E0 19/08/00 Chelsea West Ham 4 2 H 1 0 H ... 4.2 1.50 3.40 6.00 1.50 3.60 6.00 1.44 3.60 6.50
2 E0 19/08/00 Coventry Middlesbrough 1 3 A 1 1 D ... 2.7 2.25 3.20 2.75 2.30 3.20 2.75 2.30 3.20 2.62
3 E0 19/08/00 Derby Southampton 2 2 D 1 2 A ... 3.5 2.20 3.25 2.75 2.05 3.20 3.20 2.00 3.20 3.20
4 E0 19/08/00 Leeds Everton 2 0 H 2 0 H ... 4.5 1.55 3.50 5.00 1.57 3.60 5.00 1.61 3.50 4.50
5 E0 19/08/00 Leicester Aston Villa 0 0 D 0 0 D ... 2.5 2.35 3.20 2.60 2.25 3.25 2.75 2.40 3.25 2.50
6 E0 19/08/00 Liverpool Bradford 1 0 H 0 0 D ... 8.0 1.35 4.00 8.00
  • 6
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值