06 案例 - 赌球神器

简介: 理论部分先告一段落,如果还有不清晰的地方可以选择留言或我私下沟通。今天起正式进入代码阶段,入门项目是赌球神器。一、建模步骤1、清洗数据集 。2、划分训练集和测试集:12个特征;1个目标 - 获胜队伍:主队、客队、平局;3、训练三种不同的分类器:Logistic Regression、Support Vector Machine、XGBoost 。

理论部分先告一段落,如果还有不清晰的地方可以选择留言或我私下沟通。今天起正式进入代码阶段,入门项目是赌球神器。

一、建模步骤

1、清洗数据集 。
2、划分训练集和测试集:12个特征;1个目标 - 获胜队伍:主队、客队、平局;
3、训练三种不同的分类器:Logistic Regression、Support Vector Machine、XGBoost 。
4、给定主队客队情况下,使用最佳分类器预测是哪支队伍获取胜利 。

----- 在做项目之前回答一个问题 ----

有很多人问我到底哪个分类器最好?

一个较为严谨的回答是:当你没有真正用数据跑出一个模型之前,你永远不知道哪个分类器的效果最好。

但事实上,个人感觉很多分类器预测出的准确率始终在75%~78%之间徘徊,可是一旦使用了XGBoost分类器进行分类,预测效果一下子可以达到80%以上。

所以如果实在想知道哪个模型更好,不负责任的回答是:
那你就用XGBoost吧,XGBoost不仅效果好,而且运算速度也比较快。至于为什么?请先观大略不求甚解,将来有机会再说。

二、数据来源

Kaggle每年都会举办 March Madness的预测竞赛
https://www.kaggle.com/c/march-machine-learning-mania-2017/kernels
在2014年世界杯的时候,Bing正确得预测了所有15场淘汰赛阶段比赛的结果。

获取到数据后要思考两个问题:
1、我们应该使用什么模型?
2、要预测哪支球队获胜,什么样的特征才能起到重要的作用?
这不仅是编程前需要考虑的问题,同时也是最后写报告时需要总结回报的内容。

三、编程
1、导入库

数据处理用到的库:《Python - 科学计算库》笔者在该文集对pandas、numpy等常用数据处理方法做了介绍。

XGBoost 安装请参考文集:《AI - 开发工具》中的《安装 xgboost 库
如果XGBoost 安装没有问题,那么import xgboost as xgb不会报错。

linear线性方法包中导入逻辑回归:
from sklearn.linear_model import LogisticRegression
ensemble集成方法包中导入随机森林:
from sklearn.ensemble import RandomForestClassifier
支撑向量分类器:
from sklearn.svm import SVC

逻辑回归(LogisticRegression)、随机森林(RandomForestClassifier)都是属于sklearn中的库,在安装Anaconda时就已经自动包含了,所以无需安装插件,直接导入即可。

%matplotlib inline 作用参考该文章:
01 matplotlib - 折线图、绘图属性、Web安全色、子图、保存画板

import warnings warnings.filterwarnings("ignore") 忽略一些警告

完整的头文件:

#数据处理
import pandas as pd
import numpy as np
#XGBoost 生成一个由弱分类器集成的强分类器,一般来说这个弱分类器是决策树
import xgboost as xgb
#Logistic Regression 其输出只有有限个可能的值,在目标变量为分类属性时可以使用。
from sklearn.linear_model import LogisticRegression
# 随机森林同样是一个集成算法,通过独特的抽样方式获得不同的子数据集,
# 通过这些子数据集来建立决策树模型,最终通过求平均的方式来提升结果的准确性,同时来控制过拟合。
from sklearn.ensemble import RandomForestClassifier
# 由一个分隔超平面定义的判别式学习器
from sklearn.svm import SVC
%matplotlib inline
import warnings
warnings.filterwarnings("ignore")
2、读取数据

《final_dataset.csv》文件里是样本集,如果需要请留邮箱,我单独发给大家。


img_25adf42e301281e8bc77103470168b17.png
final_dataset的部分特征值

data = pd.read_csv('./Datasets/final_dataset.csv') 读取数据,算法在如下文件中已介绍:
04 pandas DataFrame_创建、文件读取、编码
05 pandas DataFrame_删改查、索引器、读写文件

在处理特征前,首先要对数据的所有特征进行深入了解,比如查看数据描述:
HomeTeam:主队
AwayTeam:客队
FTR: (H: 主队胜 NH:不是主队胜)
HTGD:Home team goal difference(主队平均进球差)
ATGD:away team goal difference(客队平均进球差)
HTP:Home team points(主队平均每轮得分)
ATP:Away team points(客队平均每轮得分)
DiffFormPts:Diff in points(主队平均得分-客队平均得分)
DiffLP:Differnece in last years position(上一年度主客队排名差)

inplace参数的理解:
修改一个对象时:
inplace=True:不创建新的对象,直接对原始对象进行修改;
inplace=False:对数据进行修改,创建并返回新的对象承载其修改结果。

完整的代码:

#读取数据
data = pd.read_csv('./Datasets/final_dataset.csv')

#移除前三周比赛并移除多余特征
data = data[data.MW > 3]

data.drop(['Unnamed: 0','HomeTeam', 'AwayTeam', 'Date', 'MW', 'HTFormPtsStr', 'ATFormPtsStr', 'FTHG', 'FTAG',
           'HTGS', 'ATGS', 'HTGC', 'ATGC','HomeTeamLP', 'AwayTeamLP','DiffPts','HTFormPts','ATFormPts',
           'HM4','HM5','AM4','AM5','HTLossStreak5','ATLossStreak5','HTWinStreak5','ATWinStreak5',
           'HTWinStreak3','HTLossStreak3','ATWinStreak3','ATLossStreak3'],1, inplace=True)

data.head()

输出 - 读取数据的结果:


img_ff3c514328c734386e485bf357bd68c9.png
读取的数据
3、探索性分析

上述直接读取的数据机器能不能认识?或者说算法能不能直接使用这些数据跑出模型来?显然不行。我们还要做一步探索性分析的工作。

探索性分析首先要考虑的是:1、我们的研究是否有价值,2、能够从数据中分析出哪些信息。

a、总比赛场数

n_matches = data.shape[0]

b、特征数量,需要用总个数减去目标变量个数。

n_features = data.shape[1] - 1

c、主队获胜场数

n_homewins = len(data[data.FTR == 'H'])

d、计算主队胜率

win_rate = (float(n_homewins) / (n_matches)) * 100

打印结果

print("比赛总场数: {}".format(n_matches))
print("特征总数: %d" %n_features)
print("主场球队获胜场数: {}".format(n_homewins))
print("主队胜率: {:.2f}%".format(win_rate))
比赛总场数: 5600
特征总数: 12
主场球队获胜场数: 2603
主队胜率: 46.48%
4、数据可视化

增加一个头文件:
from pandas.tools.plotting import scatter_matrix

scatter matrix会画出某一特征和其余特征之间所建立的二维图像

scatter_matrix(data[['HTGD','ATGD','HTP','ATP','DiffFormPts','DiffLP']], figsize=(10,10))

从图片可以发现,对角线上的图片是直方图,这是该特征和自己所画出的图,描述了其分布状况

散点图表示了一个特征和另一个特征之间的关系。这种关系可以用相关系数来表达。

img_fc6fc04579e34b4bce41f7c3784dd892.png
scatter matrix
5、数据预处理

1、将数据划分为特征集和目标集

X_all = data.drop(['FTR'],1)
y_all = data['FTR']

2、标准化数据

from sklearn.preprocessing import scale
cols = [['HTGD','ATGD','HTP','ATP','DiffLP']]
for col in cols:
    X_all[col] = scale(X_all[col])

3、将数据转换为str型

X_all.HM1 = X_all.HM1.astype('str')
X_all.HM2 = X_all.HM2.astype('str')
X_all.HM3 = X_all.HM3.astype('str')
X_all.AM1 = X_all.AM1.astype('str')
X_all.AM2 = X_all.AM2.astype('str')
X_all.AM3 = X_all.AM3.astype('str')

4、我们希望使用连续性变量,所以移除分类型变量

def preprocess_features(X):
    ''' 将比赛数据中的分类变量转化为哑变量 '''
    
    # 初始化新的输出数据集
    output = pd.DataFrame(index = X.index)

    # 检索数据的每个特征
    for col, col_data in X.iteritems():

        # 如果数据是分类型变量,将他们转化为哑变量
        if col_data.dtype == object:
            col_data = pd.get_dummies(col_data, prefix = col)
                    
        # 收集修正过的数据
        output = output.join(col_data)
    
    return output

X_all = preprocess_features(X_all)

运行结果:

print("Processed feature columns ({} total features):\n{}"
.format(len(X_all.columns), list(X_all.columns)))

输出结果:处理完后剩下24个特征

Processed feature columns (24 total features):
['HTP', 'ATP', 'HM1_D', 'HM1_L', 'HM1_W', 'HM2_D', 'HM2_L', 'HM2_W', 'HM3_D', 'HM3_L', 'HM3_W', 'AM1_D', 'AM1_L', 'AM1_W', 'AM2_D', 'AM2_L', 'AM2_W', 'AM3_D', 'AM3_L', 'AM3_W', 'HTGD', 'ATGD', 'DiffFormPts', 'DiffLP']

5、打印前五行数据

print("\nFeature values:")
X_all.head()
img_cc78163cbf6f553a5bff13211ca33722.png
打印前五行数据

from sklearn.model_selection import train_test_split

6、训练集、测试集划分
stratify参数是在数据不均衡情况下,保证训练集和测试集正例负例之间的比例保持不变

X_train, X_test, y_train, y_test = train_test_split(X_all, y_all, 
                                                    test_size = 50,
                                                    random_state = 2,
                                                    stratify = y_all)
6、训练模型
from time import time 
from sklearn.metrics import f1_score

def train_classifier(clf, X_train, y_train):
    ''' 使用训练集数据拟合分类器 '''
    
    # 开启计时、训练分类器、停止计时
    start = time()
    clf.fit(X_train, y_train)
    end = time()
    print("Trained model in {:.4f} seconds".format(end - start))

    
def predict_labels(clf, features, target):
    ''' 基于分类器进行预测,并给出F1得分 '''
    
    start = time()
    y_pred = clf.predict(features)
    end = time()
    
    print("Made predictions in {:.4f} seconds.".format(end - start))
    
    return f1_score(target, y_pred, pos_label='H'), sum(target == y_pred) / float(len(y_pred))


def train_predict(clf, X_train, y_train, X_test, y_test):
    ''' 训练和预测的模型整合 '''
    
    # 声明分类器和训练集规模
    print("Training a {} using a training set size of {}. . .".format(clf.__class__.__name__, len(X_train)))
    
    # 训练分类器
    train_classifier(clf, X_train, y_train)
    
    # 分别打印训练集和分类集的预测结果
    f1, acc = predict_labels(clf, X_train, y_train)
    print(f1, acc)
    print("F1 score and accuracy score for training set: {:.4f} , {:.4f}.".format(f1 , acc))
    
    f1, acc = predict_labels(clf, X_test, y_test)
    print("F1 score and accuracy score for test set: {:.4f} , {:.4f}.".format(f1 , acc))
# 初始化三个模型
clf_A = LogisticRegression(random_state = 42)
clf_B = SVC(random_state = 912, kernel='rbf')
clf_C = xgb.XGBClassifier(seed = 82)

train_predict(clf_A, X_train, y_train, X_test, y_test)
print('')
train_predict(clf_B, X_train, y_train, X_test, y_test)
print('')
train_predict(clf_C, X_train, y_train, X_test, y_test)
print('')
img_c999e1b91c0984d22447236d445420f7.png

显然,XGBoost看上去是我们的最佳模型,其F1和准确度是三个模型当中最高的。

XGBoost的超参设置:
img_e21082848ce7561c74ea4a7b9711c4ac.jpe
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import make_scorer


# 设置想要调整的参数
parameters = { 'learning_rate' : [0.1, 0.2],
               'n_estimators' : [40, 50],
               'max_depth': [3],
               'min_child_weight': [3],
               'gamma':[0.4],
               'subsample' : [0.8],
               'colsample_bytree' : [0.8],
               'scale_pos_weight' : [1],
               'reg_alpha':[1e-5]
             }  

# 初始化分类器
clf = xgb.XGBClassifier(seed=2)

# 得到F1得分
f1_scorer = make_scorer(f1_score,pos_label='H')

# 使用网格搜索寻找最优模型
grid_obj = GridSearchCV(clf,
                        scoring=f1_scorer,
                        param_grid=parameters,
                        cv=5)

# 将数据带入模型进行训练
grid_obj = grid_obj.fit(X_train,y_train)

# Get the estimator获取最优超参
clf = grid_obj.best_estimator_
print(clf)

# 给出最优f1得分和准确率
f1, acc = predict_labels(clf, X_train, y_train)
print("F1 score and accuracy score for training set: {:.4f} , {:.4f}.".format(f1 , acc))
    
f1, acc = predict_labels(clf, X_test, y_test)
print("F1 score and accuracy score for test set: {:.4f} , {:.4f}.".format(f1 , acc))
img_1f9a813c701e870830b8319b307aed10.png
相关文章
|
Web App开发 Ubuntu 安全
【已解决】ubuntu 16.04安装最新版本google chrome出错, 旧版本chrome浏览器安装流程
【已解决】ubuntu 16.04安装最新版本google chrome出错, 旧版本chrome浏览器安装流程
2531 2
|
Linux 开发者 Docker
Docker 引擎启动、停止、重启操作|学习笔记
快速学习 Docker 引擎启动、停止、重启操作
微信文件传输助手文件夹在哪?一起来找找
  微信文件传输助手是微信电脑版与手机微信之间相互传输图片等文件的好工具,但很多童鞋都找不到微信文件传输助手文件夹在哪,就让我们一起找找吧   1.先说说手机微信文件传输助手文件夹在哪吧   文件夹路径为/Tencent/MicroMsg/Download/     2.
4649 0
|
SQL Java
如何使用阿里云短信服务实现登录页面,手机验证码登录?1
如何使用阿里云短信服务实现登录页面,手机验证码登录?
1196 0
|
缓存 网络安全 开发工具
全面掌握 Git 和 Gitee:从安装到上传的完整指南
本文档介绍了如何安装和配置Git,以及如何与Gitee进行连接。首先从官网下载Git并安装,接着配置用户名和邮箱,生成SSH密钥并将其添加到Gitee账户,完成无密码登录的设置。文档还提供了基本的命令使用指南,包括文件操作、Git命令和gitee代码上传流程,最后讲解了提交信息的规范格式和回滚操作的方法。
1586 1
|
人工智能 搜索推荐 机器人
AppFlow无代码轻松搭建模型Agent
使用钉钉,现在每个人都能轻松创建自己的AI助手。通过结合各种插件,如天气、机票查询和地图,你可以定制个性化的工作助手。利用AppFlow,即使没有编程经验也能搭建AI Agent。步骤包括:1) 在钉钉开放平台创建应用,获取凭证;2) 在钉钉卡片平台创建AI卡片实例;3) 在AppFlow配置连接流,添加所需插件;4) 创建钉钉机器人,设置HTTP消息接收并关联AppFlow的Webhook。完成这些步骤后,你就可以在钉钉群中与你的AI助手互动了。
52442 13
|
缓存 网络协议 Windows
一分钟解决Github连接慢或者无法连接,亲测有效!
一分钟解决Github连接慢或者无法连接,亲测有效!
6349 0
一分钟解决Github连接慢或者无法连接,亲测有效!
|
机器学习/深度学习 人工智能 文字识别
多模态产品在智能文档处理应用的展望------以TextIn模型为例
**第十四届VALSE大会在重庆举行,合合信息智能创新事业部研发总监常扬分享了“文档解析与向量化技术”,重点介绍TextIn技术。TextIn解决现有文档解析挑战,如表格解析难题,建立包含数据基建、算法、应用和接入四层架构的文档解析Pipeline。关键技术包括版面分析和文档树引擎,能准确识别文档结构和阅读顺序。TextIn在C-MTEB榜单排名第一,显示其在文本向量化领域的优势,适用于长文档处理和多行业应用,有望推动AI技术进步和产业升级。**
552 1
|
关系型数据库 MySQL Linux
Mysql 5.7以上版本安装后的初始密码
~/.msyql_secret 废话少说一句话系列: CentOS系统用yum安装MySQL的朋友,请使用 grep "temporary password" /var/log/mysqld.log 命令,返回结果最后引号后面的字符串就是root的默认密码。
5201 0
|
小程序 程序员 数据安全/隐私保护
微信小程序 Spdier - OfferShow 反编译逆向(一)
文章目录 微信小程序 Spdier - OfferShow 反编译逆向(一) 前言 一、任务说明 1.尝试反编译分析出js_code参数的生成方式,用来获取token 2.将小程序搜索出来的数据保存至本地excel 二、微信小程序抓包 - 分析 三、wxapkg反编译 - 分析 1.在夜神模拟器获取微信程序员的包 1.1 获取wxapkg的地址 1.2 删除wxapkg文件重新生成 1.3 复制w
2033 0
微信小程序 Spdier - OfferShow 反编译逆向(一)

热门文章

最新文章

下一篇
开通oss服务