分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

利用Python进行NBA比赛数据分析

一、实验介绍

1.1 内容简介

不知道你是否朋友圈被刷屏过nba的某场比赛进度或者结果?或者你就是一个nba狂热粉,比赛中的每个进球,抢断或是逆转压哨球都能让你热血沸腾。除去观赏精彩的比赛过程,我们也同样好奇比赛的结果会是如何。因此本节课程,将给同学们展示如何使用nba比赛的以往统计数据,判断每个球队的战斗力,及预测某场比赛中的结果。

我们将基于2015-2016年的NBA常规赛及季后赛的比赛统计数据,预测在当下正在进行的2016-2017常规赛每场赛事的结果。

1.2 实验知识点

  • nba球队的Elo score计算
  • 特征向量
  • 逻辑回归

1.3 实验环境

  • python2.7
  • Xfce终端

1.4 实验流程

本次课程我们将按照下面的流程实现NBA比赛数据分析的任务:

  1. 获取比赛统计数据
  2. 比赛数据分析,得到代表每场比赛每支队伍状态的特征表达
  3. 利用机器学习方法学习每场比赛与胜利队伍的关系,并对2016-2017的比赛进行预测

1.5 代码获取

本次实验的源码可通过以下命令获得:

$ wget http://labfile.oss.aliyuncs.com/courses/782/prediction.py

二、获取 NBA比赛统计数据

2.1 比赛数据介绍

在本次实验中,我们将采用Basketball Reference.com中的统计数据。在这个网站中,你可以看到不同球员、队伍、赛季和联盟比赛的基本统计数据,如得分,犯规次数等情况,胜负次数等情况。而我们在这里将会使用2015-16 NBA Season Summary中数据。

在这个2015-16总结的所有表格中,我们将使用的是以下三个数据表格:

  • Team Per Game Stats:每支队伍平均每场比赛的表现统计
数据名 含义
Rk -- Rank 排名
G -- Games 参与的比赛场数(都为82场)
MP -- Minutes Played 平均每场比赛进行的时间
FG--Field Goals 投球命中次数
FGA--Field Goal Attempts 投射次数
FG%--Field Goal Percentage 投球命中次数
3P--3-Point Field Goals 三分球命中次数
3PA--3-Point Field Goal Attempts 三分球投射次数
3P%--3-Point Field Goal Percentage 三分球命中率
2P--2-Point Field Goals 二分球命中次数
2PA--2-point Field Goal Attempts 二分球投射次数
2P%--2-Point Field Goal Percentage 二分球命中率
FT--Free Throws 罚球命中次数
FTA--Free Throw Attempts 罚球投射次数
FT%--Free Throw Percentage 罚球命中率
ORB--Offensive Rebounds 进攻篮板球
DRB--Defensive Rebounds 防守篮板球
TRB--Total Rebounds 篮板球总数
AST--Assists 辅助
STL--Steals 偷球
BLK -- Blocks 封阻
TOV -- Turnovers 失误
PF -- Personal Fouls 个犯
PTS -- Points 得分
  • Opponent Per Game Stats:所遇到的对手平均每场比赛的统计信息,所包含的统计数据与Team Per Game Stats中的一致,只是代表的该球队对应的对手的

  • Miscellaneous Stats:综合统计数据

数据项 数据含义
Rk (Rank) 排名
Age 队员的平均年龄
W (Wins) 胜利次数
L (Losses) 失败次数
PW (Pythagorean wins) 基于毕达哥拉斯理论计算的赢的概率
PL (Pythagorean losses) 基于毕达哥拉斯理论计算的输的概率
MOV (Margin of Victory) 赢球次数的平均间隔
SOS (Strength of Schedule) 用以评判对手选择与其球队或是其他球队的难易程度对比,0为平均线,可以为正负数
SRS (Simple Rating System) 3
ORtg (Offensive Rating) 每100个比赛回合中的进攻比例
DRtg (Defensive Rating) 每100个比赛回合中的防守比例
Pace (Pace Factor) 每48分钟内大概会进行多少个回合
FTr (Free Throw Attempt Rate) 罚球次数所占投射次数的比例
3PAr (3-Point Attempt Rate) 三分球投射占投射次数的比例
TS% (True Shooting Percentage) 二分球、三分球和罚球的总共命中率
eFG% (Effective Field Goal Percentage) 有效的投射百分比(含二分球、三分球)
TOV% (Turnover Percentage) 每100场比赛中失误的比例
ORB% (Offensive Rebound Percentage) 球队中平均每个人的进攻篮板的比例
FT/FGA 罚球所占投射的比例
eFG% (Opponent Effective Field Goal Percentage) 对手投射命中比例
TOV% (Opponent Turnover Percentage) 对手的失误比例
DRB% (Defensive Rebound Percentage) 球队平均每个球员的防守篮板比例
FT/FGA (Opponent Free Throws Per Field Goal Attempt) 对手的罚球次数占投射次数的比例

毕达哥拉斯定律:win\% = \frac{{runs \ scored}^2}{{runs \ scored}^2 + {runs \ allowed}^2}win%=​runs scored​2​​+runs allowed​2​​​​runs scored​2​​​​

我们将用这三个表格来评估球队过去的战斗力,另外还需2015-16 NBA Schedule and Results中的2015~2016年的nba常规赛及季后赛的每场比赛的比赛数据,用以评估Elo score(在之后的实验小节中解释)。在Basketball Reference.com中按照从常规赛至季后赛的时间。列出了2015年10月份至2016年6月份的每场比赛的比赛情况。

可在上图中,看到2015年10月份的部分比赛数据。在每个Schedule表格中所包含的数据为:

数据项 数据含义
Date 比赛日期
Start (ET) 比赛开始时间
Visitor/Neutral 客场作战队伍
PTS 客场队伍最后得分
Home/Neutral 主场队伍
PTS 主场队伍最后得分
Notes 备注,表明是否为加时赛等

在预测时,我们同样也需要在2016-17 NBA Schedule and Results中2016~2017年的NBA的常规赛比赛安排数据。

2.2 获取比赛数据

我们将以获取Team Per Game Stats表格数据为例,展示如何获取这三项统计数据。

  1. 进入到basketball-refernce.com中,在导航栏中选择Season并选择2015~2016赛季中的Summary

  2. 进入到2015~2016年的Summary界面后,滑动窗口找到Team Per Game Stats表格,并选择左上方的Share & more,在其下拉菜单中选择Get table as CSV (for Excel):

  3. 复制在界面中生的的csv格式数据,并复制粘贴至一个文本编辑器保存为csv文件即可:

为了方便同学们进行实验,我们已经将数据全部都保存成csv文件上传至实验楼的云环境中。在后续的代码实现小节里,我们将给出获取这些文件的地址。

三、数据分析

在获取到数据之后,我们将利用每支队伍过去的比赛情况和Elo 等级分来判断每支比赛队伍的可胜概率。在评价到每支队伍过去的比赛情况时,我们将使用到Team Per Game Stats,Opponent Per Game Stats和Miscellaneous Stats(之后简称为T、O和M表)这三个表格的数据,作为代表比赛中某支队伍的比赛特征。我们最终将实现针对每场比赛,预测比赛中哪支队伍最终将会获胜,但并不是给出绝对的胜败情况,而是预判胜利的队伍有多大的获胜概率。因此我们将建立一个代表比赛的特征向量。由两支队伍的以往比赛情况统计情况(T、O和M表),和两个队伍各自的Elo等级分构成。

关于Elo score等级分,不知道同学们是否看过《社交网络》这部电影,在这部电影中,Mark(主人公原型就是扎克伯格,FaceBook创始人)在电影起初开发的一个美女排名系统就是利用其好友Eduardo在窗户上写下的排名公式,对不同的女生进行等级制度对比,最后PK出胜利的一方。

这条对比公式就是Elo Score等级分制度。Elo的最初为了提供国际象棋中,更好地对不同的选手进行等级划分。在现在很多的竞技运动或者游戏中都会采取Elo等级分制度对选手或玩家进行等级划分,如足球、篮球、棒球比赛或LOL,DOTA等游戏。

在这里我们将基于国际象棋比赛,大致地介绍下Elo等级划分制度。在上图中Eduardo在窗户上写下的公式就是根据Logistic Distribution计算PK双方(A和B)对各自的胜率期望值计算公式。假设A和B的当前等级分为R_AR​A​​何R_BR​B​​,则A对B的胜率期望值为:

E_A=\frac{1}{1+10^{(R_B-R_A)/400}}E​A​​=​1+10​(R​B​​−R​A​​)/400​​​​1​​

B对A的胜率期望值为

E_B=\frac{1}{1+10^{(R_A-R_B)/400}}E​B​​=​1+10​(R​A​​−R​B​​)/400​​​​1​​

如果棋手A在比赛中的真实得分S_AS​A​​(胜1分,和0.5分,负0分)和他的胜率期望值E_AE​A​​不同,则他的等级分要根据以下公式进行调整:

R_A^{new} = R_A^{old} + K(S_A - R_A^{old})R​A​new​​=R​A​old​​+K(S​A​​−R​A​old​​)

在国际象棋中,根据等级分的不同K值也会做相应的调整:

  • \ge2400≥2400,K=16
  • 2100~2400分,K=24
  • \le2100≤2100,K=32

因此我们将会用以表示某场比赛数据的特征向量为(加入A与B队比赛):[A队Elo score, A队的T,O和M表统计数据,B队Elo score, B队的T,O和M表统计数据]

四、基于数据进行模型训练和预测

4.1 实验前期准备

在本次实验环境中,我们将会使用到python的pandasnumpyscipysklearn库,不过实验楼中已经安装了numpy,所以在实验前,我们需要先利用pip命令安装另外两个Python库。

$ sudo pip install pandas$ sudo pip install scipy$ sudo pip install sklearn

在安装完所需的实验库之后,进入到实验环境的Code目录下,创建cs_782文件夹,并且通过以下地址获取我们为大家处理好的csv文件压缩包data.zip

$ cd Code$ mkdir cs_782 && cd cs_782# 获取数据文件$ wget http://labfile.oss.aliyuncs.com/courses/782/data.zip# 解压data压缩包并且删除该压缩包$ unzip data.zip $ rm -r data.zip

data文件夹中,包含了2015~2016年的NBA数据T,O和M表,及经处理后的常规赛和挑战赛的比赛数据2015~16result.csv,这个数据文件是我们通过在basketball-reference.com的2015-16 Schedule and result的几个月份比赛数据中提取得到的,其中包括三个字段:

  • WTeam: 比赛胜利队伍
  • LTeam: 失败队伍
  • WLoc: 胜利队伍一方所在的为主场或是客场 另外一个文件就是16-17Schedule.csv,也是经过我们加工处理得到的NBA在2016~2017年的常规赛的比赛安排,其中包括两个字段:
  • Vteam: 访问/客场作战队伍
  • Hteam: 主场作战队伍

4.2 代码实现

Code\cs_782目录下,创建prediciton.py开始实验。 首先插入实验相关模块:

# -*- coding:utf-8 -*-import pandas as pdimport mathimport csvimport randomimport numpy as npfrom sklearn import cross_validation, linear_model

设置回归训练时所需用到的参数变量:

# 当每支队伍没有elo等级分时,赋予其基础elo等级分base_elo = 1600team_elos = {} team_stats = {}X = []y = []folder = 'data' #存放数据的目录

在最开始需要初始化数据,从T、O和M表格中读入数据,去除一些无关数据并将这三个表格通过Team属性列进行连接:

# 根据每支队伍的Miscellaneous Opponent,Team统计数据csv文件进行初始化def initialize_data(Mstat, Ostat, Tstat):    new_Mstat = Mstat.drop(['Rk', 'Arena'], axis=1)    new_Ostat = Ostat.drop(['Rk', 'G', 'MP'], axis=1)    new_Tstat = Tstat.drop(['Rk', 'G', 'MP'], axis=1)    team_stats1 = pd.merge(new_Mstat, new_Ostat, how='left', on='Team')    team_stats1 = pd.merge(team_stats1, new_Tstat, how='left', on='Team')    return team_stats1.set_index('Team', inplace=False, drop=True)

获取每支队伍的Elo Score等级分函数,当在开始没有等级分时,将其赋予初始base_elo值:

def get_elo(team):    try:        return team_elos[team]    except:        # 当最初没有elo时,给每个队伍最初赋base_elo        team_elos[team] = base_elo        return team_elos[team]

定义计算每支球队的Elo等级分函数:

# 计算每个球队的elo值def calc_elo(win_team, lose_team):    winner_rank = get_elo(win_team)    loser_rank = get_elo(lose_team)    rank_diff = winner_rank - loser_rank    exp = (rank_diff  * -1) / 400    odds = 1 / (1 + math.pow(10, exp))    # 根据rank级别修改K值    if winner_rank < 2100:        k = 32    elif winner_rank >= 2100 and winner_rank < 2400:        k = 24    else:        k = 16    new_winner_rank = round(winner_rank + (k * (1 - odds)))    new_rank_diff = new_winner_rank - winner_rank    new_loser_rank = loser_rank - new_rank_diff    return new_winner_rank, new_loser_rank

基于我们初始好的统计数据,及每支队伍的Elo score计算结果,建立对应2015~2016年常规赛和季后赛中每场比赛的数据集(在主客场比赛时,我们认为主场作战的队伍更加有优势一点,因此会给主场作战队伍相应加上100等级分):

def  build_dataSet(all_data):    print("Building data set..")    X = []    skip = 0    for index, row in all_data.iterrows():        Wteam = row['WTeam']        Lteam = row['LTeam']        #获取最初的elo或是每个队伍最初的elo值        team1_elo = get_elo(Wteam)        team2_elo = get_elo(Lteam)        # 给主场比赛的队伍加上100的elo值        if row['WLoc'] == 'H':            team1_elo += 100        else:            team2_elo += 100        # 把elo当为评价每个队伍的第一个特征值        team1_features = [team1_elo]        team2_features = [team2_elo]        # 添加我们从basketball reference.com获得的每个队伍的统计信息        for key, value in team_stats.loc[Wteam].iteritems():            team1_features.append(value)        for key, value in team_stats.loc[Lteam].iteritems():            team2_features.append(value)        # 将两支队伍的特征值随机的分配在每场比赛数据的左右两侧        # 并将对应的0/1赋给y值        if random.random() > 0.5:            X.append(team1_features + team2_features)            y.append(0)        else:            X.append(team2_features + team1_features)            y.append(1)        if skip == 0:            print X            skip = 1        # 根据这场比赛的数据更新队伍的elo值        new_winner_rank, new_loser_rank = calc_elo(Wteam, Lteam)        team_elos[Wteam] = new_winner_rank        team_elos[Lteam] = new_loser_rank    return np.nan_to_num(X), y

最终在main函数中调用这些数据处理函数,使用sklearn的Logistic Regression方法建立回归模型:

if __name__ == '__main__':    Mstat = pd.read_csv(folder + '/15-16Miscellaneous_Stat.csv')    Ostat = pd.read_csv(folder + '/15-16Opponent_Per_Game_Stat.csv')    Tstat = pd.read_csv(folder + '/15-16Team_Per_Game_Stat.csv')    team_stats = initialize_data(Mstat, Ostat, Tstat)    result_data = pd.read_csv(folder + '/2015-2016_result.csv')    X, y = build_dataSet(result_data)    # 训练网络模型    print("Fitting on %d game samples.." % len(X))    model = linear_model.LogisticRegression()    model.fit(X, y)    #利用10折交叉验证计算训练正确率    print("Doing cross-validation..")    print(cross_validation.cross_val_score(model, X, y, cv = 10, scoring='accuracy', n_jobs=-1).mean())

最终利用训练好的模型在16~17年的常规赛数据中进行预测。 利用模型对一场新的比赛进行胜负判断,并返回其胜利的概率:

def predict_winner(team_1, team_2, model):    features = []    # team 1,客场队伍    features.append(get_elo(team_1))    for key, value in team_stats.loc[team_1].iteritems():        features.append(value)    # team 2,主场队伍    features.append(get_elo(team_2) + 100)    for key, value in team_stats.loc[team_2].iteritems():        features.append(value)    features = np.nan_to_num(features)    return model.predict_proba([features])

在main函数中调用该函数,并将预测结果输出到16-17Result.csv文件中:

#利用训练好的model在16-17年的比赛中进行预测    print('Predicting on new schedule..')    schedule1617 = pd.read_csv(folder + '/16-17Schedule.csv')    result = []    for index, row in schedule1617.iterrows():        team1 = row['Vteam']        team2 = row['Hteam']        pred = predict_winner(team1, team2, model)        prob = pred[0][0]        if prob > 0.5:            winner = team1            loser = team2            result.append([winner, loser, prob])        else:            winner = team2            loser = team1            result.append([winner, loser, 1 - prob])    with open('16-17Result.csv', 'wb') as f:        writer = csv.writer(f)        writer.writerow(['win', 'lose', 'probability'])        writer.writerows(result)

运行prediction.py

生成预测结果文件16-17Result.csv文件:

利用Python进行NBA比赛数据分析相关推荐

  1. 用python做实验数据分析_Python小实验——利用Python进行NBA比赛数据分析

    首先确定需要统计的数据,以及数据的来源. 通过毕达哥拉斯定律来进行估计:获胜的概率等于得分的平方除以(得分的平方加上机会得分的平方) 使用到了Elo等级划分制度,不懂就去百度 scipy 下载失败,百 ...

  2. 利用Python预测NBA比赛结果

    关注「实验楼」,每天分享一个项目教程 NBA总决赛正在火热上演,而有数据的地方就有预测,本教程就教你使用Python预测NBA比赛的结果. 正文共:3240 字 预计阅读时间:8 分钟‍ 一.实验介绍 ...

  3. python篮球-资深程序员教你,利用python预测NBA比赛结果,太精彩了

    我从小就是NBA篮球迷,长大了从事程序员的工作,即使工作再忙,也不会忘了紧追NBA赛事. 而今天,我就给大家分享一个有关用python分析NBA比赛结果的方法. ​ 1.简单介绍 如何用NBA以往的数 ...

  4. 资深程序员教你,利用python预测NBA比赛结果,太精彩了

    我从小就是NBA篮球迷,长大了从事程序员的工作,即使工作再忙,也不会忘了紧追NBA赛事. 而今天,我就给大家分享一个有关用python分析NBA比赛结果的方法. 如果觉得这个方式比较难,可以看底部,还 ...

  5. Python 预测 NBA 比赛结果

    Python 预测 NBA 比赛结果 一. 内容介绍 不知道你是否在朋友圈被刷屏过 NBA 的某场比赛进度或者结果?或者你就是一个 NBA 狂热粉,比赛中的每个进球.抢断或是逆转压哨球都能让你热血沸腾 ...

  6. 利用Python对NBA SportUV数据进行可视化及分析

    利用Python对NBA SportUV数据进行可视化及分析 SportUV是2005年,由以色列计算机科学家Gal Oz和Miky Tamir 创立的,其实,最早这两位大牛是搞导弹跟踪和高级光学识别 ...

  7. 从贵州茅台上市的第一天起,每天买一手茅台能够盈利多少?-利用python进行茅台股票数据分析

    从贵州茅台上市的第一天起,每天买一手茅台能够盈利多少?-利用python进行茅台股票数据分析(未统计分红和配股数据) 1.使用tushare获取2000至今的股票数据 1)首先, 使用前我们在tush ...

  8. NBA比赛数据分析与预测

    我的任务利用13到16年的NBA比赛统计数据,去预测17年的每场NBA比赛.数据是从http://www.basketball-reference.com/这个网站获得的.前期参考了https://w ...

  9. 字符串是python中特有的数据类型_python小项目一:NBA比赛数据分析

    该项目来源于实验楼,我这里只是记录下自己做完项目的笔记和总结(实验楼是py2的代码,我则是用的py3). 项目目的:通过分析之前的比赛数据,得到每个队伍的状态的特征表达,利用机器学习训练回归模型,从而 ...

最新文章

  1. 【Spring】12、Spring Security 四种使用方式
  2. Heinz College of Information Systems and Public Policy Carnegie Mellon University
  3. Objective-c 创建类的使用
  4. 挺水的一门课,发现全系都过了,就自己挂了,这是一种什么样的感觉呢?
  5. 北理在线作业答案c语言,北理工19春《面向对象程序设计》在线作业【标准答案】...
  6. UNIX标准化及实现之UNIX标准化、UNIX系统实现、标准和实现的关系以及ISO C标准头文件...
  7. php本地文件包含漏洞,php文件包含漏洞利用小结
  8. WPF - ViewModle中关闭Window
  9. compileflow 淘宝工作流引擎
  10. 模电、数电、电路面试题
  11. ubuntu打开只读文件并修改
  12. Hark的数据结构与算法练习之冒泡排序
  13. 数据库的设计关键点总结
  14. ESP-Hosted:降低物联网设备的部署成本与复杂性
  15. opencv 摄像头捕获的图像保存为avi视频 代码解析
  16. 【python】保存某个文件夹下所有图片名字到一个txt文件里
  17. 感恩生命,永不放弃——学习力克胡哲
  18. JPA使用过程中遇到的问题
  19. CCF201812-1 小明上学 (python语言)
  20. 批量删除PPT第一页最后页——VBS脚本,在office宏中运行即可

热门文章

  1. java ole,Java和OLE对象
  2. 别太把技术当回事 也别不把技术当回事
  3. 关于5+APP或wap2app制作实现JS混淆加密的方法(防止解压直接查看源码)
  4. Spring MVC Controler层获取errors验证信息 同时返回
  5. 基于hutool的MD5加密以及hutool的一些常用工具
  6. 北京联通营业厅一览表
  7. 如何在AutoCAD中将卫星底图变为有坐标参考信息的
  8. 《心之所向,素履所往》
  9. 实现CentOS/Ubuntu server上任务栏固定到桌面下方 - 收藏夹一直显示 - 任务栏在哪里 - 任务栏怎么弹出
  10. 抓阄java代码,利用python如何实现团队成员动态抓阄?