赞
踩
时隔十几天,终于自己写成了第一个基于neo4j的知识图谱
这一段时间真的是好忙,改论文,整理实验室数据,还要帮老师弄其他东西。回头看看其实六月份天天忙的一匹,但是不知道到底有什么是我沉淀下来的,还好有博客陪伴,回头看的时候能够发现还有那么点东西。话说我看了我写的第一篇博客,去年六月份的,真的是汗颜,现在的我都不知道到底在写什么。
这两天挤出一点时间,把知识图谱建立了起来,其实这个很简单的图谱,但是也踩了很多雷。
我使用的是公司内部爬虫平台免费提供的百度文库电影数据,由于是公司的,所以不知道涉及不涉及版权问题,所以只上传一点数据,就那么个意思。
然后我在定义实体的时候,我将第一行数据转化成字典类型,接着看了keys值,然后定义的节点,后来我发现第一行数据少了很多内容,不过我没有重新定义,所以定义的节点类型较少。
建立图谱的时候,能够转化成字典类型的数据是首选,因为比较好操作。
然后在跑着的时候,我发现公司的数据其实问题挺多的,有些地方由于数据不好,所以总是报错,而且只凭代码还不好解决,需要从数据整理开始,但是为了尽快建立图谱,所以在某些地方使用了try,except函数,或者直接没有定义,规避了这些事情。看来自己想做点什么东西,最好还是自己搞才行。
基础知识不多说,网上有很多的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中
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。