Python中文社区我的Python自学之路nltk

基于共现发现人物关系的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
每周有直播哦,扫码即可加入
上一篇下一篇

猜你喜欢

热点阅读