基于知识图谱的知识问答建立(二)

时隔十几天,终于自己写成了第一个基于neo4j的知识图谱

这一段时间真的是好忙,改论文,整理实验室数据,还要帮老师弄其他东西。回头看看其实六月份天天忙的一匹,但是不知道到底有什么是我沉淀下来的,还好有博客陪伴,回头看的时候能够发现还有那么点东西。话说我看了我写的第一篇博客,去年六月份的,真的是汗颜,现在的我都不知道到底在写什么。

这两天挤出一点时间,把知识图谱建立了起来,其实这个很简单的图谱,但是也踩了很多雷。

一、获取数据

我使用的是公司内部爬虫平台免费提供的百度文库电影数据,由于是公司的,所以不知道涉及不涉及版权问题,所以只上传一点数据,就那么个意思。

然后我在定义实体的时候,我将第一行数据转化成字典类型,接着看了keys值,然后定义的节点,后来我发现第一行数据少了很多内容,不过我没有重新定义,所以定义的节点类型较少。

建立图谱的时候,能够转化成字典类型的数据是首选,因为比较好操作。

然后在跑着的时候,我发现公司的数据其实问题挺多的,有些地方由于数据不好,所以总是报错,而且只凭代码还不好解决,需要从数据整理开始,但是为了尽快建立图谱,所以在某些地方使用了try,except函数,或者直接没有定义,规避了这些事情。看来自己想做点什么东西,最好还是自己搞才行。

二,建立图谱(Python代码)

基础知识不多说,网上有很多的py2neo模块的使用详解, neo4j数据库的教程,主要是思路。

第一,首先提取实体,你自己定义什么东西是实体,什么东西是属性,我在这里面定义电影名称,导演,产地是实体,剩下的内容:电影中文名、时长、链接是属性。

第二,创建实体节点:使用py2neo 模块中的Node函数,注意属性应该和你的主实体(我自己定义的说法,也就是唯一不可替代性,这里面指电影名称)的个数一样,而其他实体,比如导演,制片产地都是可能会有重复的情况,创建实体的时候,需要set()一下,不要重复创建。

第三,建立实体关系:在这里面我定义实体关系如下:

在这里面,我本来想定义双向关系,后来从网上查了查资料,发现neo4j数据库,定义双向关系是没有意义的,暂时不知道对于问答系统来说是对还是错,接下来去做再发现。 

 

虽然定义的关系有点难听,但是为了让图谱五脏俱全,就随意定义了些东西,这个可以看自己怎么定义。

其中定义关系的时候,没有用Relationship,是因为这个函数需要和Node函数组队一起用,但是我的数据量较大,如果选取这种方式,较为繁琐。所以使用 graph().run() 的形式建立图谱。

第四:完成图谱,图谱的计算量很大,由于一行数据,可以提取很多实体,各实体间的关系也可以自定义,所以数据量大的时候,运行时间较长,这是不可避免的事情。

 

下面是我的图谱截图:

我发现,我用很多数据跑出来的图谱,可视化不出来,虽然查,会存在,但是显示不了,用很少的数据, 跑反而能可视化出来。不知道为什么。

Python代码如下

# -*- coding: utf-8 -*-
from py2neo import Graph,Node,Relationship
import os
#import json

class KG:
    def __init__(self):
        self.g=Graph(
                    "http://localhost:7474/browser/",
                    http_post=7474,
                    user="neo4j",
                    password="xunfei"
                    )
        self.data_path="D:\公司项目\knowlodge_graph\百度文库数据"
    def init_data(self):
        os.chdir(self.data_path)
        with open("bkm.txt",encoding='utf-8') as file:
            director_total=[]
            region_total=[]
            time_total=[]
#            video_info_total=[]
            video_path_total=[]
            name_total=[]
            chinese_name_total=[]
            
            region_total_relationship=[]
            director_total_relationship=[]
            worked_total_relationship=[]
            for f in file:
#                print(f)
                person=eval(f)
                name=person["video_name"]
                name_total.append(name)
                time_total.append(person.get("片长",""))
                chinese_name_total.append(person.get("中文名",""))
#                video_info_total.append(person.get("video_detail_info",""))
                video_path_total.append(person.get("video_html_path",""))
                director_total.append(person.get("导演",""))
                region_total.append(person.get("制片地区",""))
                director_total_relationship.append([name,person.get("导演","")])
                region_total_relationship.append([name,person.get("制片地区","")])
                worked_total_relationship.append([person.get("导演","佚名"),person.get("制片地区","未知")])

        return {"name":name_total,"time":time_total,"chinese_name":chinese_name_total,\
                "video_path":video_path_total},\
                [set(director_total),set(region_total)],\
                [director_total_relationship,region_total_relationship,worked_total_relationship]

    def build_KG(self,name,othernode):
        self.create_name_node(name)
        count= 0
        node_name=["导演","制片地区"]
        for info in othernode:
            self.create_node(label=node_name[count],info=info)
            count +=1
#            number =number + 1 if number%len(info)==0 else 0
    def build_relationship(self,relationship):
        director_total_relationship,region_total_relationship,worked_total_relationship=relationship
        self.create_relation("电影名称","导演",director_total_relationship,"为作品","created",)
        self.create_relation("电影名称","制片地区",region_total_relationship,"拍摄于","shot")       
        self.create_relation("导演","制片地区",worked_total_relationship,"曾工作于","worked")
            
    def create_node(self,label,info):
        for num,i in enumerate(info):
#            print(i)
            self.g.create(Node(label,name=i))
            print("正在创建{0}节点,正在处理第{1}个数据,共有{2}个数据".format(label,num+1,len(info)))
    def create_name_node(self,name):
        for i in range(len(name["name"])):
            self.g.create(Node("电影名称",name=name["name"][i],chinese_name=name["chinese_name"][i],\
                               time=name["time"][i],video_path=name["video_path"][i]))
            print("正在创建名称节点,正在处理第{0}个数据,共有{1}个数据".format(i+1,len(name['name'])))
    def create_relation(self,name1,name2,data,relation1,relation1_name):
        count=0
        for rel in data:
            count +=1
            print("正在处理{0}与{1}的关系,正在进行第{2}行,共有{3}行数据".format(name1,name2,count,len(data)))
            p,q=rel
#            print("MATCH (u:{0}),(n:{1}) where u.name='{2}' and n.name='{3}' create (u)-[r:{4}{{name:'{5}'}}]->(n)".\
#                   format(name1,name2,p,q,relation1,relation1_name))
            try:   
                self.g.run("MATCH (u:{0}),(n:{1}) where u.name=\"{2}\" and n.name=\"{3}\" create (u)-[r:{4}{{name:'{5}'}}]->(n)".\
                       format(name1,name2,p,q,relation1,relation1_name))   
            except:
                print("导入{0}电影出现问题".format(p))

if __name__=='__main__':
    name,othernode,relationship=KG().init_data()
    KG().build_KG(name,othernode)
    KG().build_relationship(relationship)
    

数据(部分) 如下:

已上传至github中

https://github.com/JerryVSTom/The-part-of-data/tree/master

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值