查看原文
其他

NBA球员薪资分析——基于随机森林算法(一)

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:宋   骁

文字编辑:钱梦璇

技术总编:张   邯
前言
作为世界上最成功的商业体育联盟之一,NBA(美国职业篮球联赛)有一套非常成熟又复杂的薪资体系。这个体系不仅能保证球员的工资完全公开透明,还能保证比赛的精彩性,同时促进了联盟的健康发展。NBA球员的薪资不仅和球员个人能力挂钩,还和整个制度和球队本身战术体系有关。
NBA为了保证联盟的实力平衡设置了严格的工资帽制度。“工资帽”是一个球队给球员提供工资总额,超过了就要支付高额的奢侈税。这使得不同球队在交易的时候也要慎重考虑球员的身价,如果一笔交易涉及的球员身价不配平,球队可能也会因此而超出工资帽。
此外,NBA球员的合同还分为保障合同和非保障性合同。前者指如果球员受伤不能上场,工资照付,后者指球队根据上场场次支付薪资,球员可能随时被裁,工资数额也往往较少。相当多的球员在“转正”或“被裁”的过程中经历工资的大变动。
从机器学习的角度讲,因为以上原因的存在,预测球员的薪资是非常困难的。但幸好NBA对所有球员进行了详尽到近乎“变态”的技术统计,任何球队在考量一个球员的时候,都基于大量的技术统计结果做出决策。“真实命中率”这类指标的引入也确实更客观地衡量一个球员的真实得分效率。
本文是一个使用机器学习方法预测球员薪资的尝试。由于球员伤病等原因,一些球员的薪资变动非常大,因此我们选用2016-2017赛季的技术统计去预测下一个赛季球员的薪资,这样能够保证球员的竞技状态改变较少。
本文使用的两个数据均来自数据科学平台Kaggle,公开数据源在此:
https://www.kaggle.com/koki25ando/salary
https://www.kaggle.com/drgilermo/nba-players-stats
其中,变量字段说明如下:


目录

    • 1  数据清理

      • 1.1  变量相关系数

    • 2  变量转换

    • 3  建模

      • 3.1  交叉验证

      • 3.2  变量重要性统计



数据清洗


import pandas as pd import numpy as npimport matplotlib.pyplot as pltimport seaborn as snssalarydf = pd.read_csv("./data/NBA_season1718_salary.csv")seasons = pd.read_csv("./data/Seasons_Stats.csv")
用上一个赛季的技术统计数据预测下赛季的薪酬,存在同一个球员在一个赛季辗转不同球队的情况,这时同一个球员在数据中就会留下多条记录。而在seasons表中,这名球员就会多出一行记录他在多支球队中的汇总表现,这时他的Tm列就被记为TOT。如下所示:
salarydf[salarydf['Player'] == 'Troy Williams']

一个赛季辗转两只球队的Troy Williams出现了单独的TOT行:

seasons[(seasons['Player'] == 'Troy Williams') & (seasons['Year'] == 2017)]

因此,如果一个球员辗转多支球队则取他薪资的平均数。这里使用groupby函数计算每一名球员2017-2018赛季的薪资平均数。

salary_mean = salarydf.groupby(salarydf['Player']).mean() # 以球员为分组进行平均salary_mean = pd.DataFrame(salary_mean)salary_mean['Player'] = salary_mean.index # 新建球员姓名列salary_mean.reset_index(drop=True,inplace =True) # 去除 indexsalary_mean = salary_mean[['Player','season17_18']] # 选择两列salary_mean.rename(columns = {'season17_18':'salary17_18'},inplace = True) # 重命名salary_mean['salary17_18'] = salary_mean['salary17_18'] / 1000000 # 将薪资单位化为百万salary_mean.head()

对于技术统计数据,采取相同的措施。这里我们将TOT行单独拿出来并删除在单个队伍中的数据统计(TOT记录了汇总值),因为没有TOT行的不属于单赛季辗转过多支球队的球员。

在建模之前我们将会删除模型中不需要的特征,比如说球员姓名等等。同时将汇总数据除以出场次数计算得到场均数据。

seasons = seasons[seasons['Year'] == 2017] # 只保留16-17赛季的技术统计seasons_tot = seasons[seasons['Tm'] == 'TOT'] # 得到辗转多队的数据行seasons.drop_duplicates(['Player'], keep= False ,inplace=True) # 删除单个队的数据行together = pd.concat([seasons, seasons_tot])together = together[['Player','Pos','Age','G','PER', 'MP','PTS','AST','TRB','TOV','BLK','STL']]
c = ['MPG','PPG','APG','RPG','TOPG','BPG','SPG']w = ['MP','PTS','AST','TRB','TOV','BLK','STL']
for i,s in zip(c,w): # 把所有汇总数据除以出场次数得到场均值 together[i] = together[s] / together['G']
together.drop(w,axis=1,inplace = True)together.drop(['G'],axis=1,inplace = True)together.loc[together['Pos'] == 'PF-C','Pos'] = 'PF' # 重编码stats_salary = pd.merge(together, salary_mean) # 数据合并stats_salary.head()

OK!上面就是我们得到的将球员的数据统计和薪资合并以后的数据了。Player对应的是球员姓名,salary17_18对应的是球员2017-2018赛季的薪资(单位:百万美元)。我们后面所要做的是用数据统计特征预测salary17_18这一列。我们可以先画图探查一下各变量之间的线性相关关系。



变量相关系数


%matplotlib inline %config InlineBackend.figure_format = 'svg' #Jupyter Notebook魔术命令,设置图片输出格式为svg
import seaborn as snssns.set_style('white')plt.rcParams['font.sans-serif']=['SimHei'] # 图片中文输出plt.rcParams['axes.unicode_minus']=Falseheat_salary = stats_salary[['salary17_18','Pos','MPG','PPG','APG', 'RPG','TOPG','BPG','SPG','Age','PER']]dfData = heat_salary.corr() #相关矩阵sns.heatmap(dfData).set( xlabel='变量', ylabel='变量')

相关性系数在0-1之间浮动变化。图中格子的颜色越浅,说明变量的相关性越强。我们可以看出和薪资变量相关性较大的是场均得分、出场时间和效率值等变量,而较为不重要的因素是年龄和场均封盖。这可能是因为年龄较大的球员可能直接选择退役或被球队裁掉,而不是继续待在球队中拿底薪。值得注意的是,场均失误数和场均得分、场均助攻相关性较强,这说明参与进攻越多的球员同时也会导致更多的失误。

以上我们将NBA球员的技术统计和薪资数据做了一些清理和分析,明天我们将使用随机森林算法对薪资进行预测。敬请期待~





对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
高亮输出之唐诗作者

湖北省各市疫情数据爬取

古代诗人总去的这些地方你一定要知道!

DataFrame数组常用方法(二)

ftools命令——畅游大数据时代的加速器

卫健委的“糊涂账”

Pandas中数据的排序与切片

DataFrame数组常用方法

巧用局部宏扩展函数dir

过了14天潜伏期真的没事了?

Pandas基本数据类型介绍

NumPy数组基本介绍

“个性化”sortobs命令,教你实现排序自由

携手战疫,我们在行动

恭贺新春,平安顺遂|各省疫情关注度地图

过年观影指南(二)

过年观影指南(一)

egenmore隐藏功能——进制转换

关于我们



微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。

此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。
投稿邮箱:statatraining@163.com
投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存