NLP第20课:Neo4j 从入门到构建一个简单知识图谱

[复制链接]
daocaomen 发表于 2019-5-7 11:47:58 | 显示全部楼层 |阅读模式
来源:https://www.jianshu.com/p/d4175930e820
若内容不全,可点击上述链接查看来源网页,在网页中点击红色双层向下的箭头阅读全文


Neo4j对于大多数人来说,可能是比较陌生的。其实,Neo4j是一个图形数据库,就像传统的关系数据库中的Oracel和MySQL一样,用来持久化数据。Neo4j是最近几年发展起来的新技术,属于NoSQL数据库中的一种。

本文主要从Neo4j为什么被用来做知识图谱,Neo4j的简单安装,在Neo4j浏览器中创建节点和关系,Neo4j的Python接口操作以及用Neo4j构建一个简单的农业知识图谱五个方面来讲。

Neo4j为什么被用来做知识图谱

从第19课《知识挖掘与知识图谱概述》中,我们已经明白,知识图谱是一种基于图的数据结构,由节点和边组成。其中节点即实体,由一个全局唯一的ID标示,关系(也称属性)用于连接两个节点。通俗地讲,知识图谱就是把所有不同种类的信息连接在一起而得到一个关系网络,提供了从“关系”的角度去分析问题的能力。

而Neo4j作为一种经过特别优化的图形数据库,有以下优势:

  • 数据存储:不像传统数据库整条记录来存储数据,Neo4j以图的结构存储,可以存储图的节点、属性和边。属性、节点都是分开存储的,属性与节点的关系构成边,这将大大有助于提高数据库的性能。

  • 数据读写:在Neo4j中,存储节点时使用了Index-freeAdjacency技术,即每个节点都有指向其邻居节点的指针,可以让我们在时间复杂度为O(1)的情况下找到邻居节点。另外,按照官方的说法,在Neo4j中边是最重要的,是First-classEntities,所以单独存储,更有利于在图遍历时提高速度,也可以很方便地以任何方向进行遍历。

  • 资源丰富:Neo4j作为较早的一批图形数据库之一,其文档和各种技术博客较多。

  • 同类对比:Flockdb安装过程中依赖太多,安装复杂;Orientdb,Arangodb与Neo4j做对比,从易用性来说都差不多,但是从稳定性来说,neo4j是最好的。

综合上述以及因素,我认为Neo4j是做知识图谱比较简单、灵活、易用的图形数据库。

Neo4j的简单安装

Neo4j是基于Java的图形数据库,运行Neo4j需要启动JVM进程,因此必须安装JavaSE的JDK。从Oracle官方网站下载JavaSEJDK,选择版本JDK8以上版本即可。

下面简单介绍下Neo4j在Linux和Windows的安装过程。首先去官网下载对应版本。解压之后,Neo4j应用程序有如下主要的目录结构:

  • bin目录:用于存储Neo4j的可执行程序;
  • conf目录:用于控制Neo4j启动的配置文件;
  • data目录:用于存储核心数据库文件;
  • plugins目录:用于存储Neo4j的插件。
Linux系统下的安装

通过tar解压命令解压到一个目录下:

tar-xzvfneo4j-community-3.3.1-unix.tar.gz

然后进入Neo4j解压目录:

cd/usr/local/neo4j/neo4j-community-3.1.0

通过启动命令,可以实现启动、控制台、停止服务:

bin/neo4jstart/console/stop(启动/控制台/停止)

通过cypher-shell命令,可以进入命令行:

bin/cypher-shell在Neo4j浏览器中创建节点和关系

下面,我们简单编写Cypher命令,Cypher命令可以通过Neo4j教程学习,在浏览器中通过Neo4j创建两个节点和两个关系。

在$命令行中,编写Cypher脚本代码,点击Play按钮完成创建,依次执行下面的语句:

CREATE(n:Person{name:'Andres',title:'Developer'})returnn;

作用是创建一个Person,并包含属性名字和职称。

enterimagedescriptionhere

下面这条语句也创建了一个Person对象,属性中只是名字和职称不一样。

CREATE(n:Person{name:'Vic',title:'Developer'})returnn;

紧接着,通过下面两行命令进行两个Person的关系匹配:

match(n:Person{name:"Vic"}),(m:Person{name:"Andres"})create(n)-[r:Friend]->(m)returnr;match(n:Person{name:"Vic"}),(m:Person{name:"Andres"})create(n)<-[r:Friend]-(m)returnr;

最后,在创建完两个节点和关系之后,查看数据库中的图形:

match(n)returnn;

如下图,返回两个Person节点,以及其关系网,两个Person之间组成Friend关系:

enterimagedescriptionhereNeo4j的Python操作

既然Neo4j作为一个图库数据库,那我们在项目中使用的时候,必然不能通过上面那种方式完成任务,一般都要通过代码来完成数据的持久化操作。其中,对于Java编程者来说,可通过SpringDataNeo4j达到这一目的。

而对于Python开发者来说,Py2neo库也可以完成对Neo4j的操作,操作过程如下。

首先安装Py2neo。Py2neo的安装过程非常简单,在命令行通过下面命令即可安装成功。

pipinstallpy2neo

安装好之后,我们来看一下简单的图关系构建,看下面代码:

frompy2neo.dataimportNode,Relationshipa=Node("Person",name="Alice")b=Node("Person",name="Bob")ab=Relationship(a,"KNOWS",b)

第一行代码,首先引入Node和Relationship对象,紧接着,创建a和b节点对象,最后一行匹配a和b之间的工作雇佣关系。接着来看看ab对象的内容是什么:

print(ab)

通过print打印出ab的内容:

(Alice)-[:KNOWS{}]->(Bob)

通过这样,就完成了Alice和Bob之间的工作关系,如果有多组关系将构建成Person之间的一个关系网。

了解更多Py2neo的使用方法,建议查看官方文档。

用Neo4j构建一个简单的农业知识图谱

我们来看一个基于开源语料的简单农业知识图谱,由于过程比较繁杂,数据和知识图谱数据预处理过程这里不再赘述,下面,我们重点看基于Neo4j来创建知识图谱的过程。

整个过程主要包含以下步骤:

环境准备语料准备语料加载知识图谱查询展示Neo4j环境准备。

根据上面对Neo4j环境的介绍,这里默认你已经搭建好Neo4j的环境,并能正常访问,如果没有环境,请自行搭建好Neo4j的可用环境。

本次提供的语料是已经处理好的数据,包含6个csv文件,文件内容和描述如下。

attributes.csv:文件大小2M,内容是通过互动百科页面得到的部分实体的属性,包含字段:Entity、AttributeName、Attribute,分别表示实体、属性名称、属性值。文件前5行结构如下:

Entity,AttributeName,Attribute密度板,别名,纤维板葡萄蔓枯病,主要为害部位,枝蔓坎德拉,性别,男坎德拉,国籍,法国坎德拉,场上位置,后卫

hudong_pedia.csv:文件大小94.6M,内容是已经爬好的农业实体的百科页面的结构化数据,包含字段:title、url、image、openTypeList、detail、baseInfoKeyList、baseInfoValueList,分别表示名称、百科URL地址、图片、分类类型、详情、关键字、依据来源。文件前2行结构如下:

"title","url","image","openTypeList","detail","baseInfoKeyList","baseInfoValueList""菊糖","http://www.baike.com/wiki/菊糖","http://a0.att.hudong.com/72/85/20200000013920144736851207227_s.jpg","健康科学##分子生物学##化学品##有机物##科学##自然科学##药品##药学名词##药物中文名称列表","[药理作用]诊断试剂人体内不含菊糖,静注后,不被机体分解、结合、利用和破坏,经肾小球滤过,通过测定血中和尿中的菊糖含量,可以准确计算肾小球的滤过率。菊糖广泛存在于植物组织中,约有3.6万种植物中含有菊糖,尤其是菊芋、菊苣块根中含有丰富的菊糖[6,8]。菊芋(Jerusalemartichoke)又名洋姜,多年生草本植物,在我国栽种广泛,其适应性广、耐贫瘠、产量高、易种植,一般亩产菊芋块茎为2000~4000kg,菊芋块茎除水分外,还含有15%~20%的菊糖,是加工生产菊糖及其制品的良好原料。","中文名:","菊糖""密度板","http://www.baike.com/wiki/密度板","http://a0.att.hudong.com/64/31/20200000013920144728317993941_s.jpg","居家##巧克力包装##应用科学##建筑材料##珠宝盒##礼品盒##科学##糖果盒##红酒盒##装修##装饰材料##隔断##首饰盒","密度板(英文:MediumDensityFiberboard(MDF))也称纤维板,是以木质纤维或其他植物纤维为原料,施加脲醛树脂或其他适用的胶粘剂制成的人造板材。按其密度的不同,分为高密度板、中密度板、低密度板。密度板由于质软耐冲击,也容易再加工,在国外是制作家私的一种良好材料,但由于国家关于高密度板的标准比国际标准低数倍,所以,密度板在中国的使用质量还有待提高。","中文名:##全称:##别名:##主要材料:##分类:##优点:","密度板##中密度板纤维板##纤维板##以木质纤维或其他植物纤维##高密度板、中密度板、低密度板##表面光滑平整、材质细密性能稳定"

hudong_pedia2.csv:文件大小41M,内容结构和hudong_pedia.csv文件保持一致,只是增加数据量,作为hudong_pedia.csv数据的补充。

new_node.csv:文件大小2.28M,内容是节点名称和标签,包含字段:title、lable,分别表示节点名称、标签,文件前5行结构如下:

title,lable药物治疗,newNode膳食纤维,newNodeBovenMerwede,newNode亚美尼亚苏维埃百科全书,newNode

wikidata_relation.csv:文件大小1.83M,内容是实体和关系,包含字段HudongItem1、relation、HudongItem2,分别表示实体1、关系、实体2,文件前5行结构如下:

HudongItem1,relation,HudongItem2菊糖,instanceof,化合物菊糖,instanceof,多糖瓦尔,instanceof,河流菊糖,subclassof,食物瓦尔,originofthewatercourse,莱茵河

wikidata_relation2.csv:大小7.18M,内容结构和wikidata_relation.csv一致,作为wikidata_relation.csv数据的补充。语料加载。

语料加载,利用Neo4j的LOADCSVWITHHEADERSFROM...功能进行加载,具体操作过程如下。

首先,依次执行以下命令:

//将hudong_pedia.csv导入LOADCSVWITHHEADERSFROM"file:///hudong_pedia.csv"ASlineCREATE(p:HudongItem{title:line.title,image:line.image,detail:line.detail,url:line.url,openTypeList:line.openTypeList,baseInfoKeyList:line.baseInfoKeyList,baseInfoValueList:line.baseInfoValueList})

执行成功之后,控制台显示成功:

enterimagedescriptionhere

上面这张图,表示数据加载成功,并显示加载的数据条数和耗费的时间。

//新增了hudong_pedia2.csvLOADCSVWITHHEADERSFROM"file:///hudong_pedia2.csv"ASlineCREATE(p:HudongItem{title:line.title,image:line.image,detail:line.detail,url:line.url,openTypeList:line.openTypeList,baseInfoKeyList:line.baseInfoKeyList,baseInfoValueList:line.baseInfoValueList})//创建索引CREATECONSTRAINTON(c:HudongItem)ASSERTc.titleISUNIQUE

以上命令的意思是,将hudong_pedia.csv和hudong_pedia2.csv导入Neo4j作为结点,然后对titile属性添加UNIQUE(唯一约束/索引)。

注意:如果导入的时候出现Neo4jJVM内存溢出错误,可以在导入前,先把Neo4j下的conf/neo4j.conf中的dbms.memory.heap.initial_size和dbms.memory.heap.max_size调大点。导入完成后再把值改回去即可。

下面继续执行数据导入命令:

//导入新的节点LOADCSVWITHHEADERSFROM"file:///new_node.csv"ASlineCREATE(:NewNode{title:line.title})//添加索引CREATECONSTRAINTON(c:NewNode)ASSERTc.titleISUNIQUE//导入hudongItem和新加入节点之间的关系LOADCSVWITHHEADERSFROM"file:///wikidata_relation2.csv"ASlineMATCH(entity1:HudongItem{title:line.HudongItem}),(entity2:NewNode{title:line.NewNode})CREATE(entity1)-[:RELATION{type:line.relation}]->(entity2)LOADCSVWITHHEADERSFROM"file:///wikidata_relation.csv"ASlineMATCH(entity1:HudongItem{title:line.HudongItem1}),(entity2:HudongItem{title:line.HudongItem2})CREATE(entity1)-[:RELATION{type:line.relation}]->(entity2)

执行完这些命令后,我们导入new_node.csv新节点,并对titile属性添加UNIQUE(唯一约束/索引),导入wikidata_relation.csv和wikidata_relation2.csv,并给节点之间创建关系。

紧接着,继续导入实体属性,并创建实体之间的关系:

LOADCSVWITHHEADERSFROM"file:///attributes.csv"ASlineMATCH(entity1:HudongItem{title:line.Entity}),(entity2:HudongItem{title:line.Attribute})CREATE(entity1)-[:RELATION{type:line.AttributeName}]->(entity2);LOADCSVWITHHEADERSFROM"file:///attributes.csv"ASlineMATCH(entity1:HudongItem{title:line.Entity}),(entity2:NewNode{title:line.Attribute})CREATE(entity1)-[:RELATION{type:line.AttributeName}]->(entity2);LOADCSVWITHHEADERSFROM"file:///attributes.csv"ASlineMATCH(entity1:NewNode{title:line.Entity}),(entity2:NewNode{title:line.Attribute})CREATE(entity1)-[:RELATION{type:line.AttributeName}]->(entity2);LOADCSVWITHHEADERSFROM"file:///attributes.csv"ASlineMATCH(entity1:NewNode{title:line.Entity}),(entity2:HudongItem{title:line.Attribute})CREATE(entity1)-[:RELATION{type:line.AttributeName}]->(entity2)

这里注意,建索引的时候带了label,因此只有使用label时才会使用索引,这里我们的实体有两个label,所以一共做2*2=4次。当然也可以建立全局索引,即对于不同的label使用同一个索引。

以上过程,我们就完成了语料加载,并创建了实体之间的关系和属性匹配,下面我们来看看Neo4j图谱关系展示。

知识图谱查询展示

最后通过cypher语句查询来看看农业图谱展示。

首先,展示HudongItem实体,执行如下命令:

MATCH(n:HudongItem)RETURNnLIMIT25

对HudongItem实体进行查询,返回结果的25条数据,结果如下图:

enterimagedescriptionhere

接着,展示NewNode实体,执行如下命令:

MATCH(n:NewNode)RETURNnLIMIT25

对NewNode实体进行查询,返回结果的25条数据,结果如下图:

enterimagedescriptionhere

之后,展示RELATION直接的关系,执行如下命令:

MATCHp=()-[r:RELATION]->()RETURNpLIMIT25

展示实体属性关系,结果如下图:

enterimagedescriptionhere总结

本节内容到此结束,回顾下整篇文章,主要讲了以下内容:

  • 解释了Neo4j被用来做知识图谱的原因;
  • Neo4j的简单安装以及在Neo4j浏览器中创建节点和关系;
  • Neo4j的Python接口操作及使用;
  • 从五个方面讲解了如何使用Neo4j构建一个简单的农业知识图谱。

最后,强调一句,知识图谱未来会通过自然语言处理技术和搜索技术结合应用会越来越广,工业界所出的地位也会越来越重要。

参考文献及推荐阅读