1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > [译]剖析勇士如何成为新赛季夺冠热门:基于Spark GraphFrames的金州勇士传球网络分析...

[译]剖析勇士如何成为新赛季夺冠热门:基于Spark GraphFrames的金州勇士传球网络分析...

时间:2019-02-23 01:06:12

相关推荐

[译]剖析勇士如何成为新赛季夺冠热门:基于Spark GraphFrames的金州勇士传球网络分析...

databricks 最近发布了 GraphFrames,这是一个用 DataFrames 封装图处理过程的Spark插件。

我评估了网络分析并且利用丰富的的数据对金州勇士的传球网络进行可视化。

金州勇士的传球网络

传接球

联盟 MVP Stephen Curry 接到了大多数的传球,而团队中的 MVP Draymond Green则发动了最多的传球。

我们已经看到大多数的进攻是由 Curry 和 Green 的相互传球开始的。

图片来自 GIPHY

入度 inDegree

出度 outDegree

标签传递算法 (Label Propagation Algorithm)

标签传递是一种在图网络中寻找队伍的算法。

这种算法在没有已有标签的情况下,依然可以很好地将球员分为前锋和后卫。

网页排名算法 (Pagerank Algorithm)

在一个网络中 PageRank 可以检测节点的重要程度。

毫无疑问,Stephen Curry、 Draymond Green 和 Klay Thompson 是Top3.

这个算法可以发现 Shaun Livingston 和 Andre Iguodala 在金州勇士的传球中扮演着关键角色。

示例

library(networkD3)setwd('/Users/yuki/Documents/code_for_blog/gsw_passing_network')passes <- read.csv("passes.csv")groups <- read.csv("groups.csv")size <- read.csv("size.csv")passes$source <- as.numeric(as.factor(passes$PLAYER))-1passes$target <- as.numeric(as.factor(passes$PASS_TO))-1passes$PASS <- passes$PASS/50groups$nodeid <- groups$namegroups$name <- as.numeric(as.factor(groups$name))-1groups$group <- as.numeric(as.factor(groups$label))-1nodes <- merge(groups,size[-1],by="id")nodes$pagerank <- nodes$pagerank^2*100forceNetwork(Links = passes,Nodes = nodes,Source = "source",fontFamily = "Arial",colourScale = JS("d3.scale.category10()"),Target = "target",Value = "PASS",NodeID = "nodeid",Nodesize = "pagerank",linkDistance = 350,Group = "group", opacity = 0.8,fontSize = 16,zoom = TRUE,opacityNoHover = TRUE)

节点大小: pagerank值

节点颜色: 队伍

连线宽度: 传球次数(接球和发球)

工作流

调用API

我使用playerdashptpass的端点并且将同队所有球员数据保存到本地的 JSON 文件中。

数据来自 -16赛季的传球记录。

# 金州勇士球员 IDsplayerids = [75,78,2738,202691,101106,2760,2571,203949,203546,203110,39,203105,2733,1626172,203084]# 调用 API 并且存储结果为 JSONfor playerid in playerids:os.system('curl "/stats/playerdashptpass?''DateFrom=&''DateTo=&''GameSegment=&''LastNGames=0&''LeagueID=00&''Location=&''Month=0&''OpponentTeamID=0&''Outcome=&''PerMode=Totals&''Period=0&''PlayerID={playerid}&''Season=-16&''SeasonSegment=&''SeasonType=Regular+Season&''TeamID=0&''VsConference=&''VsDivision=" > {playerid}.json'.format(playerid=playerid))

JSON -> Panda’s DataFrame

接着,我结合每个JSON文件到一个 DataFrame 中。

raw = pd.DataFrame()for playerid in playerids:with open("{playerid}.json".format(playerid=playerid)) as json_file:parsed = json.load(json_file)['resultSets'][0]raw = raw.append(pd.DataFrame(parsed['rowSet'], columns=parsed['headers']))raw = raw.rename(columns={'PLAYER_NAME_LAST_FIRST': 'PLAYER'})raw['id'] = raw['PLAYER'].str.replace(', ', '')

准备节点和边

你需要为 Spark 中的 GraphFrames 准备一个像点+边的特殊的数据格式。顶点表示了图中的节点和运动员ID,边表示节点之间的关系。你可以添加一些附加特征比如权重,但是你没法找出在稍后的分析中可以更好表现的特征。一个可行的办法是尝试穷举所有的可能方案。(也欢迎大家留言讨论)

# 生成初始节点pandas_vertices = raw[['PLAYER', 'id']].drop_duplicates()pandas_vertices.columns = ['name', 'id']# 生成初始边pandas_edges = pd.DataFrame()for passer in raw['id'].drop_duplicates():for receiver in raw[(raw['PASS_TO'].isin(raw['PLAYER'])) &(raw['id'] == passer)]['PASS_TO'].drop_duplicates():pandas_edges = pandas_edges.append(pd.DataFrame({'passer': passer, 'receiver': receiver.replace( ', ', '')}, index=range(int(raw[(raw['id'] == passer) &(raw['PASS_TO'] == receiver)]['PASS'].values))))pandas_edges.columns = ['src', 'dst']

图分析

vertices = sqlContext.createDataFrame(pandas_vertices)edges = sqlContext.createDataFrame(pandas_edges)# Analysis partg = GraphFrame(vertices, edges)print("vertices")g.vertices.show()print("edges")g.edges.show()print("inDegrees")g.inDegrees.sort('inDegree', ascending=False).show()print("outDegrees")g.outDegrees.sort('outDegree', ascending=False).show()print("degrees")g.degrees.sort('degree', ascending=False).show()print("labelPropagation")g.labelPropagation(maxIter=5).show()print("pageRank")g.pageRank(resetProbability=0.15, tol=0.01).vertices.sort('pagerank', ascending=False).show()

网络可视化

当你运行 GitHub 仓库中的代码 gsw_passing_network.py,你需要检查在工作目录下有passes.csvgroups.csvsize.csv这三个文件。我用R中的networkD3包来实现酷炫的可交互的 D3 制图。

library(networkD3)setwd('/Users/yuki/Documents/code_for_blog/gsw_passing_network')passes <- read.csv("passes.csv")groups <- read.csv("groups.csv")size <- read.csv("size.csv")passes$source <- as.numeric(as.factor(passes$PLAYER))-1passes$target <- as.numeric(as.factor(passes$PASS_TO))-1passes$PASS <- passes$PASS/50groups$nodeid <- groups$namegroups$name <- as.numeric(as.factor(groups$name))-1groups$group <- as.numeric(as.factor(groups$label))-1nodes <- merge(groups,size[-1],by="id")nodes$pagerank <- nodes$pagerank^2*100forceNetwork(Links = passes,Nodes = nodes,Source = "source",fontFamily = "Arial",colourScale = JS("d3.scale.category10()"),Target = "target",Value = "PASS",NodeID = "nodeid",Nodesize = "pagerank",linkDistance = 350,Group = "group", opacity = 0.8,fontSize = 16,zoom = TRUE,opacityNoHover = TRUE)

参考资料

Introducing GraphFrames

项目 GitHub 源码

Weaver: A High-Performance, Transactional Graph Database Based on Refinable Timestamps

本文已获得原作者:YUKI KATOH 授权HarryZhu翻译

英文原文地址:http://opiateforthemass.es/ar...

作为分享主义者(sharism),本人所有互联网发布的图文均遵从CC版权,转载请保留作者信息并注明作者 Harry Zhu 的 FinanceR专栏:/blog...,如果涉及源代码请注明GitHub地址:/harryprince。微信号: harryzhustudio

商业使用请联系作者。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。