科比老大职业生涯数据预测(基于随机森林模型)

news2024/10/6 3:15:46

1.实验背景

     
科比·布莱恩特,作为NBA历史上最伟大的篮球运动员之一,他的职业生涯充满了无数精彩瞬间。

科比于1996年以13顺位的选秀身份进入联盟,一生都效力于洛杉矶湖人队。于2016年宣布退役,职业生涯获奖无数,5次NBA总冠军,2次FMVP,1次MVP,4次AMVP,18次全明星,生涯总得分超33000分,未来的名人堂球员等。在今年的1月26日,科比乘坐的私人飞机不幸失事,科比和二女儿吉安娜永远地离开了我们,这对无数球迷是一个莫大的打击。虽然科比离开了我们,但曼巴精神将激励着一代又一代的年轻人去追逐自己的梦想。

本实验旨在通过分析科比职业生涯的比赛数据,深入挖掘他的投篮技巧和比赛表现,从而更好地理解他的篮球艺术和竞技水平。同时,本实验也将帮助机器学习学习者掌握数据分析的基本技能,包括数据预处理特征工程模型建立参数调整等。


2.实验目的


1. 掌握Numpy, Pandas, Matplotlib, Seaborn等常用数据分析库的用法。
2. 学会数据预处理的方法,包括数据清洗、数据合并、数据转换等。
3. 学会特征工程,包括特征提取、特征选择、特征转换等。
4. 学会建立随机森林模型,并进行模型参数调整,选择最优参数。
5. 学会对测试数据进行预测,并保存模型结果。

3.数据集说明

该数据集收录了自96赛季~2016赛季,科比整个职业生涯的比赛记录,共有30697条数据。每一条数据都是一次出手记录,其中包括动作类型,投篮类型,投射距离,投射位置,是否命中等25个特征。在该数据集中我们将以是否命中篮筐为标签值来进行分析,带有标签值的数据共25697条。我们将以这25697条数据作为训练数据进行建模,来对不带标签的5000条数据进行预测。


4.实验步骤


4.1数据读取与描述性统计

读取科比职业生涯比赛数据集,对数据进行简单的描述性统计分析,了解数据的分布情况。

#导入此数据分析任务中要使用的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns;sns.set()
%matplotlib inline
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import KFold
raw = pd.read_csv('kobe_data.csv')
raw.head()

让我们来看看数据集长啥样:

由上述结果可以看出,该数据集共有25个特征,其中24个特征都是完整的,只有shot_made_flag这个特征是存在缺失值的。

所以接下来我们会将数据集切分为两部分,含有shot_made_flag的数据集作为训练集,缺失shot_made_flag的数据集作为测试集。

通过对训练集进行建模,来预测测试集上的shot_made_flag值。

4.2单变量分析

(1)查看科比出手类型的分布,绘制出手类型的次数统计图。

#查看科比出手类型的分布
plt.figure(figsize = (10,6))
raw['combined_shot_type'].value_counts().plot(kind = 'bar')
plt.xlabel('出手类型');plt.ylabel('出手次数');plt.title('科比职业生涯不同出手类型的次数统计')

由上图可知,科比最喜欢的进攻方式就是跳投+肘击,紧接着是上篮。

(2)查看科比两分球,三分球的出手数,绘制出手数的柱状图。

#查看科比两分球,三分球的出手数
plt.figure(figsize = (8,6))
raw['shot_type'].value_counts().plot(kind = 'bar')
plt.xlabel('远投还是中距离');plt.ylabel('出手次数');plt.title('科比职业生涯远投和中距离的出手数')
plt.xticks(rotation = 0)

由上图可以看出,科比的进攻手段主要以中距离进攻为主,像我们比较熟悉的急停跳投,翻身跳投,干拔跳投等。


(3)查看科比出手距离的分布,绘制出手距离的直方图。

#查看科比出手距离的分布
plt.figure(figsize = (8,6))
raw['shot_distance'].hist(bins = 100)
plt.xlabel('出手距离');plt.ylabel('出手次数');plt.title('科比出手距离的分布')


(4)绘制出手距离的箱线图

这里简单介绍一下箱线图

箱线图(Box Plot),又称为盒须图盒式图箱形图,是一种用于展示一组数据分布情况的统计图表。它由五个数值点组成,分别是:最小值(下边缘)(Min)、下四分位数(Q1)、中位数、上四分位数(Q3)和最大值(上边缘)(Max)。箱线图能够反映数据的分散情况,展示数据集的对称性、分布的集中趋势以及离散程度,同时还能检测出异常值。

箱线图的组成部分如下:

中位数(Med):数据集的中心位置,将数据分为上下两部分。
箱体(Box):箱子由下四分位数(Q1)和上四分位数(Q3)之间的距离构成,表示数据的中间50%的分布范围。箱体的高度(即Q3与Q1之间的距离)被称为四分位距(IQR)。
须(Whisker):从箱体的两侧延伸出来,通常延伸到数据集的最小值和最大值,但在处理异常值时,可能会延伸到小于Q1-1.5IQR和大于Q3+1.5IQR的最近数据点。
异常值(Outlier):在须之外的数据点,通常用圆点表示。这些值被认为是异常或离群的。


箱线图的特点和用途:

直观展示数据分布:通过箱线图,我们可以直观地看到数据的中位数、上下四分位数以及异常值,从而对数据的整体分布有一个快速的了解。
比较多个数据集:通过绘制多个数据集的箱线图,可以方便地比较不同数据集的分布特点。
检测异常值:箱线图能够清晰地展示出数据中的异常值,有助于数据清洗和异常检测。

#绘制出手距离的箱型图
plt.figure(figsize = (6,4))
sns.boxplot(data = raw,y = 'shot_distance')
plt.xlabel('出手距离');plt.ylabel('出手次数');plt.title('科比出手距离的分布')

由上图可以看出科比在篮下的出手最多,大约有6000次,大约75%的出手为2分球,25%的三分球。

(5)可视化科比的出手区域,按照不同的标准划分的出手区域

#可视化科比的出手区域,按照不同的标准划分的出手区域
import matplotlib.cm as cm
plt.figure(figsize  = (20,10))

def scatter_plot_by_category(feat):
    alpha = 0.1
    gs = raw.groupby(feat)
    cs = cm.rainbow(np.linspace(0,1,len(gs)))
    for g,c in zip(gs,cs):
        plt.scatter(g[1].loc_x,g[1].loc_y,color = c,alpha = alpha)
#shot_zone_area出手区域,左侧,右侧,中场,后场等
scatter_plot_by_category(raw['shot_zone_area'])
plt.title('shot_zone_area')

#shot_zone_basic另一种划分出手区域的方式,中线,禁区,油漆区,左侧底角,右侧底角等
plt.subplot(1,3,2)
scatter_plot_by_category(raw['shot_zone_basic'])
plt.title('shot_zone_basic')

#shot_zone_range出手区域的距离,小于8英尺,8-16英尺,16-24英尺,24英尺以上等
#三分球(22英尺以上)
plt.subplot(1,3,3)
scatter_plot_by_category(raw['shot_zone_range'])
plt.title('shot_zone_range')

4.3双变量分析

(1)查看科比的出手命中率,绘制命中率的柱状图。

#查看科比的出手命中率
plt.figure(figsize = (6,4))
kobe['shot_made_flag'].value_counts(normalize = True).plot(kind = 'bar')
plt.xlabel('命中情况');plt.ylabel('命中个数');plt.title('科比的出手命中率')

该样本只是整个数据集中的部分样本,不能反映出其职业生涯的真实命中率。 可以看出科比的出手命中率大约为44%,还是挺高的命中率。

(2)观察不同出手类型与命中率之间的关系,绘制条形图。

#观察不同出手类型与命中率之间的关系

sns.barplot(data = kobe,x = 'combined_shot_type',y = 'shot_made_flag')

由上图可知,命中率从高往低依次为:扣篮-擦板-上篮-勾手-跳投-补篮

(3)观察两分球与三分球的命中率

#观察两分球与三分球的命中率

sns.barplot(data = kobe,x = 'shot_type',y = 'shot_made_flag')

kobe.groupby('shot_type')['shot_made_flag'].value_counts(normalize = True)

上述结果可以看出科比的两分球命中率为47.7%,三分球的命中率为32.9%。

(4)观察出手距离与命中率之间的关系

#观察出手距离与命中率之间的关系
sns.scatterplot(data = kobe, x = 'shot_distance',y = 'shot_made_flag' )

sns.violinplot(data = kobe, y = 'shot_distance',x = 'shot_made_flag' )

由上图可以看出,出手距离越远,命中率越低,出手超过43英尺的都没有命中。

4.4数据预处理和特征工程


删除对最终预测结果无影响的id特征。
创建一个新的特征time_remaining,用于替代minutes_remaining和seconds_remaining,删除这两个特征。
将season数据处理为更简单易懂的格式。
删除lat,lon特征,因为它们与loc_x,loc_y表达的含义相同。
删除action_type特征,因为它与combined_shot_type表达的含义相近。
保留一个shot_zone_area特征,因为shot_zone_area,shot_zone_basic,shot_zone_range表达的含义相同。
删除team_name和game_date特征,因为它们对最终的预测结果没有影响。
保留opponent特征,因为matchup和opponent表达的是相同的意思。

#删除对最终预测结果无影响的id特征
drop_ids = ['game_event_id','game_id','team_id','shot_id']
for feature in drop_ids:
    raw = raw.drop(feature,axis = 1)
#创建一个新的特征time_remaining,用于替代minutes_remaining和seconds_remaining
raw['time_remaining'] = raw['minutes_remaining']*60 + raw['seconds_remaining']
#删除minutes_remaining和seconds_remaining特征
raw = raw.drop(['minutes_remaining','seconds_remaining'],axis = 1)
raw['season'].unique()
#将season数据处理为更简单易懂的格式
raw['season'] = raw['season'].apply(lambda x:int(x.split('-')[1]))
raw['season'].unique()
#lat,lon,loc_x,loc_y表达的是相同的含义,删除lat,lon特征
raw = raw.drop(['lat','lon'],axis = 1)
#action_type和combined_shot_type表达的含义相近,删除action_type
raw = raw.drop(['action_type'],axis = 1)

#shot_zone_area,shot_zone_basic,shot_zone_range表达的也是相同的含义,保留一个就行
raw = raw.drop(['shot_zone_basic','shot_zone_range'],axis = 1)

#team_name和game_date对最终的预测结果也没什么影响,删除这两个特征
raw = raw.drop(['team_name','game_date'],axis = 1)

#matchup和opponent表达的是相同的意思,保留opponent就行
raw = raw.drop('matchup',axis = 1)
#查看当前数据集的信息
raw.info()

       

4.5划分训练集和测试集

将带有标签的数据作为训练集,不带标签的数据作为测试集。

#划分训练集测试集
train_data = raw[pd.notnull(raw['shot_made_flag'])]
test_data = raw[pd.isnull(raw['shot_made_flag'])]

print('训练集的大小:',train_data.shape)
print('测试集的大小:',test_data.shape)

                                       

由于该测试集没有标签,所以我们需要通过交叉验证的方式将训练集分为训练样本和验证样本,用验证集来评估模型的好坏。

最终选取最好的模型,对测试样本进行预测。

4.6建立随机森林模型并进行调参

在这里先简单介绍一下随机森林模型:

随机森林(Random Forest)是一种基于决策树的集成机器学习算法,它通过在训练过程中引入随机性来提高预测性能,并且对过拟合具有很好的鲁棒性。随机森林由多个决策树组成,每个决策树都是在一个随机子集上进行训练的。这些决策树共同构成了一个“森林”,用于对新数据进行预测。

随机森林模型的训练过程如下:

①随机抽样:从原始数据集中进行有放回的随机抽样,得到多个样本集。
②决策树训练:对于每个样本集,训练一个决策树模型。在训练过程中,每个决策树节点在选择分裂特征时,只考虑一个随机子集的所有特征。
③聚合预测:对于新的数据点,将所有决策树的预测结果进行汇总。对于分类问题,通常采用多数投票法;对于回归问题,通常取所有树预测值的平均值。

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
import time

#初始化一个随机森林模型
RFC = RandomForestClassifier()

#使用网格搜索gridsearchcv寻找最佳的模型参数
param_grid = {'n_estimators':[40,80,120,160,200],
             'max_depth':[3,4,5,6,7,8,9,10],
             'min_samples_split':[3,4,5,6,7]}
grid = GridSearchCV(RFC,param_grid = param_grid,cv = 5,verbose = 2,n_jobs = -1)
t1 = time.time()
grid.fit(train_features,train_labels)
t2 = time.time()
print('模型的训练时间{}'.format(t2 - t1))


初始化一个随机森林模型。
使用网格搜索gridsearchcv寻找最佳的模型参数。
训练模型并找出最佳的模型参数。

5.实验总结

本实验通过分析科比·布莱恩特职业生涯的比赛数据,深入挖掘他的投篮技巧和比赛表现,帮助我们地理解他的篮球艺术和竞技水平。同时,本实验也帮助机器学习入门者掌握数据分析的基本技能,包括数据预处理、特征工程、模型建立和参数调整等。

What can I say

manba out!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1894549.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

暑假学习DevEco Studio第2天

学习目标: 掌握页面跳转 学习内容: 跳转页面 创建页面: 在“project”窗口。打开“entry>src>main>ets”,右击“pages”,选择“New>ArkTS File”,命名“Second”,点击回车键。 在页面的路由&#xff0…

8.ApplicationContext常见实现

ClassPathXmlApplicationContext 基于classpath下xml格式的配置文件来创建 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-i…

c++类模板及应用

文章目录 为什么要有函数模板一般实现举例类模板举例 继承中类模板的使用特殊情况 友元函数模板类和静态成员类模板实践 为什么要有函数模板 项目需求: 实现多个函数用来返回两个数的最大值&#xff0c;要求能支持char类型、int类型、double 一般实现举例 类模板举例 继承中类…

MySQL之备份与恢复(四)

备份与恢复 存储引擎和一致性 3.复制 从备库中备份最大的好处是可以不干扰主库&#xff0c;避免在主库上增加额外的负载。这是一个建立备库的好理由&#xff0c;即使不需要用它做负载均衡或高可用。如果钱是个问题&#xff0c;也可以把备份用的备库用于其他用户&#xff0c;…

Linux_进程池

目录 1、进程池基本逻辑 2、实现进程池框架 3、文件描述符的继承 4、分配任务给进程池 5、让进程池执行任务 6、回收子进程 7、进程池总结 结语 前言&#xff1a; 在Linux下&#xff0c;进程池表示把多个子进程用数据结构的方式进行统一管理&#xff0c;在任何时候…

代码随想录——无重叠区间(Leetcode435)

题目链接 贪心 排序 class Solution {public int eraseOverlapIntervals(int[][] intervals) {int res 0;if(intervals.length 1 || intervals.length 0){return res;}// 按左边界排序Arrays.sort(intervals, new Comparator<int[]>() {public int compare(int[] …

面试突击指南:Java基础面试题3

1.介绍下进程和线程的关系 进程:一个独立的正在执行的程序。 线程:一个进程的最基本的执行单位,执行路径。 多进程:在操作系统中,同时运行多个程序。 多进程的好处:可以充分利用CPU,提高CPU的使用率。 多线程:在同一个进程(应用程序)中同时执行多个线程。 多线程…

学习率调度器简明教程

学习率是神经网络训练中最重要的超参数之一&#xff0c;影响学习过程的速度和有效性。学习率过高会导致模型在最小值附近震荡&#xff0c;而学习率过低会导致训练过程非常缓慢甚至停滞。本文直观地介绍了学习率调度程序&#xff0c;它是用于在训练期间调整学习率的技术。 NSDT工…

解决SeaTunnel 2.3.4版本写入S3文件报错问题

在使用Apache SeaTunnel时&#xff0c;我遇到了一个写入S3文件的报错问题。通过深入调试和分析&#xff0c;找到了问题所在&#xff0c;并提出了相应的解决方案。 本文将详细介绍报错情况、参考资料、解决思路以及后续研究方向&#xff0c;希望对大家有帮助&#xff01; 一、…

江门雅图仕职业技术学校领导一行莅临泰迪智能科技参观调研

7月2日&#xff0c;江门雅图仕职业技术学校总校长肖胜阳、校长许昌、办公室主任任志娟等莅临广东泰迪智能科技股份有限公司产教融合实训中心参观调研。泰迪智能科技董事长张良均、副总经理施兴、产品中心总监周东平、校企合作经理吴桂锋进行热情接待&#xff0c;双方就学校专业…

Python用于处理 DNS 查询库之Dnspython 使用详解

概要 Dnspython 是一个开源的 Python 库,专门用于处理 DNS 查询。它被设计为既简单易用又功能强大,可以满足从简单到复杂的各种 DNS 相关需求。无论是进行基础的 DNS 查询还是进行高级的 DNS 服务器管理,dnspython 都能提供相应的功能。 这个库支持包括 A、AAAA、MX、TXT …

汉光联创HGLM2200N黑白激光多功能一体机加粉及常见问题处理

基本参数&#xff1a; 机器型号&#xff1a;HGLM2200N 产品名称&#xff1a;A4黑白激光多功能一体机 基础功能&#xff1a;打印、扫描、复印 打印速度&#xff1a;22页/分钟 纸张输入容量&#xff1a;150-249页 单面支持纸张尺寸&#xff1a;A4、A5、A6 产品尺寸&#x…

拓展欧几里得和裴蜀定理

裴蜀定理&#xff08;或贝祖定理&#xff09;说明了对任何整数a、b和它们的最大公约数d&#xff0c;关于未知数x和y的线性不定方程&#xff08;称为裴蜀等式&#xff09;&#xff1a;若a,b是整数,且gcd(a,b)d&#xff0c;那么对于任意的整数x,y,axby都一定是d的倍数&#xff0c…

pytorch中的contiguous()

官方文档&#xff1a;https://pytorch.org/docs/stable/generated/torch.Tensor.contiguous.html 其描述contiguous为&#xff1a; Returns a contiguous in memory tensor containing the same data as self tensor. If self tensor is already in the specified memory forma…

音乐发行平台无加密开源源码

适用于唱片公司&#xff0c;用于接收物料&#xff0c;下载物料功能&#xff1a;个人或机构认证&#xff0c;上传专辑和歌曲&#xff0c;版税结算环境要求php7.4Nginx 1、导入数据库 2、/inc/conn.php里填写数据库密码等后台路径/admin&#xff08;可自行修改任意入口名称&…

Java中子类继承和方法重写_java重写父类方法参数变了怎么改

public(非私有)private私有()构造方法不能继承不能继承成员变量能继承能继承成员方法能继承不能继承 1.也不能继承父类的有参构造方法,具体看构造函数继承特点 2.私有的成员变量相当于从父类拷贝一份拿过来用的,不能直接用,需要get/set方法 继承特点 继承中 成员变量访问特点:如…

重参数化技巧

Q&#xff1a;标准正态分布 P&#xff1a;预期的分布&#xff08;假设符合正态分布&#xff09; 学习与 - 手推 Diffusion Model (DDPM) 1/3 &#xff1a;数学原理推导_哔哩哔哩_bilibili

【test】小爱同学通过esp32控制电脑开关

文章目录 一、环境准备二、开关机原理数据传输框架 三、环境搭建1.巴法云平台设置2.米家设置3.windows网络唤醒设置4.搭建esp32开发环境并部署&#xff08;1&#xff09;新建项目&#xff08;2&#xff09;导入esp32库&#xff08;3&#xff09; 添加库&#xff08;4&#xff0…

透过 Go 语言探索 Linux 网络通信的本质

大家好&#xff0c;我是码农先森。 前言 各种编程语言百花齐放、百家争鸣&#xff0c;但是 “万变不离其中”。对于网络通信而言&#xff0c;每一种编程语言的实现方式都不一样&#xff1b;但其实&#xff0c;调用的底层逻辑都是一样的。linux 系统底层向上提供了统一的 Sock…

君子签区块链+AI,驱动组织实现高效合同管理、精准风险控制

在传统合同签署的过程中&#xff0c;企业、组织、机构都面临着合同签署与管理的诸多问题和挑战&#xff1a;合同种类繁多、数量庞大导致起草效率低下&#xff1b;管理流程繁琐、权限分散使得审批周期冗长且效率低下&#xff1b;合同签订版本难以精准复核&#xff0c;风险防控更…