作者:大邓


本篇文章是阅读实验楼 Foerc的“python基于共现提取《釜山行》人物关系”的总结。如果大家对于绚丽的网络关系节点图感兴趣,可以去实验楼学习。

python演员关系参演电影类型的数量 python人物关系_python演员关系参演电影类型的数量

要画出上图的节点网络关系图,需要使用Gephi,下载地址gephi,如果大家想精进学习gephi可以去这里学习https://www.baidu.com/link?url=a4REdia6AuOIP5ITsK6tf8Rs4kS9qr5YGT-sYIfKK4gMLHVjTtaiOg1q7iZi02yO&wd=&eqid=d15f436100054000000000065870a856

上面的步骤实际上很简单,都是可视化操作,照着鼠标点击gephi软件就可以,我就不展开了。但是使用gephi前,我们需要知道gephi软件需要的数据格式是什么样子的,只要准备好符合gephi的数据,才能出来绚丽的关系图。

节点文件边文件

Id, Label, Weight(节点出现的次数)



python演员关系参演电影类型的数量 python人物关系_python_02

边文件,有

Source(起点),Target(终端),Weight(该起点-终点的出现次数)



python演员关系参演电影类型的数量 python人物关系_python_03

python演员关系参演电影类型的数量 python人物关系_公众号_04

所以现在的问题是把上述的数据结构的两份文件(节点文件、边文件)准备好。


节点文件还很好解决,只要统计出现的人物名的次数即可。

边文件里涉及到两个节点,及其出现的次数。这里就用到共现,即如果两个实体经常在一个区域出现,那么这两者存在关系的可能性会相当高。我们选择出现频率大于一定阈值的边,排除掉冗余的边,即可获取到边文件。

[文件及源码](https://pan.baidu.com/s/1geHFpa7)

import jieba
import codecs
import jieba.posseg as pseg

“”“
在代码中,我使用字典类型names保存人物,该字典的键为人物名称,值为该人物在全文中出现的次数。我使用字典类型relationships保存人物关系的有向边,该字典的键为有向边的起点,值为一个字典edge,edge的键是有向边的终点,值是有向边的权值,代表两个人物之间联系的紧密程度。lineNames是一个缓存变量,保存对每一段分词得到当前段中出现的人物名称,lineName[i]是一个列表,列表中存储第i段中出现过的人物。
”“”
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:
		    # 当分词长度小于2或该词词性不为nr时认为该词不为人名
                    continue
                # 为当前段的环境增加一个人物
		lineNames[-1].append(w.word)		
			
                if names.get(w.word) is None:
		    names[w.word] = 0
		    relationships[w.word] = {}
                    # 该人物出现次数加 1
		    names[w.word] += 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:
                # 两人共同出现次数加 1
	        relationships[name1][name2] = relationships[name1][name2]+ 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的这个实验,收获很大。想到了我之前做的文本情感分析,最基础的就是获得完整全面的情感词,但是不同领域的情感词是不同的,需要针对特定的领域进行针对性的建立词典。而这就需要用到共现理论,但之前苦于不懂如何实现。