GraphGists

对于不了解欧洲歌唱大赛的人来说,它是一场欧洲国家之间的歌曲比赛。其特殊之处在于,各国必须互相投票来决定获胜者。

giphy

但是,每年都有同样的感觉:好像有些国家在拉帮结派。我们能否借助图数据库来揭示这种感觉呢?让我们拭目以待。

模型非常简单

Eurovision

这里收集的数据代表了2012年、2013年、2014年和2015年欧洲歌唱大赛决赛的所有投票。

注意:投票国也可以是候选国。

对于注意到“Autralia”的人来说,这并不是“Austria”的拼写错误,澳大利亚在2015年确实作为候选国参加了欧洲歌唱大赛。

谁参加了?是哪一年?是以候选国还是投票国的身份参加?

我们先从简单的开始,看看谁参加了哪场决赛,以及谁只是投票国。

MATCH (country)-[v:VOTE]->()
WITH country, count(DISTINCT v.year) AS nb_voting ,collect(DISTINCT v.year) AS year_voting
MATCH ()-[p:VOTE]->(country)
WITH country, nb_voting,year_voting, count(DISTINCT p.year) AS nb_participation ,collect(DISTINCT p.year) AS year_participation
RETURN country.name,nb_voting,year_voting,nb_participation,year_participation
ORDER BY nb_participation DESC

一年内的投票分布可视化

快速图表展示一年内的投票分布(这里是2015年)。

MATCH path = (voter:Country)-[v:VOTE]->(candidate:Country)
WHERE v.year = 2015 AND v.score >= 8
RETURN path

最佳投票国

哪个投票国总是投给获胜者?

MATCH (voter)-[vote:VOTE]->(country)
WHERE vote.score = 12 AND country.winner = "Yes"
WITH voter, COUNT(DISTINCT vote.year) AS nb_year , COLLECT(DISTINCT vote.year) AS years
WHERE nb_year = 4
RETURN voter.name,years
ORDER BY nb_year DESC

如果你想下注,英国看起来是个非常好的顾问 :-D

投票的影响?

如果我们只考虑8、10、12分的投票,每年排名会改变吗?

MATCH ()-[up:VOTE]->(country)
WHERE up.score >= 8
WITH country, up.year as year, SUM(up.score) AS up_score
MATCH ()-[all:VOTE]->(country)
WHERE all.year = year
WITH country, year, up_score , SUM(all.score) as all_score
RETURN country.name,year, all_score,up_score
ORDER BY year,all_score DESC

所以,看起来8分以下的投票并没有真正影响排名。也许前5名中的一些位置会互换,但没有剧烈的变化。

投票的多样性

正如我们之前看到的,最重要的分数是著名的8、10和12分。这些分数每年是如何按国家分布的?

我们来看看一个国家投票给了多少个不同的候选国。

MATCH (a)-[e:VOTE]->(b)
WHERE e.score >= 8
WITH a, count(DISTINCT e.year) AS years, collect(DISTINCT b.name) AS candidate, count(DISTINCT b.name) AS nb_candidate,toFloat(count(DISTINCT b.name))/ toFloat(count(DISTINCT e.year)*3) AS ratio
WHERE ratio <> 1
RETURN a.name,candidate,nb_candidate,years,ratio
ORDER BY ratio ASC

详情

MATCH (voter)-[e:VOTE]->(candidate)
WHERE e.score >= 8
WITH voter, candidate, collect(DISTINCT e.year) AS years, COUNT(DISTINCT e.year) as nb_year
RETURN voter.name,candidate.name,years
ORDER BY nb_year DESC,voter.name

这个比例显示了一个国家在四届比赛中投票的“多样性”。大多数国家每次投票给了几乎不同的国家。但有少数国家没有这种投票的多样性,它们几乎总是投给同一个候选国。

可视化

MATCH w WHERE w.winner = "Yes" REMOVE w:Country SET w:Winner;
MATCH (a)-[e:VOTE]->(b)
WHERE e.score >= 8
WITH a,b, count(DISTINCT e.year) AS years
WHERE years >= 2
CREATE p= (a)-[r:SIMILAR_VOTE {nb:years}]->(b)

RETURN p

12分投给了…​ Foaf

在这个查询中,我们将尝试检查每年双方投票得分都达到8分的互投情况。

MATCH (a)-[e:VOTE]->(b),(b)-[f:VOTE]->(a)
WHERE f.year = e.year AND e.score >= 8 AND f.score >= 8
RETURN a.name,b.name,e.year,e.score,f.score
ORDER BY e.year,a.name

这个结果相当详细,我们可以按年份进行聚合来简化。

MATCH (a)-[e:VOTE]->(b), (b)-[f:VOTE]->(a)
WHERE f.year = e.year AND e.score >= 8 AND f.score >= 8
WITH a,b,collect(DISTINCT e.year) as years,count(DISTINCT e.year) as nb_years
RETURN a.name,b.name,years
ORDER BY nb_years DESC

有趣的是,确实存在互相投票的国家,对于其中一些国家来说,在四年中出现了2次。

朋友圈图

让我们可视化最后的结果

MATCH w WHERE w.winner = "Yes" REMOVE w:Country SET w:Winner;
MATCH p = (a)-[e:VOTE]->(b), q = (b)-[f:VOTE]->(a)
WHERE f.year = e.year AND e.score >= 8 AND f.score >= 8

RETURN p

有趣的是,一些获胜者看起来像是某个国家集群的一部分。但由于他们是获胜者,他们在图中自然表现得像一个“枢纽”。让我们去掉这些获胜者,再绘制一遍图。

MATCH p = (a)-[e:VOTE]->(b), q = (b)-[f:VOTE]->(a)
WHERE f.year = e.year AND e.score >= 8 AND f.score >= 8 AND a.winner <> "Yes" AND b.winner <> "Yes"

RETURN p

无论是否包含获胜候选国,结果都一样:它几乎看起来像世界边界图。所以听起来有些国家属于“地理帮派”的一部分。

结论

当然,通过更多数据和更详细的分析,这项调查可以得到改进。

我们不能肯定地得出国家是否组织成“帮派”的结论,但我们可以观察到一些有趣的特异性,并根据地理位置区分出一些国家集群。