作为一个NBA球迷,看到这一章还是挺激动的。
不过内容有点难,研究了半天。。。

要是赌球的,用这章的预测+凯利公式,是不是就能提升赢钱概率了?

数据预处理

回归书本内容,既然要分析,首先需要有数据:
打开basketball-reference数据链接:


点开Get table as CSV (for Excel),这样我们就能获得数据了。
常规赛是4月16日截至,我们使用常规赛的数据~
直接crtl+C,crtl+V到txt,直接改名csv即可。
(就几个月份,如果要弄的数据多的,可以爬虫)

我们先用pandas来读取一下:

import pandas as pd
data_filename = r'保存路径\文件名.csv'
dataset = pd.read_csv(data_filename)
print(dataset)

可以看到,自动识别成了一个1230 rows x 10 columns的<class ‘pandas.core.frame.DataFrame’>。(图片略掉)

各列名称为:
Date Start (ET) Visitor/Neutral PTS Home/Neutral PTS.1 Unnamed: 6 Unnamed: 7 Attend. Notes
其中,空白自己识别为:Unnamed:列号。
现在,我们把它重命名一下,防止客队和主队的分数看不清楚。
同时把日期转换成数据格式:parse_dates=[0] ##代表第0列的数据日期格式进行转换。

import pandas as pd
data_filename = r'保存路径\文件名.csv'
dataset = pd.read_csv(data_filename, parse_dates=[0])
dataset.columns = ["Date","Start","Visitor Team","VisitorPts", "Home Team", "HomePts","Score Type","OT?", "Attend.", "Notes"]
print(dataset)



可以看到这次的格式就相当整齐,且每一列的表头都完善了。

提取新特征

篮球比赛肯定有输赢,得分高的队伍,就是赢家,所以可以通过简单的判断,来增加一列数据,来判断home是否战胜了vistor:
dataset[“HomeWin”]= dataset[“VisitorPts”] < dataset[“HomePts”]
在把这列单独抽取,作为我们的预测是否准确的判断值:
y_true = dataset[“HomeWin”].values

为了预测这个结果,我们先通过简单的方法:
看看这个队伍上一轮,是否取得了胜利,
如果球队是第一次出现,则默认他们上一场是输球。(当然这里是可以改进的。)
实现方法为:
from collections import defaultdict
dataset[“HomeLastWin”] = False
dataset[“VisitorLastWin”] = False
won_last = defaultdict(int)

字典的键为球队,值为是否赢得上一场比赛。
遍历所有行,在此过程中,更新每一行,为其增加两个特征值:两支球队在上场比赛有没有获胜,并且更新defaultdict:
for index, row in dataset.iterrows(): ##遍历所有行,index是行号,row是具体内容。
home_team = row[“Home Team”] ##提取主队名
visitor_team = row[“Visitor Team”] ##提取客队名
row[“HomeLastWin”] = won_last[home_team] ##第n行的主队上一轮否赢球进行赋值,默认为0(False)
row[“VisitorLastWin”] = won_last[visitor_team] ##第n行的客队上一轮否赢球进行赋值,默认为0(False)
dataset.ix[index] = row ##
won_last[home_team] = row[“HomeWin”] ##更新defaultdict
won_last[visitor_team] = not row[“HomeWin”] ##更新defaultdict

我们可以看一下,20~25行的数据,与每一行的结构究竟是如何的:
if index==25:print(row,type(row)) ## 打印index==25的row
print(dataset.ix[20:25]) ##循坏外,打印20~25行(是包含25的)的DataFrame
整理代码并看结果:

import pandas as pd
import numpy as np
from collections import defaultdictdata_filename = r'保存路径\文件名.csv'
dataset = pd.read_csv(data_filename, parse_dates=[0])
dataset.columns = ["Date","Start","Visitor Team","VisitorPts", "Home Team", "HomePts","Score Type","OT?", "Attend.", "Notes"]
dataset["HomeWin"] = dataset["VisitorPts"] < dataset["HomePts"]
y_true = dataset["HomeWin"].valuesdataset["HomeLastWin"] = False
dataset["VisitorLastWin"] = False
won_last = defaultdict(int)
for index, row in dataset.iterrows():home_team = row["Home Team"] ##提取主队名visitor_team = row["Visitor Team"] ##提取客队名row["HomeLastWin"] = won_last[home_team] ##第n行的主队上一轮否赢球进行赋值,默认为0(False)row["VisitorLastWin"] = won_last[visitor_team] ##第n行的客队上一轮否赢球进行赋值,默认为0(False)dataset.ix[index] = row ##won_last[home_team] = row["HomeWin"]won_last[visitor_team] = not row["HomeWin"]if index==25:print(row,type(row))print(dataset.ix[20:25])

可以看到,row的结果非常清晰,且for index, row in dataset.iterrows():
这句非常像enumerate()函数。


决策树(Decision tree)

接下来就要进入正题了:
既然获取了y_true这个真值,又获取了HomeLastWinVisitorLastWin这2个条件,那么就可以进行决策树的预测了。

决策树是一种有监督的机器学习算法,它看起来就像是由一系列节点组成的流程图,其中位于上层节点的值决定下一步走向哪个节点。


首先是训练阶段,用训练数据构造一棵树。上一章的近邻算法没有训练阶段,但是决策树需要。从这个意义上说,近邻算法是一种惰性算法,在用它进行分类时,它才开始干活。相反,决策树跟大多数机器学习方法类似,是一种积极学习的算法,在训练阶段完成模型的创建。
 其次是预测阶段,用训练好的决策树预测新数据的类别。以上图为例,[“is raining”,“very
windy”]的预测结果为“Bad”(坏天气)。

决策树中的参数

退出准则是决策树的一个重要特性。构建决策树时,最后几步决策仅依赖于少数个体,随意性大。使用特定节点作出推测容易导致过拟合训练数据,而使用退出准则可以防止决策精度过高。
除了设定退出准则外,也可以先创建一棵完整的树,再对其进行修剪,去掉对整个过程没有提供太多信息的节点。这个过程叫作剪枝(pruning)。
scikit-learn库实现的决策树算法给出了退出方法,使用下面这两个选项就可以达到目的。
min_samples_split:指定创建一个新节点至少需要的个体数量。。
min_samples_leaf:指定为了保留节点,每个节点至少应该包含的个体数量。
第一个参数控制着决策节点的创建,第二个参数决定着决策节点能否被保留。 决策树的另一个参数是创建决策的标准,常用的有以下两个。
基尼不纯度(Gini impurity):用于衡量决策节点错误预测新个体类别的比例。
信息增益(Informationgain):用信息论中的熵来表示决策节点提供多少新信息。

使用决策树

from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(random_state=14)

然后可以通过主客队上一场的输赢情况来进行预测。
X_previouswins = dataset[[“HomeLastWin”, “VisitorLastWin”]].values
依旧是深究过的cross_val_score函数来进行评分。
from sklearn.model_selection import cross_val_score
scores = cross_val_score(clf, X_previouswins, y_true,scoring=‘accuracy’)
print(“Accuracy: {0:.1f}%”.format(np.mean(scores) * 100))

整理代码如下:

import pandas as pd
import numpy as np
from collections import defaultdict
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_scoredata_filename = r'保存路径\文件名.csv'
dataset = pd.read_csv(data_filename, parse_dates=[0])
dataset.columns = ["Date","Start","Visitor Team","VisitorPts", "Home Team", "HomePts","Score Type","OT?", "Attend.", "Notes"]
dataset["HomeWin"] = dataset["VisitorPts"] < dataset["HomePts"]
y_true = dataset["HomeWin"].valuesdataset["HomeLastWin"] = False
dataset["VisitorLastWin"] = False
won_last = defaultdict(int)
for index, row in dataset.iterrows():home_team = row["Home Team"] ##提取主队名visitor_team = row["Visitor Team"] ##提取客队名row["HomeLastWin"] = won_last[home_team] ##第n行的主队上一轮否赢球进行赋值,默认为0(False)row["VisitorLastWin"] = won_last[visitor_team] ##第n行的客队上一轮否赢球进行赋值,默认为0(False)dataset.ix[index] = row ##won_last[home_team] = row["HomeWin"]won_last[visitor_team] = not row["HomeWin"]clf = DecisionTreeClassifier(random_state=14)
X_previouswins = dataset[["HomeLastWin", "VisitorLastWin"]].values
scores = cross_val_score(clf, X_previouswins, y_true,scoring='accuracy')
print("Accuracy: {0:.1f}%".format(np.mean(scores) * 100))

结果为:Accuracy: 57.8%
比起随机预测的50%来准确了一丢丢。。。
从数据集中构建有效特征(Feature Engineering,特征工程)是数据挖掘的难点所在,好的特征直接关系到结果的正确率——甚至比选择合适的算法更重要!
那么接下来思考这2个问题:
 一般而言,什么样的球队水平更高?
 两支球队上一次相遇时,谁是赢家?
通常,上一赛季的常规赛结果,对下一赛季还是有指导意义的。
(但不排除马刺摆烂获取邓肯后的突飞猛进,或者是詹黄远走洛杉矶骑士彻底摆烂之类的情况)
获取2013年常规赛的战绩:
保存成CSV之后,继续用pandas读取数据:
standings_filename = r’保存路径\文件名.csv’
standings = pd.read_csv(standings_filename)
print(standings)


可以看到,详细记载了总战绩,主场,客场,对东部,对西部,分区,分差小于3分,每个月战绩等等数据。
现在,我们只使用一列数据:排名!
dataset[“HomeTeamRanksHigher”] = 0 ##之前的dataset新增一列数据:主队排名更高为1,默认为0。
for index, row in dataset.iterrows(): ##继续循环每一行
home_team = row[“Home Team”]
visitor_team = row[“Visitor Team”] ##获取主客队名称。
但是。。。有个情况是,2014年,新奥尔良黄蜂改名为了鹈鹕。。。所以需要进行替换。
if home_team == “New Orleans Pelicans”:
home_team = “New Orleans Hornets”
elif visitor_team == “New Orleans Pelicans”:
visitor_team = "New Orleans Hornets"

获取主队的排名:
home_rank = standings[standings[“Team”] ==home_team][“Rk”].values[0]
即,首先对standings这个DataFrame中的Team列的所有数据进行判断,是否是home_team:standings[“Team”]==home_team
然后获取这个home_team的排名。
同理可以获取客队的排名:
visitor_rank = standings[standings[“Team”]==visitor_team][“Rk”].values[0]
然后更新 “HomeTeamRanksHigher"的数据:
row[“HomeTeamRanksHigher”] = int(home_rank > visitor_rank)
最后,令dataset.ix[index] = row
这样子,除了"HomeLastWin”, “VisitorLastWin”,我们又有了新的特征:“HomeTeamRanksHigher”,从新进行决策树计算:
X_homehigher = dataset[[“HomeLastWin”, “VisitorLastWin”,“HomeTeamRanksHigher”]].values
clf = DecisionTreeClassifier(random_state=14)
scores = cross_val_score(clf, X_homehigher, y_true,scoring=‘accuracy’)
print(“Accuracy: {0:.1f}%”.format(np.mean(scores) * 100))

汇总代码,并且计算结果:

import pandas as pd
import numpy as np
from collections import defaultdict
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_scoredata_filename = r'保存路径\文件名.csv'
dataset = pd.read_csv(data_filename, parse_dates=[0])
dataset.columns = ["Date","Start","Visitor Team","VisitorPts", "Home Team", "HomePts","Score Type","OT?", "Attend.", "Notes"]
dataset["HomeWin"] = dataset["VisitorPts"] < dataset["HomePts"]
y_true = dataset["HomeWin"].valuesdataset["HomeLastWin"] = False
dataset["VisitorLastWin"] = False
won_last = defaultdict(int)
for index, row in dataset.iterrows():home_team = row["Home Team"] ##提取主队名visitor_team = row["Visitor Team"] ##提取客队名row["HomeLastWin"] = won_last[home_team] ##第n行的主队上一轮否赢球进行赋值,默认为0(False)row["VisitorLastWin"] = won_last[visitor_team] ##第n行的客队上一轮否赢球进行赋值,默认为0(False)dataset.ix[index] = row ##won_last[home_team] = row["HomeWin"]won_last[visitor_team] = not row["HomeWin"]clf = DecisionTreeClassifier(random_state=14)
X_previouswins = dataset[["HomeLastWin", "VisitorLastWin"]].values
scores = cross_val_score(clf, X_previouswins, y_true,scoring='accuracy')
print("Accuracy: {0:.1f}%".format(np.mean(scores) * 100))standings_filename =r'保存路径\文件名.csv'
standings = pd.read_csv(standings_filename)dataset["HomeTeamRanksHigher"] = 0
for index, row in dataset.iterrows():home_team = row["Home Team"]visitor_team = row["Visitor Team"]if home_team == "New Orleans Pelicans":home_team = "New Orleans Hornets"elif visitor_team == "New Orleans Pelicans":visitor_team = "New Orleans Hornets"home_rank = standings[standings["Team"]==home_team]["Rk"].values[0]visitor_rank = standings[standings["Team"]==visitor_team]["Rk"].values[0]row["HomeTeamRanksHigher"] = int(home_rank > visitor_rank)dataset.ix[index] = rowX_homehigher = dataset[["HomeLastWin","VisitorLastWin","HomeTeamRanksHigher"]].values
clf = DecisionTreeClassifier(random_state=14)
scores = cross_val_score(clf, X_homehigher, y_true,scoring='accuracy')
print("Accuracy: {0:.1f}%".format(np.mean(scores) * 100))

可以看到,从Accuracy: 57.8%,提升到了Accuracy: 60.3%。
但是球场上不存在强者恒强,弱者恒弱的情况,于是应该思考:是否还能提升准确率呢??
我们想到了,球队A打法,就是克制球队B,尽管他们总体胜率可能不如B,但是每一次相遇,A总能让B吃苦头。
于是我们增加另一列数据:AB相遇,上一次的胜者是谁?
首先创建一个 defaultdict(int)来存储并更新
last_match_winner = defaultdict(int)
dataset[“HomeTeamWonLast”] = 0

遍历所有的行,获取主客队名:
for index, row in dataset.iterrows():
home_team = row[“Home Team”]
visitor_team = row[“Visitor Team”]

创建一个交锋双方的元组,如果是主队获胜,那么dataset[“HomeTeamWonLast”] = 1且更新 defaultdict。
teams = tuple(sorted([home_team, visitor_team]))
row[“HomeTeamWonLast”] = 1 if last_match_winner[teams] ==row[“Home Team”] else 0
dataset.ix[index] = row

winner = row[“Home Team”] if row[“HomeWin”] else row[“Visitor Team”]
last_match_winner[teams] = winner

X_lastwinner = dataset[[“HomeTeamRanksHigher”, “HomeTeamWonLast”]].values
clf = DecisionTreeClassifier(random_state=14)
scores = cross_val_score(clf, X_lastwinner, y_true,scoring=‘accuracy’)
print(“Accuracy: {0:.1f}%”.format(np.mean(scores) * 100))

汇总代码,可以得到新的预测结果为:Accuracy: 60.6%。
又提高了0.3%。

下一文,开始讲随机森林。

参考文献:
1.https://pandas.pydata.org/pandas-docs/stable/reference/frame.html#indexing-iteration
2.https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#examples-using-sklearn-tree-decisiontreeclassifier

Python数据挖掘入门与实践 第三章 用决策树预测获胜球队(一)pandas的数据预处理与决策树(Decision tree)相关推荐

  1. 改写《python数据挖掘入门与实践》第九章Gutenberg书籍下载代码

    @数据挖掘 改写<python数据挖掘入门与实践>第九章Gutenberg书籍下载代码 可能是gutenberg网站改版的缘故,随书附带的getdata.py代码执行会报错. 个人将其进行 ...

  2. python 从入门到实践 第三章

    在第3章,你将学习如何在被称为列表的变量中存储信息集,以及如何通过遍历列表来操作 其中的信息 写注释 # 代码越长 标识好代码的重要性 越来越重要 要求习惯:在代码中编写清晰,简洁的注释 开始研究更复 ...

  3. Python数据挖掘入门与实践-第9章-古腾堡计划网站书籍资料下载

    由于python版本以及网站更新等原因,导致了书上的代码没有用了.因此自己试着修改了代码. 下面就来讲讲修改中遇到的主要问题 问题:网站URL变更 # 书上的代码 url_base = "h ...

  4. Python数据挖掘入门与实践-OneR分类算法

    Python数据挖掘入门与实践-OneR分类算法 OneR算法 OneR算法是根据已有的数据中,具有相同特征值的个体最可能属于哪个类别进行分类. 在本例中,只需选区Iris是个特征中分类效果最好的一个 ...

  5. Python编程:从入门到实践 第三章--函数

    Python编程:从入门到实践 第三章-函数 语法 就还是需要先记一下函数定义的语法: def Test(num):num = 12 如上,def func_name(factors): # code ...

  6. 数据挖掘入门读物《Python数据挖掘入门与实践》豆瓣评分[7.70]

    好书推荐.视频分享,公众号"读书ReadBook"与您一起进步 下载地址-- 1.点击阅读原文或者地址 https://ebooklist.mobi/2019/05/20/6465 ...

  7. Python数据挖掘入门与实践pdf

    下载地址:网盘下载 内容简介  · · · · · · 本书作为数据挖掘入门读物,介绍了数据挖掘的基础知识.基本工具和实践方法,通过循序渐进地讲解算法,带你轻松踏上数据挖掘之旅.本书采用理论与实践相结 ...

  8. Python数据挖掘入门与实践 彩图 pdf

    下载地址:网盘下载 内容简介  · · · · · · 本书作为数据挖掘入门读物,介绍了数据挖掘的基础知识.基本工具和实践方法,通过循序渐进地讲解算法,带你轻松踏上数据挖掘之旅.本书采用理论与实践相结 ...

  9. python_tweets.json (python数据挖掘入门与实践数据集下载)

    最近在看python数据挖掘入门与实践一书,书不错,有个不好的地方是,书上所用的数据集,有几个测试数据在网上非常不好找 下面几个资源是我自己整理出来的,上传到CSDN,有需要的朋友可以下载 leagu ...

最新文章

  1. 继承和多态 3.0 -- 菱形继承
  2. libevent+多线程的服务器模型
  3. 互动整合营销_营销成本日益升高,整合营销到底有多重要
  4. Android 7.1.1 锁屏界面启动流程
  5. dede中list标签php,dedecms标签中什么表示列表标签
  6. 简单控制器java,无法找到模板:创建一个简单的控制器和视图
  7. activity与service 使用Handler Messenger数据传递
  8. c语言形式参数若为b 4,2016年计算机二级c语言题库
  9. 2.PHP 扩展开始以及内核应用(1) --- PHP 变量在内核中的实现
  10. HBuilder X 报 Error: Unbalanced delimiter found in string 错误
  11. 基于74系列芯片的红绿灯设计
  12. 从10个经典工业设计案例,来看什么是工业设计
  13. Pytorch统计模型参数量和计算量
  14. 学生管理系统的设计与实现
  15. mysql怎么求时间差
  16. 搭建指标体系的底层逻辑
  17. python平均成绩计算异常处理_【Python 20】BMR计算器4.0(异常处理)
  18. 尤登弘—中小企业最佳赢利管理模式
  19. 【迅为iMX6Q】开发板 u-boot 2020.04 SD卡 启动
  20. 为什么我会关心“雪球嘉年华”活动

热门文章

  1. 淘集集打单软件那个好?那个打单软件能批量打单?
  2. Qt+Opencv实现本地视频读取及显示
  3. 什么是gulp?使用方法?
  4. 开源聊天机器人程序QRobot(QuickRobot)
  5. Web前端开发------第五周
  6. python爬取妹子图片1_【爬虫】直接上干货-爬取妹子图整站图片
  7. Midjourney以图生图的详细教程(含6种案例介绍)
  8. 人脸变身“门禁卡”!人脸识别门禁打造智能物业管理
  9. 阿里巴巴达摩院通义千问【附申请链接】阿里版ChatGPT
  10. 交换机直连电脑配置telnet