有点标题党的嫌疑,实际是介绍如何使用 R 绘制 heatmap 的文章。
今天无意间在Flowingdata看到一篇关于如何使用 R 来做 heatmap 的文章(请移步到这里)。虽然 heatmap 只是 R 中一个很普通的图形函数,但这个例子使用了2008-2009赛季 NBA 50个顶级球员数据做了一个极佳的演示,效果非常不错。对 R 大致了解的童鞋可以直接在 R console 上敲
?heatmap
直接查看帮助即可。
没有接触过 R 的童鞋继续围观,下面会仔细介绍如何使用 R 实现 NBA 50位顶级球员指标表现热图:
关于 heatmap,中文一般翻译为“热图”,其统计意义wiki上解释的很清楚:
A heat map is a graphical representation of data where the values taken by a variable in a two-dimensional map are represented as colors.Heat maps originated in 2D displays of the values in a data matrix. Larger values were represented by small dark gray or black squares (pixels) and smaller values by lighter squares.
下面这个图即是Flowingdata用一些 R 函数对2008-2009 赛季NBA 50名顶级球员指标做的一个热图(点击参看大图):

先解释一下数据:
这里共列举了50位球员,估计爱好篮球的童鞋对上图右边的每个名字都会耳熟能详。这些球员每个人会有19个指标,包括打了几场球(G)、上场几分钟(MIN)、得分(PTS)……这样就行成了一个50行×19列的矩阵。但问题是,数据有些多,需要使用一种比较好的办法来展示,So it comes, heatmap!
简单的说明:
比如从上面的热图上观察得分前3名(Wade、James、Bryant)PTS、FGM、FGA比较高,但Bryant的FTM、FTA和前两者就差一些;Wade在这三人中STL是佼佼者;而James的DRB和TRB又比其他两人好一些……
姚明的3PP(3 Points Percentage)这条数据很有意思,非常出色!仔细查了一下这个数值,居然是100%。仔细回想一下,似乎那个赛季姚明好像投过一个3分,并且中了,然后再也没有3p。这样本可真够小的!
最后是如何做这个热图(做了些许修改):
Step 0. Download R
R 官网:http://www.r-project.org,它是免费的。官网上面提供了Windows,Mac,Linux版本(或源代码)的R程序。
Step 1. Load the data
R 可以支持网络路径,使用读取csv文件的函数read.csv。
读取数据就这么简单:
read.csv("http://datasets.flowingdata.com/ppg2008.csv", sep=",")
Step 2. Sort data
按照球员得分,将球员从小到大排序:
nba <- nba[order(nba$PTS),]
当然也可以选择MIN,BLK,STL之类指标
Step 3. Prepare data
把行号换成行名(球员名称):
row.names(nba) <- nba$Name
去掉第一列行号:
nba <- nba[,2:20] # or nba <- nba[,-1]
Step 4. Prepare data, again
把 data frame 转化为我们需要的矩阵格式:
nba_matrix <- data.matrix(nba)
Step 5. Make a heatmap
# R 的默认还会在图的左边和上边绘制 dendrogram,使用Rowv=NA, Colv=NA去掉
heatmap(nba_matrix, Rowv=NA, Colv=NA, col=cm.colors(256), revC=FALSE, scale='column')
这样就得到了上面的那张热图。
Step 6. Color selection
或者想把热图中的颜色换一下:
heatmap(nba_matrix, Rowv=NA, Colv=NA, col=heat.colors(256), revC=FALSE, scale="column", margins=c(5,10))
延伸阅读:
来自于kerimcan和krees这些人的讨论:
http://sekhon.polisci.berkeley.edu/stats/html/heatmap.html
http://enotacoes.wordpress.com/2007/11/16/easy-guide-to-drawing-heat-maps-to-pdf-with-r-with-color-key/
补充:
早上起来发现 David Smith 同样更新了博客。唉,这厮嗅觉也忒灵敏!哈哈
本场比赛前7分钟火箭发挥还不错,最高取得了10分的领先(11-21),但受上一场力拼森林狼三个加时影响,火箭诸将体能逐渐不支,慢慢失去优势。虽然巴丁格整场替补发挥出色,无奈,随着阿里扎上篮不进,比分定格在了115-106。
相比热火发烫的53.6%投篮命中率,火箭发挥比较正常,48.7%。火箭唯一问题出现在了失误方面,8-15,如果火箭失误控制的好,也许结果可能是另外一个结果。
比赛过程中,杨毅提到(大致意思):由于没有超级球星,火箭必须比其他球队付出更多的努力才能获得胜利,也就是说其他球队会从容地为季后赛调整状态。火箭没有这个资本,为了常规赛的成绩,火箭进入疲劳期的时间要更早。要保证后面的球队成绩,要么莫雷尽最大能力交易,补充火箭;要么阿德尔曼通过更加合理细致的轮转,让每个核心球员得到充分休息。
问题来了:在不改变现有火箭球员结构的前提下,火箭的战术轮转体系中,球员的位置如何?
引子:
本场比赛火箭一共20个助攻,Brooks 和 Battier 分别助攻了最高的5个和4个。每次助攻都会涉及两位球员,那么本场比赛所有助攻结果综合在一起,即我们将助攻者和被助攻者之间的关系使用社会网络关系表现出来,会有一些有趣的现象:

注释:
箭头方向是助攻方向,比如最下面的是 Shane Battier 给 Chuck Hayes 的助攻。
整理几个重要的关键点来评论一下:
- Brooks 无疑是比赛的发起者,我们发现他的助攻几乎包括了中锋、前锋位置的所有人(但不包括阿里扎,好像我记得有个镜头阿里扎要球,Brooks 没有理会)。
- Battier 既是助攻的受益者,又是助攻的发起者。个人一直比较喜欢的球员,篮球智商非常高。
- Budinger 这场比赛发挥出色,同队友给予其的帮助分不开。我们看到很多个球员对其都有直接帮助。
- Andersen 从助攻网络关系角度看,属于一个策应型中锋,而且是由里向外策应的那类。从比赛中观察,似乎球风有些偏软(本赛季我第一次看直播比赛 ^_^)
- Ariza 接受的助攻并不多,只有 Battier 的一次,其他都是给别人的助攻,和 Brooks 一样,属于个人能力比较强,擅于自己创造得分机会的球员。
假如:
我是教练组成员,我提议(单从本场比赛结果看):
- Brooks、Battier、Ariza、Andersen 在火箭进攻体系中位置比较重要,轮转的时候尽量保证其中的两人或三人同时在场。
- Budinger 属于绝好的替补球员,但似乎不适合同 Battier、Hayes 同时在场。
- Lowry 在组织进攻方面能力欠佳,使用上须谨慎。
更新分割:
40场比赛助攻数据同时考虑,结果有些凌乱:

注:这个赛季火箭队有一些球员实际上并没有真正的进入轮转,比如”Tracy McGrady”,”Mike Harris”,”Jermaine Taylor”,”Pops Mensah-Bonsu”,”Brian Cook”。虽然有些球员(比如麦蒂)的确对球队的(被)助攻仍有帮助,但贡献非常有限。出于结果整洁性的考虑,上图已将这些球员因素剔除。
由于绘图算法使用的是 Force-based_algorithms,也就是说这种算法做出的图,边(edges)会尽可能的少。解释为,对球员关系的影响就是:
同其他球员关系比较多的球员将绘制的比较靠近中心,而关系较少的球员会绘制在相对靠外的位置。
重新观察火箭队助攻网络图,发现:
1月16日对热火比赛中,Kyle Lowry 和 Trevor Ariza 发挥的确出了问题,尤其是 Lowry 这点上。
如果我们求解这个网络中各个球员的 page rank 值,可以认为是每个球员同其他球员助攻的关键程度。
|
Name |
PageRank |
| 1 |
Aaron Brooks |
0.1690 |
| 2 |
Trevor Ariza |
0.1496 |
| 5 |
Luis Scola |
0.1334 |
| 3 |
Kyle Lowry |
0.1268 |
| 7 |
Shane Battier |
0.1099 |
| 8 |
Carl Landry |
0.0966 |
| 9 |
Chase Budinger |
0.0741 |
| 4 |
Chuck Hayes |
0.0724 |
| 6 |
David Andersen |
0.0681 |
Brooks、Ariza、Scola、Lowry、Battier 在助攻重要性角度上,占据球队的前五位。如何使用“田忌赛马”的策略制胜,则是教练组的问题。
让我欣慰的是 Hayes 的重要程度要比 Andersen 要好,单单从上一场比赛上看,Andersen 发挥的有些超常。
P.S. 维基百科上没有区别 “有向网络”和“无向网络”的 page rank ,上个表中的 page rank 值属于“无向网络”值,同上面的图略有区别(有向网络中,Lowry 的关键性仅比 Hayes 高,有些无奈)。
上次说到准备分析一下火箭的投篮点,今天补上一张球员投篮点和球队命中率的示例图:

注释:Hit Rate 部分,不同颜色的线条代表了第一二三四节的投篮命中率,也就是hat(beta)的值。 如果有人把图一帧一帧的看完,会发现:
- 火箭开局并不好,但在第一节后半段和第二节上半段发挥很好;其余时间发挥着实一般。
- 火箭攻击点大部分集中在两个区域:篮板前3英尺的水平线上和弧顶至禁区间区域。
是说,湖人成功将火箭进攻路线阻断?呵呵,比赛的时候我在写上面图的代码,没来得及看 ^_^
有意思的一个赛季,由于赛季之初 Artest 的到来,球迷们又开始 yy 松鼠姚的总冠军之路。不过可惜,随着 T. McGrady 的报废,基本上这赛季总决赛大门又一次提前关闭。紧接着球队的主力 PG(R. Alston)被换走,今天又签下James White,我就纳闷了,为啥和火箭有关系的人我都关注过呢。 松鼠姚至今天(2009.03.05)共 28 次两双,占出场次数的 48%,场均数据并不惊艳:
|
min |
FG |
FGA |
X3P |
X3PA |
FT |
FTA |
OREB |
DREB |
REB |
AST |
STL |
BLK |
TO |
PF |
EF |
PTS |
|
32.9 |
7.2 |
13.1 |
0.0 |
0.0 |
5.4 |
6.2 |
2.7 |
6.9 |
9.6 |
1.6 |
0.4 |
1.8 |
3.2 |
3.2 |
11.1 |
19.8 |
场均得分 PTS 为 19.8 分,场均篮板 REB 为 9.6 个。 离场均两双还有一点点距离,给个及格分好了。
顺便做了下对火箭球员分析,共使用了 273 个火箭球员的相关变量,得到的结论解释了我几条疑问:
指标我就不多说了,爱打篮球的筒子一般都知道 FG、AST、REB 这类乱七八糟的指标,要说明的是 1722 、532 这些数字是 ESPN 给 NBA 球员定义的编号,1722 就是 Y. Ming 了,其他的 532 为 T. McGrady,11 为 R. Alston,25 为 Artest ,1781 为 L. Scola ,3192 为 A. Brooks;而 1、0 则为方便记录胜负而设置的。
从图上不难找到火箭的关键球员,他们左右了每场比赛的胜负。对火箭成绩走向最关键的球员是 Y. Ming ,因为他在最根部,是决定下一个球员因素的前提(本赛季 T. McGrady 由于伤病困扰数据大幅下滑,不过从侧面说明 Y.Ming 已然是球队老大)。其他球员因素不必过多解释,数据显示结果唯一让我不满便是 S. Battier 的重要性,本来这次数据探索我就是朝着他去的,结果还是没有合适指标可以显示他的作用。再找时间做好了。
关于为什么 R. Alston 为什么会被换走,这里同样可以给大家一个清晰的解释:当 Yao 的 Field Goal 低于 5.5 时,同时 T. McGrady 的 AST 小于4.5 次时,R. Alston 的上场时间成为关键因素,不过抱歉的说,当他上场时间大于35.5 min 时,火箭会输!!估计莫雷应该用的是同样方法看到这一怪现象吧。那 R. Alston 在交易日截止之前被换走也就不难理解了。
阿德尔曼的普林斯顿体系是不是适合火箭。说实话,我也不熟。至今,我对经典的三角进攻都不知道如何开始。不过,火箭的 Team 数据(不包括20090305对爵士)可以说明一切。Exciting 的时刻来了:

- 如果火箭的得分(PTS)能够上到 102 分以上,那么这场比赛是拿定了。这种比赛个人认为应该是队员对教练战术执行彻底,进攻如行云流水,人挡杀人,见佛杀佛。这赛季以高于 102 的比分战胜的球队甚至包括马刺(103-84)、爵士(120-115) 等西部强队。
- 如果得分小于等于 102 分时,决定因素就转到防守篮板(DREB)上了。一般防守篮板小于31个时,输得概率比较高;不过即使防守篮板不济,当抢断大于10次时还是有希望得回胜利的。
- 得分小于 102,篮板大于 31 个,决定因素就变成了三分球试投(3PA)。只要投进三分球试投能够低于 19 个时,球队仍然可以以高概率赢得比赛(92%)。大家该冒出疑问了,为啥三分球试投数小了才能赢球,不是多了更好么。诚然从数字上看确实如此,但火箭三分多了,一般都是后卫在“浪投”,既不能对内线造成杀伤也不能迅速解决战斗。这也就是火箭从赛季之初一直在囤积后场的原因。只可惜,至今天,火箭的后场还是那么烂。
看看今天对爵士的比赛:火箭得分 94(没进攻),防守篮板 23(没防守) ,抢断为 8(没激情),你把这些数据按上图走一遍,是不是告诉你会返回 0。不输才怪!