基于共现发现人物关系的python实现
2017-01-07 本文已影响2681人
大邓和他的python
本篇文章是阅读实验楼Foerc的“python基于共现提取《釜山行》人物关系”的总结。如果大家对于绚丽的网络关系节点图感兴趣,可以去实验楼学习。
图1 gephi做出的关系网络图
gephi1.jpeg图2 gephi工作界面
gephi2.jpeg要画出上图的节点网络关系图,需要使用Gephi,下载地址,如果大家想精进学习gephi可以去这里学习.
上面的步骤实际上很简单,都是可视化操作,照着鼠标点击gephi软件就可以,我就不展开了。但是使用gephi前,我们需要知道gephi软件需要的数据格式是什么样子的,只要准备好符合gephi的数据,才能出来绚丽的关系图。
画出绚丽的关系图,需要给gephi输入两份文件,即节点文件和边文件。
节点文件,有三个变量Id, Label, Weight(节点出现的次数)
节点.png边文件,有Source(起点),Target(终端),Weight(该起点-终点的出现次数) 边文件.png
所以现在的问题是把上述的数据结构的两份文件(节点文件、边文件)准备好。
节点文件还很好解决,只要统计出现的人物名的次数即可。
边文件里涉及到两个节点,及其出现的次数。这里就用到共现,即如果两个实体经常在一个区域出现,那么这两者存在关系的可能性会相当高。我们选择出现频率大于一定阈值的边,排除掉冗余的边,即可获取到边文件。
文件及源码
import jieba
import codecs
import jieba.posseg as psegnames = {}
names = {} # 姓名字典
relationships = {} # 关系字典
lineNames = [] # 每段内人物关系
# count names
jieba.load_userdict("/Users/apple888/Desktop/桌面文件/project/釜山行/dict.txt") # 加载字典
with codecs.open("/Users/apple888/Desktop/桌面文件/project/釜山行/busan.txt", "r", "utf-8") as f:
for line in f.readlines():
poss = pseg.cut(line) # 分词并返回该词词性
lineNames.append([]) # 为新读入的一段添加人物名称列表
for w in poss:
if w.flag != "nr" or len(w.word) < 2:
continue # 当分词长度小于2或该词词性不为nr时认为该词不为人名
lineNames[-1].append(w.word) # 为当前段的环境增加一个人物
if names.get(w.word) is None:
names[w.word] = 0
relationships[w.word] = {}
names[w.word] += 1 # 该人物出现次数加 1
# explore relationships
for line in lineNames: # 对于每一段
for name1 in line:
for name2 in line: # 每段中的任意两个人
if name1 == name2:
continue
if relationships[name1].get(name2) is None: # 若两人尚未同时出现则新建项
relationships[name1][name2]= 1
else: relationships[name1][name2] = relationships[name1][name2]+ 1 # 两人共同出现次数加 1
# output
with codecs.open("/Users/apple888/Desktop/桌面文件/project/釜山行/busan_node.txt", "a+", "utf-8") as f:
f.write("Id Label Weight\r\n")
for name, times in names.items():
f.write(name + " " + name + " " + str(times) + "\r\n")
with codecs.open("/Users/apple888/Desktop/桌面文件/project/釜山行/busan_edge.txt", "a+", "utf-8") as f:
f.write("Source Target Weight\r\n")
for name, edges in relationships.items():
for v, w in edges.items():
if w > 3:
f.write(name + " " + v + " " + str(w) + "\r\n")
之前在吴军《数学之美》提出过共现,但是不知道怎么实现,看了Foerc的这个实验,收获很大。想到了我之前做的文本情感分析,最基础的就是获得完整全面的情感词,但是不同领域的情感词是不同的,需要针对特定的领域进行针对性的建立词典。而这就需要用到共现理论,但之前苦于不懂如何实现。
欢迎关注公众号 大邓带你玩转python
大邓带你玩转python每周有直播哦,扫码即可加入