GraphGists

探索星球大战社交网络

我最近从计算的角度审视了整个星球大战宇宙,从中提取并分析了所有七部电影的社交网络。社交网络结构揭示了各部电影之间一些有趣的差异,特别是原始三部曲与前传之间的差异。在这里,我将探讨如何使用Neo4j数据库来表示和探索同一网络。

您可以在我的两篇博客文章中阅读更多关于我原始分析的内容,其中包括额外的社交网络分析和我用于下载和提取数据的F#脚本

网络

社交网络是使用电影剧本自动构建的。网络中的节点代表各个角色,如果他们在同一电影场景中发言,则通过链接连接。该网络仅包含出现在至少两个场景中且在剧本中明确命名的角色(我排除了名为“PILOT”甚至“STAR DESTROYER TECHNICIAN”的角色)。我还将角色分为两类:Person(人物)和Droid(机器人)。

这些互动构成了网络的基本结构,其中角色通过SPEAKS_WITH关系连接。我还使用APPEARS_IN关系包含了有关各部电影的信息。下图展示了网络的总体结构

network relations

设置

现在,我们可以使用来自全部7部电影组合而成的社交网络来设置数据库。

让我们看看数据库中的一些基本信息。以下查询提取了网络中包含的所有电影。

MATCH (m:Movie)
RETURN m.name

看来数据库中正确包含了全部七部星球大战电影。

简单的网络属性

现在,我们可以根据每部电影的网络属性开始进行比较。原始三部曲的社交网络与前传有何不同?《原力觉醒》又与其他电影有何比较?

让我们先看看每部电影中的角色数量。以下查询提取角色,并按他们出现的电影进行汇总返回数量。

MATCH (m:Movie)<-[:APPEARS_IN]-(character)
RETURN m.name AS movie, count(*) AS characters
ORDER BY m.name;

我们可以立即看到电影之间的一些差异。原始三部曲(第四集到第六集)的角色数量最少。另一方面,第一集:《魅影危机》的角色数量最多,几乎是原始三部曲的两倍。

角色之间有多少互动?在此查询中,我们提取在同一部电影中都出现的两个角色之间的所有链接,并返回每部电影的链接数量。这是一种简化,因为我假设如果两个角色之间存在链接,那么他们在同时出现的所有电影中都存在互动。

MATCH (m)<-[:APPEARS_IN]-(character)-[:SPEAKS_WITH]-(character2)-[:APPEARS_IN]->(m)
RETURN m.name AS movie, count(*) AS edges
ORDER BY m.name;

结果显示了一个类似的情况,原始三部曲的角色之间的链接数量较少,社交网络也较小。这与原始电影更紧凑、更有组织性的结构相符,原始电影的角色数量较少,更能将故事串联起来。

提取社交网络关系

我们还可以使用数据库提取每部星球大战电影的社交网络。以下查询提取出现在特定电影中的所有角色以及他们之间的所有互动。我使用第七集作为示例

MATCH network=(m)<-[:APPEARS_IN]-(character1)-[r]-(character2)-[:APPEARS_IN]->(m)
WHERE m.name='Episode VII: The Force Awakens'
RETURN character1, r, character2

我们可以看到网络中与黑暗面角色对应的部分,包括斯诺克、赫克斯将军等。还有一个节点集群代表抵抗组织飞行员,他们主要相互互动并与波互动。让我们更详细地探索网络。

角色在网络中的重要性

社交网络中中心性的基本衡量标准是度中心性。这仅仅是每个节点在网络中的连接数量。在我们的星球大战网络中,这对应于每个角色发言的场景总数。以下查询提取每个角色的SPEAKS_WITH关系数量,并返回前10名结果。

MATCH (ch1)-[:SPEAKS_WITH]-(ch2)
RETURN ch1.name AS name, count(*) AS degree
ORDER BY count(*) DESC LIMIT 10;

这个结果受到前传庞大社交网络的强烈影响。阿纳金位居榜首,是与其他角色互动最多的角色。由于前传的存在,就连贾贾也进入了前10名。

谁的度最高?

我们可以转而看看在各部电影中谁的度最高。此查询提取相互交谈并出现在同一电影中的角色,并计算每个此类连接的数量。我使用原始的第四集:《新希望》作为示例。

MATCH (m)<-[:APPEARS_IN]-(ch1)-[:SPEAKS_WITH]-(ch2)-[:APPEARS_IN]->(m)
WHERE m.name='Episode IV: A New Hope'
RETURN ch1.name AS name, count(*) AS degree
ORDER BY count(*) DESC LIMIT 5;

在这里,卢克·天行者是最核心的角色,其次是莱娅和机器人。

我们还可以可视化结果并查看具体的互动。例如,以下查询提取所有与卢克·天行者互动过的角色,以及他们出现的电影。

MATCH path=(luke:Person {name: 'LUKE'})-[:SPEAKS_WITH]-(other)-[:APPEARS_IN]-(movie)
RETURN path

在这里我们可以看到,有些角色集中在特定的电影中(这些角色只出现在该特定电影中)。其他与卢克在多部电影中互动的角色则在网络中显示为更核心的节点。

总结

这个GraphGist展示了如何利用我从电影剧本中提取的星球大战社交网络进行简单的社交网络分析。我们探讨了如何提取和汇总各部电影以及特定角色的子网络。总的来说,这是我第一次使用Neo4j,创建网络并从数据库中提取有趣的信息非常容易。

© . All rights reserved.