用决策树预测获胜球队

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/buside/article/details/86132518

3.1 加载数据集

这里用到的数据集是NBA 2015-2016赛季所有场次的历史数据,数据集可以从http://www.basketball-reference.com/leagues/NBA_2016_games.html上下载,整理好的数据集放到网盘:https://pan.baidu.com/s/1jn09FumgOnBIoXxAYIbCPg

import pandas as pd
from collections import defaultdict
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
#设置列完整显示
pd.set_option('display.max_rows', None, 'display.max_columns', None,'expand_frame_repr',False)
dataset = pd.read_csv(r"E:\NBA15-16 dataset\basketball.csv",parse_dates=['Date'])
#设置列标题
dataset.columns = ["Date", "Start (ET)", "Visitor Team", "VisitorPts", "Home Team", "HomePts", "OT?", "Score Type", "Attend.", "Notes"]


3.1.1 提取新特征

确定类别值,这里我们用1表示主场队获胜,用0表示客场队获胜。

# -*- coding: UTF-8
import pandas as pd
from collections import defaultdict
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
pd.set_option('display.max_rows', None, 'display.max_columns', None,'expand_frame_repr',False)
dataset = pd.read_csv(r"E:\NBA15-16 dataset\basketball.csv",parse_dates=['Date'])
dataset.columns = ["Date", "Start (ET)", "Visitor Team", "VisitorPts", "Home Team", "HomePts", "OT?", "Score Type", "Attend.", "Notes"]
standings = pd.read_csv(r"E:\NBA15-16 dataset\standings.csv")
# 主场获胜的球队
dataset["HomeWin"] = dataset["VisitorPts"] < dataset["HomePts"]
y_true = dataset["HomeWin"].values

won_last = defaultdict(int)

for index, row in dataset.iterrows():
    home_team = row["Home Team"]
    visitor_team = row["Visitor Team"]

    # 更新每行,添加"HomeLastWin"和"VisitorLastWin"
    dataset.at[index, "HomeLastWin"]=won_last[home_team]
    dataset.at[index, "VisitorLastWin"] = won_last[visitor_team]
    # 用当前行的比赛结果更新两支球队上场比赛的情况,作为下一次更新使用
    won_last[home_team] = int(row["HomeWin"])
    won_last[visitor_team] = 1-int(row["HomeWin"])

print(dataset.iloc[:5])

得到前5行数据

 Date Start (ET)          Visitor Team          VisitorPts              Home Team  HomePts        OT? Score Type  Attend. Notes  HomeWin  HomeLastWin  VisitorLastWin
0 2015-10-27    8:00 pm       Detroit Pistons         106          Atlanta Hawks       94  Box Score        NaN    19187   NaN    False          0.0             0.0
1 2015-10-27    8:00 pm   Cleveland Cavaliers          95          Chicago Bulls       97  Box Score        NaN    21957   NaN     True          0.0             0.0
2 2015-10-27   10:30 pm  New Orleans Pelicans          95  Golden State Warriors      111  Box Score        NaN    19596   NaN     True          0.0             0.0
3 2015-10-28    7:30 pm    Philadelphia 76ers          95         Boston Celtics      112  Box Score        NaN    18624   NaN     True          0.0             0.0
4 2015-10-28    7:30 pm         Chicago Bulls         115          Brooklyn Nets      100  Box Score        NaN    17732   NaN    False          0.0             1.0

3.2 决策树

创建决策树的算法有多种,大都通过迭代生成一棵树,它们从根节点开始,选取最佳特征,用于第一个决策,到达下一个节点,选择下一个最佳特征,以此类推。当发现无法从增加树的层级中获取更多信息时,算法启动退出机制。

3.2.1 决策树中的参数

除了设定退出准则外,也可以创建一颗完整的树,再对其进行修剪,去掉对整个过程没有提供太多信息的节点,这个过程叫作剪枝。

scikit-learn库实现的决策树算法给出了退出方法,使用如下两个选项:

(1)min_samples_split:指定创建一个新节点至少需要的个体量。

(2)min_samples_leaf:指定为了保留节点,每个节点至少应该包含的个体数量。

第一个参数控制着节点的创建,第二个参数决定决策节点能否被保留。

决策树的另一个参数是创建决策的标准,常用的有以下两个:

(1)基尼不纯度:用于衡量决策节点错误预测新个体类别的比例。

(2)信息增益:用信息论中的熵来表示决策节点提供多少信息。

3.2.2 使用决策树

# -*- coding: UTF-8
import numpy as np
import pandas as pd
from collections import defaultdict
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
pd.set_option('display.max_rows', None, 'display.max_columns', None,'expand_frame_repr',False)
dataset = pd.read_csv(r"E:\NBA15-16 dataset\basketball.csv",parse_dates=['Date'])
dataset.columns = ["Date", "Start (ET)", "Visitor Team", "VisitorPts", "Home Team", "HomePts", "OT?", "Score Type", "Attend.", "Notes"]
standings = pd.read_csv(r"E:\NBA15-16 dataset\standings.csv")
# 主场获胜的球队
dataset["HomeWin"] = dataset["VisitorPts"] < dataset["HomePts"]
y_true = dataset["HomeWin"].values

won_last = defaultdict(int)

for index, row in dataset.iterrows():
    home_team = row["Home Team"]
    visitor_team = row["Visitor Team"]

    # 更新每行,添加"HomeLastWin"和"VisitorLastWin"
    dataset.at[index, "HomeLastWin"]=won_last[home_team]
    dataset.at[index, "VisitorLastWin"] = won_last[visitor_team]
    # 用当前行的比赛结果更新两支球队上场比赛的情况,作为下一次更新使用
    won_last[home_team] = int(row["HomeWin"])
    won_last[visitor_team] = 1-int(row["HomeWin"])

# print(dataset.iloc[:5])
clf = DecisionTreeClassifier(random_state=14)
X_previouswins = dataset[["HomeLastWin","VisitorLastWin"]].values
# 参数cv为交叉验证生成器,默认参数为5
scores = cross_val_score(clf,X_previouswins,y_true,scoring="accuracy",cv=5)
print(np.mean(scores)*100)

结果为59.42%。通过增加新特征,可以提高预测的准确率。

3.3 随机森林

一颗决策树可以学到很复杂的规则。然而可能导致过拟合的问题--学到的规则只适用于训练集。解决方法之一就是调整决策树算法,限制它学到的规则数量。例如,把决策树的深度限制在三层,只让它学习从全局角度拆分数据集的最佳规则,不让它学习适用面很窄的特定规则,这些规则会将数据集进一步拆分为更加细致的群组。使用这种折中方案得到的决策树泛化能力强,但整体表现稍弱。为弥补上述方法的不足,我们可以创建多颗决策树,用它们分别进行预测,再根据少数服从多数的原则从多个预测结果中选择最终预测结果。这正是随机森林的工作原理。

3.3.1 随机森林算法的参数

scikit-learn库中的RandomForestClassifier是对随机森林算法的实现,提供了一系列参数。由于使用了DecisionTreeClassifier的大量实例,所以它量的很多参数是一致的,如决策标准(基尼不纯度/信息增益)、max_features和min_samples_split.还引入了一些新的参数:

(1)n_estimators:用来指定创建决策树的数量。该值越高,所花时间越长,正确率(可能)也越高。

(2)oob_score:如果设置为真,测试时将不使用训练模型时用过的数据。

(3)n_jobs:采用并行计算方法训练决策树时所用到的内核数量。

猜你喜欢

转载自blog.csdn.net/buside/article/details/86132518
今日推荐