美文网首页Python中文社区我的Python自学之路nltk
基于共现发现人物关系的python实现

基于共现发现人物关系的python实现

作者: 大邓和他的python | 来源:发表于2017-01-07 17:34 被阅读2681次

    本篇文章是阅读实验楼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
    每周有直播哦,扫码即可加入

    相关文章

      网友评论

        本文标题:基于共现发现人物关系的python实现

        本文链接:https://www.haomeiwen.com/subject/wbpfbttx.html