先上效果
今天在一如既往地划水时,水友给我推了个小说叫《剑来》。下班回到家,准备下载了看一下,结果一看,光txt都要9MB,以我磨蹭的速度,怕不是明年都看不完。正好最近在做一些NLP相关的东西,就想拿这个小说来练个手。
根据小说的内容,建立一个简单的人物关系图
思路大概是:
1. 建立人物列表
2. 计算每个人物在小说里的出现次数
3. 计算每2个人物在小说里共同出现的次数
4. 把1,2,3制作成简单的图表
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from pyecharts import Graph
#对全文根据句号进行分割
def cut_test():
reader = open("jianlai.txt","r",encoding="utf-8").read()
sentence_list = reader.split("。")
return sentence_list
#计算名字在全文中出现的次数
def count_name():
reader = open("jianlai.txt", "r", encoding="utf-8").read()
output = []
for i in name:
count = reader.count(i)
# 主角出现的次数太多,最终作图效果会受影响,这个小小处理一下
if i == "陈平安":
count = count/5
row = {"name": i, "symbolSize": count/100}
output.append(row)
return output
#计算两个角色一起出现在一句句子里的次数
def get_rel(name1, name2,snetence):
counter = 0
for i in sentence:
if name1 in i and name2 in i:
counter +=1
row = {"source": name1, "target": name2, "weight": counter/100}
return row
#根据所有角色列表,计算两两角色一起出现的次数
def count_re():
output = []
counter = 0
for i in name:
for m in name[counter:]:
if i != m:
row = get_rel(i,m,sentence)
if row["weight"] >0:
output.append(get_rel(i,m,sentence))
counter += 1
return output
#用pyecharts画图
def paint_grapg(nodes=[],links=[]):
print(nodes)
print(links)
nodes = nodes
links = links
graph = Graph("《剑来》人物关系热力图", height=800)
graph.add("",
nodes,
links,
graph_repulsion=200,
graph_edge_length=400,
graph_layout="force",
is_label_show=True,
line_opacity=0.2,
line_curve=0.5
)
graph.use_theme("dark")
graph.render()
if __name__ == '__main__':
name = ['陈平安', '齐静春', '宁姚', '阮秀', '李宝瓶', '宋集薪', '稚圭', '老秀才', '阿良', '左右', '崔瀺', '阮邛', '老杨头', '陆沉', '道老二', '宋长镜',
'李二', '郑大风', '魏檗', '崔姓老人', '裴杯', '曹慈', '裴钱']
sentence = cut_test()
name_count = count_name()
rel_count = count_re()
paint_grapg(name_count,count_re())
复制代码
下一步可以做的优化
1. 现在所有的人物都没有分类,下一步可以根据人物的性别、门派做一个简单的分类
2. 做完才发现这一版连jieba都没用,下一步可以对句子做一些分词和词性标记,看能不能提取点什么好玩的东西出来。
3. 现在人物之间的“共同出现”关系的频次没有表现在图表上,可以下次优化
4. 现在人物之间仅有“共同出现”这一种关系,可以考虑制作更多的人物关系类型,扩展以后,可以考虑使用neo4j或者d3来做呈现。