GraphGists

引言

每年,NBA 季后赛都会吸引全球数十亿观众和大量美元。博彩公司有自己的秘密算法来计算每场比赛的赔率。一支获胜记录良好的球队当然有更大的获胜机会。但对于历史战绩好坏参半的球队呢?我不是赌徒,但我对这些算法很感兴趣。

问题

通常要确定两支球队之间的胜率,你可以查看它们的历史交锋记录:总胜场和总负场;但如果这两支球队以前从未交锋过,或者更可能的是,最近几年从未交锋过,尤其是在NBA总决赛中,一支来自东部,另一支来自西部?一种比较方法是计算它们的胜率:(总胜场)/(总比赛场数)。然而,考虑到每支球队大多(或有时完全)只与来自本赛区的球队交手,胜率可能不太具有可比性。

解决方案

利用图数据库中的路径概念,不仅可以轻松计算传统统计数据,还可以引入新方法,通过季后赛链条将任意两支球队联系起来。如果我们将两支相互交锋过的球队视为已连接,并且这种连接关系可以被中继,那么进入某年季后赛的所有球队都将直接或间接连接;或者如果我们合并多年的季后赛,所有参加NBA季后赛的球队都会连接。基于这些连接,可以利用最短路径来找到任意两支球队之间最紧密的关系。如果我们为这些连接赋予数值,就可以使用可衡量机制来比较任意两支球队。

数据模型

  • 每支 NBA 球队是一个节点 [共 30 个节点]

  • 每个季后赛轮次(不是单场比赛,而是整个轮次)是一个节点 [每年 15 个轮次]

  • 每个季后赛轮次的结果将存储在边中;每条边的方向将从球队指向轮次,获胜场数将存储在该边中 [0,1,2,3,4]

设置

设置代码将把 2013、2014 和 2015 年的 NBA 季后赛结果作为示例数据加载到图数据库中。

单年的 NBA 季后赛

显示 2015 年的整个季后赛结果。

MATCH (t)-[]->(p:Playoff)
WHERE p.Year = "2015"
RETURN t,p

一支球队的历史季后赛记录

显示一支球队的所有历史季后赛记录。

MATCH (t:Team {Name: "Golden State"})-[w:WIN]->(:Playoff)<-[l:WIN]-()
RETURN t,w,l

计算胜率

列出过去 3 年每支球队的所有历史胜负记录。

MATCH (t:Team)-[w:WIN]->(:Playoff)<-[l:WIN]-()
RETURN t.Name as TEAM, SUM(w.Win) AS TOTAL_WIN, SUM(l.Win) as TOTAL_LOSS,
(toFloat(SUM(w.Win)) / (toFloat(SUM(w.Win))+ toFloat(SUM(l.Win)))) as WIN_PERCENTAGE
ORDER BY SUM(w.Win) DESC

如果两支球队以前交锋过:显示两支球队之间的季后赛历史记录

如果两支球队以前交锋过,以下查询将列出它们之间的所有比赛记录。

MATCH (t1:Team {Name: "Miami"})-[r1:WIN]->(p:Playoff)<-[r2:WIN]-(t2:Team {Name:"San Antonio"})
RETURN t1,r1,p,r2,t2

如果两支球队以前交锋过:计算胜负场次

对于以前交锋过的两支球队,可以使用它们的胜率来预测哪支球队更强。

MATCH (t1:Team {Name: "Miami"})-[r1:WIN]->(p:Playoff)<-[r2:WIN]-(t2:Team {Name:"San Antonio"})
RETURN p.Year as Year,r1.Win as Miami,r2.Win as San_Antonio
ORDER BY p.Year DESC

在上述例子中,圣安东尼奥和迈阿密在过去 3 年的季后赛中交锋了 12 场,圣安东尼奥赢了 7 场,输了 5 场。因此,如果他们在 2016 年 NBA 总决赛中再次相遇,圣安东尼奥可能有稍高的获胜机会。

如果两支球队以前从未交锋过:简单示例

找到两支球队之间的所有最短路径

MATCH (t1:Team {Name: "Miami"}),(t2:Team {Name:"Portland"}),
	p = AllshortestPaths((t1)-[*..14]-(t2))
RETURN p
MATCH p= AllShortestPaths((t1:Team {Name: "Miami"})-[:WIN*0..14]-(t2:Team {Name:"Portland"}))
WITH extract(r IN relationships(p)| r.Win) AS RArray
RETURN RArray

在上述例子中,一条路径 [1,4,4,1] 表示两支球队获胜机会可能相等,但在另一条路径 [4,3,4,,1] 中迈阿密显示出一点优势。所以我们可以说,如果迈阿密和波特兰在总决赛中相遇,迈阿密有更大的获胜机会。

如果两支球队以前从未交锋过:复杂示例

找到两支球队之间的所有最短路径

MATCH (t1:Team {Name: "Golden State"}),(t2:Team {Name:"Toronto"}),
	p = AllshortestPaths((t1)-[*..14]-(t2))
RETURN p
MATCH (t1:Team {Name: "Golden State"}),(t2:Team {Name:"Toronto"}),
	p = AllshortestPaths((t1)-[r:WIN*..14]-(t2))
WITH r,p,extract(r IN relationships(p)| r.Win ) AS paths
RETURN paths

上述情况比简单示例更复杂:共有 6 条最短路径,每条路径包含 8 个关系。因此,我引入了一个概念叫做平均净胜场,即每条路径的平均净胜场,其中 [净胜场] = 一条最短路径中 [总胜场数] - [总负场数]。当球队 A 到球队 B 的平均净胜场为正时,球队 A 对球队 B 具有获胜优势。

MATCH p= AllShortestPaths((t1:Team {Name: "Golden State"})-[:WIN*0..14]-(t2:Team {Name:"Toronto"}))
WITH extract(r IN relationships(p)| r.Win) AS RArray, LENGTH(p)-1  as s
RETURN AVG(REDUCE(x = 0, a IN [i IN range(0,s) WHERE i % 2 = 0 | RArray[i] ] | x + a)) //total win
- AVG(REDUCE(x = 0, a IN [i IN range(0,s) WHERE i % 2 <> 0 | RArray[i] ] | x + a)) //total loss
AS NET_WIN

当前模型的扩展

上面描述的模型仅使用原始的胜负场数来建议比较时的布尔结果。如果我们要将更多球队放在一起排名或建立更准确的可量化评级系统,可以将更多元素引入模型中——例如,球馆可以帮助在分析中考虑主场优势;或者为季后赛的不同轮次分配权重,这样 NBA 总决赛中的净胜场数在计算最短路径上的平均净胜场时,可以比第一轮中的净胜场数产生更显著的影响。

© . All rights reserved.