GraphGists

探索星球大战社交网络

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

您可以在我的两篇博文中阅读更多关于我最初分析的信息,其中包括其他社交网络分析以及我用于下载和提取数据的 F# 脚本

网络

社交网络是使用电影剧本自动构建的。网络中的节点代表各个角色,如果他们在同一电影场景中都说话,则通过链接连接。该网络仅包含至少出现在两个场景中并在剧本中明确命名的角色(我排除了名为“飞行员”甚至“星际驱逐舰技术员”的角色)。我还将角色分为两类:PersonDroid

交互创建了网络的基本结构,其中角色通过 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,创建网络并从数据库中提取有趣信息非常容易。