kaggle:谁是NBA最佳防守球员?(二)

浏览: 2518

image.png

接着前几天发的关于kaggle中NBA球员投篮数据探索性数据分析和可视化分析之后,小编本打算对这13万的投篮数据跑几个机器学习模型预测一下投篮的,可是电脑内存不给力,试了几次之后便作罢了。还打算第一次试一下kaggle上被传的神乎其技的大杀器xgboost的呢。机器学习的模型都写好了,有图为证:

image.png

于是便转而去做特征构造,毕竟知乎和Quora上都认为特征工程作为kaggle的核心技能。前几天NBA颁奖大会本赛季的最佳防守球员是勇士队的追梦.格林,于是便从防守端的角度出发,利用特征工程手段来分析2014-15赛季哪些球员才算NBA里拥有顶级防守水平的球员。

不了解特征工程的同学看这篇文章就够了:

https://www.zhihu.com/question/29316149

小编这里就不分条条框框了,直接上代码来的舒适。

读入数据,进行特征观察与变量筛选:

nbashots<-read.csv("D:/Rdata/kaggle_nbashots/shot_logs.csv")
str(nbashots)
attach(nbashots)
#剔除触球时间小于0的记录
nbashots <- nbashots[TOUCH_TIME > 0,]
#因与FGM变量含义一致,删除Shot Result变量
nbashots <- nbashots[,-14]

数据集中有两个关于时间的变量,一个是比赛时间变量GAME_CLOCK,另一个是投篮时间变量SHOT_CLOCK,二者格式并不统一,我们可以使用gsub函数进行处理:

player_name <- as.character(player_name)
player_name <- factor(player_name)
#处理比赛时间变量
GAME_CLOCK <- as.character(GAME_CLOCK)
GAME_CLOCK <- gsub(":", ".", GAME_CLOCK)
#与投篮时间变量类型一致
GAME_CLOCK <- as.numeric(GAME_CLOCK)

下面就进入到特征工程的表演时间了。我们首先定义比赛中所谓的关键时刻,将投篮时间在第四节最后一分钟以内且双方最终分差在五分以内的投篮定义为关键投篮。且看特征构造过程:

nbashots$Crucial_time <- "No"
nbashots$Crucial_time[nbashots$GAME_CLOCK <= 1 &
nbashots$PERIOD >= 4 & abs(nbashots$FINAL_MARGIN) <= 5] <- "Yes"
nbashots$Crucial_time <- factor(nbashots$Crucial_time)

再通过运球次数和投篮距离来定义相应的投篮类型。我们将投篮类型分为六种:接球就投、空切、突破上篮、单打、长时间单打和定点三分。

nbashots$shot_type[nbashots$DRIBBLES <= 1 & 
     nbashots$SHOT_DIST > 4] <- 'Catch and Shoot'
nbashots$shot_type[nbashots$DRIBBLES <= 1 &
     nbashots$SHOT_DIST <= 4] <- 'Cut'
nbashots$shot_type[nbashots$DRIBBLES > 1 &
     nbashots$SHOT_DIST  <= 4] <- 'Drive'
nbashots$shot_type[nbashots$DRIBBLES > 4] <- 'ISO'
nbashots$shot_type[nbashots$DRIBBLES > 20] <- 'Long ISO'
nbashots$shot_type[nbashots$DRIBBLES <=1 &
      nbashots$PTS_TYPE == 3] <- 'Spot Up Three'
nbashots$shot_type <- factor(nbashots$shot_type)

看一下统计结果:

summary(nbashots$shot_type)
Catch and Shoot    Cut   Drive    ISO  Long ISO Spot Up Three
  34134   17025   4665   18109    507   28090
  NA's
  22181

长时间ISO的球霸毕竟还是少的哈。

根据防守人距投篮人距离来定义投篮质量。将投篮质量分为open(空位)wide open(大空位)tightly contested(无死角盯防)contested(全面盯防到位)四种:

nbashots$shot_quality <- 'Open'
nbashots$shot_quality[nbashots$CLOSE_DEF_DIST <= 2]
<- 'Tightly Contested'
nbashots$shot_quality[nbashots$CLOSE_DEF_DIST <= 3.5] <- 'Contested'
nbashots$shot_quality[nbashots$CLOSE_DEF_DIST > 6] <- 'Wide Open'
nbashots$shot_quality <- factor(nbashots$shot_quality)

看一下统计结果:

summary(nbashots$shot_quality)
Contested      Open Wide Open
   58965     44404     21342

看来坊间传说的在NBA里任何时间你拿到球都有一个七尺大汉张牙舞爪的站在你身前的说法不是虚的啊。

下面为了定义一名NBA球员的防守有哪些指标构成,我们需要通过变量之间的关系构造被防守人投篮命中率(OppFG)、被防守人每回合得分(OppPPP)、与投篮人距离(OppDist)、每名防守人防守的投篮次数(ShotsCont)、防守投篮时与篮筐的平均距离(RimDist)以及每名球员作为离投篮人最近的防守投篮次数(ShotsNear),在构造这些防守变量前,需要创建一些空的向量来存储这些变量内容。数据集中包括473名防守球员,我们利用rep函数如下:

OppFG <- rep(1, 473)
OppPPP <- rep(1, 473)
OppDist <- rep(1, 473)
ShotsCont <- rep(1, 473)
RimDist <- rep(1, 473)
ShotsNear <- rep(1, 473)

FGM <- nbashots$FGM
PTS <- nbashots$PTS
CLOSE_DEF_DIST <- nbashots$CLOSE_DEF_DIST
SHOT_DIST <- nbashots$SHOT_DIST
CLOSEST_DEFENDER <- nbashots$CLOSEST_DEFENDER

for (i in 1:473) {
 OppFG[i] = sum(FGM[CLOSEST_DEFENDER == DefenderList[i]])
 /length(FGM[CLOSEST_DEFENDER == DefenderList[i]])
 OppPPP[i] = sum(PTS[CLOSEST_DEFENDER == DefenderList[i]])
 /length(FGM[CLOSEST_DEFENDER == DefenderList[i]])
 OppDist[i] = sum(CLOSE_DEF_DIST[CLOSEST_DEFENDER ==
 DefenderList[i]])/length(FGM[CLOSEST_DEFENDER == DefenderList[i]])
 ShotsCont[i] = length(FGM[CLOSEST_DEFENDER == DefenderList[i]
 & CLOSE_DEF_DIST <= 3.5])
 RimDist[i] = sum(SHOT_DIST[CLOSEST_DEFENDER == DefenderList[i]])
 /length(FGM[CLOSEST_DEFENDER == DefenderList[i]])
 ShotsNear[i] = length(FGM[CLOSEST_DEFENDER == DefenderList[i]])
}

创建球员防守能力指标的数据框nba_def并进行统计:

nba_def <- data.frame(DefenderList, OppFG, OppPPP, 
OppDist, ShotsCont, RimDist, ShotsNear)
summary(nba_def)
      DefenderList     OppFG            OppPPP          OppDist         ShotsCont    
Acy, Quincy   :  1   Min.   :0.0000   Min.   :0.0000   Min.   : 1.000   Min.   :  0.0  
Adams, Jordan :  1   1st Qu.:0.4233   1st Qu.:0.9348   1st Qu.: 3.888   1st Qu.: 42.0  
Adams, Steven :  1   Median :0.4524   Median :1.0026   Median : 4.165   Median :112.0  
Adrien, Jeff  :  1   Mean   :0.4579   Mean   :1.0194   Mean   : 4.187   Mean   :124.7  
Afflalo, Arron:  1   3rd Qu.:0.4821   3rd Qu.:1.0749   3rd Qu.: 4.454   3rd Qu.:187.0  
Ajinca, Alexis:  1   Max.   :1.0000   Max.   :2.6667   Max.   :18.900   Max.   :423.0  
(Other)       :467                                                                    
   RimDist        ShotsNear    
Min.   : 4.20   Min.   :  1.0  
1st Qu.:11.99   1st Qu.: 96.0  
Median :14.84   Median :253.0  
Mean   :14.09   Mean   :263.7  
3rd Qu.:16.30   3rd Qu.:406.0  
Max.   :23.25   Max.   :791.0  

简单用几个指标看下2014-15赛季哪些球员的防守表现较为突出。先通过限制对手命中率和限制对手每回合得分数来看一下,ggplot2作图展示:

ggplot(data = nba_def[ShotsCont >= 150 & OppFG <= .41,],
      aes(OppFG, OppPPP)) +
 geom_point(colour = "black", size = 2) +
 geom_point(aes(colour = DefenderList)) +
 geom_smooth(method = "lm", se = FALSE) +
 geom_text(aes(label = DefenderList), size = 3, vjust = 0,
 check_overlap = TRUE) + guides(colour = FALSE) +
 labs(x = "Opponent Field Goal Percentage",
 y = "Opponent Points per Possesion")

在防守对方投篮150次以上并且限制对方命中率在41%以下的优秀防守球员中,对手的命中率和每回合得分数表现如下图:

image.png

一些以防守凶悍著称的球员包括今年首轮给登哥造成麻烦的罗伯森、爵士的戈伯特、勇士的博格特、德拉蒙德.格林等球员。当然图中也有库里和蒙塔这类防守一般的球员,通过限制对手命中率和每回合得分数的线性关系可以看出来。

再来看一个与投篮人距离和每回合得分数之间的关系图:

ggplot(EliteDef, aes(OppDist, OppPPP)) + 
 geom_point(colour = "black", size = 2) +
 geom_point(aes(colour = DefList)) +
 geom_smooth(method = "lm", se = FALSE) +
 geom_text(aes(label = DefenderList), size = 3, vjust = 0,
 check_overlap = TRUE) +
 guides(colour = FALSE) +
 labs(x = "Average Distance of Contest",
 y = "Opponent Points per Possession")

image.png

由图中也可以看出,二者也呈现出较强的线性关系。NBA里一些长手长脚的球员即使你离他4英尺远以上,他的长臂干扰仍然可以使得你的命中率极低。比如雷霆的安德烈.罗伯森、鹈鹕的戴维斯等。

总体写的比较乱,仅分析了一点内容,对于构造的防守指标里面的其他没用到的指标也大有文章可做。这里小编仅展示一些特征工程的方法,毕竟这才是kaggle的核心。部分参考了kaggle用户Stefanlangen的结果,并对部分代码做了优化。kaggle给的每个数据集都有太多可供挖掘的部分,有兴趣的同学可以深入探索下啦。最后放一张我麦的照片吧。

image.png



推荐 0
本文由 鲁伟 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册