Gephi 可视化 + NetworkX 网络分析——《釜山行》人物关系(三)

Gephi 可视化 + NetworkX 网络分析------《釜山行》人物关系(三)

标签: Gephi | NetworkX | Python3 | matplotlib | 网络可视化 | 人物关系

实验环境: 华为云 FlexusX / Ubuntu 24.04 / Python 3.12.3

分析节点: node-03(公网 124.70.105.142)

可视化节点: node-04(公网 120.46.44.194)

1. 本文目标

  1. 在 node-03 用 NetworkX 构建无向图,计算常见网络指标;
  2. 导出 .gexf / .graphml 格式,供 Gephi 导入;
  3. 在 node-04 用 matplotlib 生成静态可视化图;
  4. 演示 Gephi 安装和导入流程;
  5. 对结果进行解读。

2. NetworkX 网络分析(node-03)

2.1 代码(busan_network.py)

python 复制代码
#!/usr/bin/env python3
import networkx as nx
import json

# 读取节点和边
nodes = []
with open("/root/nodes.csv", "r", encoding="utf-8") as f:
    for line in f.readlines()[1:]:
        parts = line.strip().split(",")
        nodes.append({"id": parts[0], "label": parts[1], "weight": int(parts[2])})

edges = []
with open("/root/edges.csv", "r", encoding="utf-8") as f:
    for line in f.readlines()[1:]:
        parts = line.strip().split(",")
        edges.append({"source": parts[0], "target": parts[1], "weight": int(parts[2])})

# 构建无向图
G = nx.Graph()
for node in nodes:
    G.add_node(node["id"], label=node["label"], weight=node["weight"])
for edge in edges:
    G.add_edge(edge["source"], edge["target"], weight=edge["weight"])

# 计算指标
degree_centrality = nx.degree_centrality(G)
betweenness_centrality = nx.betweenness_centrality(G)
closeness_centrality = nx.closeness_centrality(G)
eigenvector_centrality = nx.eigenvector_centrality(G, max_iter=1000)
clustering = nx.clustering(G)
density = nx.density(G)
avg_path = nx.average_shortest_path_length(G)

# 指标写入节点属性
for node in G.nodes():
    G.nodes[node]["degree_centrality"] = round(degree_centrality[node], 4)
    G.nodes[node]["betweenness_centrality"] = round(betweenness_centrality[node], 4)
    G.nodes[node]["closeness_centrality"] = round(closeness_centrality[node], 4)
    G.nodes[node]["eigenvector_centrality"] = round(eigenvector_centrality[node], 4)
    G.nodes[node]["clustering"] = round(clustering[node], 4)

# 导出 Gephi 格式
nx.write_gexf(G, "/root/busan_network.gexf")
nx.write_graphml(G, "/root/busan_network.graphml")

stats = {
    "nodes": len(nodes),
    "edges": len(edges),
    "density": round(density, 4),
    "avg_path_length": round(avg_path, 4),
    "degree_centrality": {k: round(v, 4) for k, v in degree_centrality.items()},
    "betweenness_centrality": {k: round(v, 4) for k, v in betweenness_centrality.items()},
    "closeness_centrality": {k: round(v, 4) for k, v in closeness_centrality.items()},
    "eigenvector_centrality": {k: round(v, 4) for k, v in eigenvector_centrality.items()},
}
with open("/root/network_stats.json", "w", encoding="utf-8") as f:
    json.dump(stats, f, ensure_ascii=False, indent=2)

2.2 真实服务器输出

text 复制代码
root@ecs-11e6-0003:~# cd /root && python3 busan_network.py
============================================================
步骤1: 读取节点和边数据
============================================================
节点数: 11
边数: 55

============================================================
步骤2: 构建NetworkX无向图
============================================================
图节点数: 11
图边数: 55

============================================================
步骤3: 计算网络拓扑指标
============================================================

--- 度中心性 (Degree Centrality) ---
石宇: 1.0000
秀安: 1.0000
尚华: 1.0000
盛京: 1.0000
珍熙: 1.0000
英国: 1.0000
容国: 1.0000
老姐姐: 1.0000
老妹妹: 1.0000
乞丐: 1.0000
列车长: 1.0000

--- 介数中心性 (Betweenness Centrality) ---
石宇: 0.0000
...
列车长: 0.0000

--- 接近中心性 (Closeness Centrality) ---
石宇: 1.0000
...
列车长: 1.0000

--- 特征向量中心性 (Eigenvector Centrality) ---
石宇: 0.3015
...
列车长: 0.3015

--- 聚类系数 (Clustering Coefficient) ---
石宇: 1.0000
...
列车长: 1.0000

网络密度 (Density): 1.0000
平均最短路径长度: 1.0000

2.3 指标解释

指标 含义 本实验结果 说明
度中心性 节点直接连接数占总节点数的比例 1.0 完全图,每人都与其他 10 人相连
介数中心性 最短路径中经过该节点的比例 0.0 任意两点都直接相连,无"桥梁"
接近中心性 到达其他节点的平均距离倒数 1.0 距离全为 1,最紧密
特征向量中心性 连接的邻居重要程度的综合 0.3015 完全图,所有节点相同
聚类系数 邻居之间两两相连的比例 1.0 邻居子图也是完全图
网络密度 实际边数 / 最大可能边数 1.0 完全图密度
平均最短路径 任意两节点最短距离平均 1.0 一步可达

可见,当文本较短、所有人物都相互共现时,NetworkX 的拓扑指标 会全部拉满。因此真正有用的信息是 边权重(共现次数),而非二值网络的拓扑结构。下面的可视化将突出边权重。

3. matplotlib 静态可视化(node-04)

3.1 全图可视化

busan_visualize.py 读取 busan_network.gexf,使用 Spring 布局渲染,得到:

节点大小 = 出现频次;节点颜色 = 出现频次;边宽度 = 共现次数;白色标签为边权重。

3.2 人物频次图

3.3 中心性指标对比图

从图中可见度中心性、接近中心性、聚类系数均为 1,介数中心性均为 0,再一次验证"完全图"结论。

3.4 过滤核心网络(权重 >= 7)

为了突出核心关系,新增 busan_visualize_filtered.py,只保留共现次数 ≥ 7 的边:

python 复制代码
THRESHOLD = 7
G = nx.Graph()
for node, attr in G_full.nodes(data=True):
    G.add_node(node, **attr)
for u, v, attr in G_full.edges(data=True):
    if attr.get("weight", 0) >= THRESHOLD:
        G.add_edge(u, v, weight=attr["weight"])

输出结果:

text 复制代码
过滤阈值: >= 7
节点数: 11, 边数: 24

过滤后,核心人物被聚成紧密社群,而老姐姐、老妹妹、列车长因共现次数低于阈值而孤立,直观说明她们在叙事中相对边缘。

3.5 核心关系表

Top 核心关系集中在:

  • 石宇 ↔ 秀安(父女,12)
  • 石宇 ↔ 盛京(共同保护秀安,11)
  • 秀安 ↔ 盛京(被共同保护,11)
  • 石宇 ↔ 尚华(并肩作战,9)
  • 尚华 ↔ 盛京(夫妻,9)
  • 珍熙 ↔ 容国(恋人,9)

这与电影剧情高度吻合。

4. Gephi 安装与导入流程

4.1 安装 OpenJDK 17

Gephi 是 Java 桌面程序,需要 JDK 17:

bash 复制代码
apt-get update -qq
apt-get install -y openjdk-17-jdk

4.2 下载 Gephi

bash 复制代码
wget https://github.com/gephi/gephi/releases/download/v0.10.1/gephi-0.10.1-linux-x64.tar.gz
sudo tar xzf gephi-0.10.1-linux-x64.tar.gz -C /opt

如果 GitHub 下载慢,可以先把安装包本地下载再 SCP 到服务器。

4.3 导入 GEXF

  1. 打开 Gephi → 数据实验室 → 导入电子表格;
  2. 选择 nodes.csv,导入为 节点表;
  3. 选择 edges.csv,导入为 边表;
  4. 或直接 文件 → 打开 ,选择 busan_network.gexf。

4.4 推荐布局与样式设置

设置项 推荐值 效果
布局算法 Force Atlas 2 / Fruchterman-Reingold 自动展开节点
节点大小 Weight(出现频次) 突出主角
节点颜色 Modularity(社团检测) 区分人物社群
边粗细 Weight(共现次数) 关系越强越粗
标签 显示 Label 人物名称

5. 踩坑总结

问题 原因 解决
pip3 install 失败 Ubuntu 24.04 PEP 668 加 --break-system-packages
多 pip 进程死锁 批量安装并发 单节点 nohup 后台安装,安装完验证导入
中文乱码 无中文字体 apt-get install fonts-noto-cjk
介数中心性除零 完全图所有值为 0 改以节点频次作为颜色映射
SSH banner 读取失败 连接过于频繁 加 banner_timeout=60 并间隔重试

6. 三篇完整输出文件

文件 说明
busan_text.txt 电影文本
busan_dict.txt 自定义人名词典
busan_segment.py 分词与共现提取
busan_network.py NetworkX 分析
busan_visualize.py matplotlib 全图可视化
busan_visualize_filtered.py 核心网络可视化
nodes.csv Gephi 节点表
edges.csv Gephi 边表
busan_network.gexf Gephi 导入文件
network_stats.json 网络指标统计

7. 总结

本项目通过 4 台服务器完整演示了:

  1. 共现网络的理论和构建方法;
  2. jieba 分词与自定义词典;
  3. NetworkX 网络指标计算;
  4. GEXF 导出与 Gephi 导入流程;
  5. matplotlib 静态可视化与权重过滤技巧。

从《釜山行》人物关系中提取到的核心社群与电影剧情一致,验证了共现网络方法在文本人物关系挖掘上的有效性。

8. 参考

相关推荐
MasonYyp39 分钟前
声音转文字的模型
python
草莓熊Lotso3 小时前
【C++ 基于微服务的即时通讯系统】etcd + brpc 从安装到服务注册发现全链路实战
网络·数据库·c++·redis·微服务·etcd
信誓旦旦的程序猿8 小时前
【Python量化实战宝典 #08】可转债与债券接口手册:转股价·溢价率·纯债价值(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
Lethehong8 小时前
Oracle 加个字段,目标库就报错?KFS 用“先拆后组“打通异构 DDL
数据库·oracle
砚底藏山河8 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
今年下半年8 小时前
AI智能体项目实战记录(02):初始化 Python 项目
开发语言·人工智能·python·fastapi
Williamtym8 小时前
PickGo Lab实践:用浏览器、Python和MCP串起机器人搬运仿真
开发语言·python·机器人
Web极客码9 小时前
锁定真正的磁盘卡顿:我用 OpenCode 配合 eBPF 诊断 NVMe 队列深度延迟与 I/O 写放大
数据库·oracle
CS创新实验室9 小时前
Python 对象“死“了之后去了哪?——引用计数与分代垃圾回收
开发语言·jvm·python
CCblandy9 小时前
雪花 ID 四个边界实测:时钟回拨重号 500 个,前端 JSON.parse 直接丢精度
后端·python·算法·性能优化·架构