知识图谱小鲸鱼队之 Task 1 知识图谱介绍

知识图谱

“知识图谱本质上是语义网络(Semantic Network)的知识库”。但这有点抽象,换个角度,从实际应用的角度出发其实可以简单地把知识图谱理解成多关系图(Multi-relational Graph)。从语言中提取关键信息,省略不必要的词,将关键信息及其联系进行可视化(多关系图),形成图谱,从而获取相关知识。

多关系图

多关系图是一种图,图在数据结构中的定义是由节点(Vertex)和边(Edge)来构成,但这些图通常只包含一种类型的节点和边。而多关系图一般包含多种类型的节点和多种类型的边。

实体

在知识图谱中,我们通常用“实体(Entity)”来表达图里的节点、用“关系(Relation)”来表达图里的“边”。

知识图谱的价值

知识图谱是人工智能很重要的一个分支, 人工智能的目标为了让机器具备像人一样理性思考及做事的能力 -> 在符号主义的引领下,知识工程(核心内容即建设专家系统)取得了突破性的进展 -> 在整个知识工程的分支下,知识表示是一个非常重要的任务 -> 而知识图谱又恰恰是知识表示的重要一环。

搜索领域的Google搜索、百度搜索,社交领域的领英经济图谱,企业信息领域的天眼查企业图谱等都涉及知识图谱。

交叉研究包含有:自然语言处理与语义web、数据挖掘、机器学习、知识表示与推理、认知计算、信息检索与抽取。

怎么构建知识图谱呢?

知识图谱的构建过程分为四个功能模块:分别是数据获取、信息获取、知识融合和知识处理。

数据获取

数据源主要来自两种渠道:

第一种:业务本身的数据。这部分数据通常包含在公司内的数据库表并以结构化的方式存储,一般只需要简单预处理即可以作为后续AI系统的输入;
第二种:网络上公开、抓取的数据。这些数据通常是以网页的形式存在所以是非结构化的数据,一般需要借助于自然语言处理等技术来提取出结构化信息。

信息获取

信息获取分为三个关键技术:实体提取、关系提取和属性提取。这也是多关系图的性质及知识图谱的一个非常重要的概念Schema所要求的。

知识融合

知识融合就是把“信息获取”过程中得到的散乱信息整合起来。它分为两个部分,实体链接和知识合并。

知识处理

知识处理主要包括三个关键技术:本体构建、知识推理和质量评估。

知识图谱的具体构建技术

实体关系识别技术(Named Entity Recognition)

从文本里提取出实体并对每个实体做分类/打标签

关系抽取技术(Relation Extraction)

将实体间的关系从文本中提取出来

实体统一(Entity Resolution)

对于有些实体写法上不一样,但其实是指向同一个实体。其不仅可以减少实体的种类,也可以降低图谱的稀疏性(Sparsity)。

指代消解(Disambiguation)

文本中出现的“it”, “he”, “she”这些词到底指向哪个实体

知识图谱的存储

知识图谱主要有两种存储方式:

  • 一种是基于RDF的存储;
  • 另一种是基于图数据库的存储。

区别:

RDF图数据库
数据的易发布以及共享高效的图查询和搜索
三元组的方式来存储数据以属性图为基本的表示形式
不包含属性信息包含属性,更容易表达现实的业务场景
标准的推理引擎没有标准的推理引擎

其中Neo4j系统目前仍是使用率最高的图数据库,它拥有活跃的社区,而且系统本身的查询效率高,但唯一的不足就是不支持准分布式。相反,OrientDB和JanusGraph(原Titan)支持分布式,但这些系统相对较新,社区不如Neo4j活跃,这也就意味着使用过程当中不可避免地会遇到一些刺手的问题。如果选择使用RDF的存储系统,Jena或许一个比较不错的选择。

Neo4j

Neo4j采用的是Cypher图形查询语言,允许用户不必编写图形结构的遍历代码,就可以对图形数据进行高效的查询。
设计目的:类似SQL,适合于开发者以及在数据库上做点对点模式(ad-hoc)查询的专业操作人员。
其具备的能力包括:
创建、更新、删除节点和关系
通过模式匹配来查询和修改节点和关系 - 管理索引和约束等

Neo4j实战

1. 创建节点

  1. 删除数据库中以往的图,确保一个空白的环境进行操作【注:慎用,如果库内有重要信息的话】:
MATCH (n) DETACH DELETE n';

在这里插入图片描述

  1. 创建一个人物节点:
  CREATE (n:Person {name:'John'}) RETURN n

CREATE是创建操作,Person是标签,代表节点的类型。
花括号{}代表节点的属性,属性类似Python的字典。
这条语句的含义就是创建一个标签为Person的节点,该节点具有一个name属性,属性值是John。

创建完一个人物实体后,会出现结果,点击左边一列的Graph即可看到创建的任务实体John:在这里插入图片描述

  1. 创建更多的人物节点,并分别命名:
  CREATE (n:Person {name:'Sally'}) RETURN n;
  CREATE (n:Person {name:'Steve'}) RETURN n;
  CREATE (n:Person {name:'Mike'}) RETURN n;
  CREATE (n:Person {name:'Liz'}) RETURN n;
  CREATE (n:Person {name:'Shawn'}) RETURN n;

在这里插入图片描述
创建成功后,这时候发现看不到上面的图了,这时候可以查看网页左边的Database Information中的Node Labels,点击Person旁边的即可出现类似创建一个任务后的结果。
在这里插入图片描述
接着点击Graph出现创建的6个人物实体:
在这里插入图片描述

  1. 创建地区节点
  CREATE (n:Location {city:'Miami', state:'FL'})
  CREATE (n:Location {city:'Boston', state:'MA'})
  CREATE (n:Location {city:'Lynn', state:'MA'})
  CREATE (n:Location {city:'Portland', state:'ME'})
  CREATE (n:Location {city:'San Francisco', state:'CA'})

再次查看Database Information中的Node Labels,发现新增了Location属性。
感兴趣的同学也可以试试点击Node Labels下三个不同的东西,看看有什么结果,我就不剧透咯~
得到的图如下:
在这里插入图片描述

2. 创建关系

  1. 朋友关系
  MATCH (a:Person {name:'Liz'}), 
        (b:Person {name:'Mike'}) 
  MERGE (a)-[:FRIENDS]->(b)

方括号[]即为关系,FRIENDS为关系的类型。
注意这里的箭头–>是有方向的,表示是从a到b的关系。 这样,Liz和Mike之间建立了FRIENDS关系

  1. 关系增加属性
  MATCH (a:Person {name:'Shawn'}), 
        (b:Person {name:'Sally'}) 
  MERGE (a)-[:FRIENDS {since:2001}]->(b)
  1. 增加更多的朋友关系
  MATCH (a:Person {name:'Shawn'}), (b:Person {name:'John'}) MERGE (a)-[:FRIENDS {since:2012}]->(b)
  MATCH (a:Person {name:'Mike'}), (b:Person {name:'Shawn'}) MERGE (a)-[:FRIENDS {since:2006}]->(b)
  MATCH (a:Person {name:'Sally'}), (b:Person {name:'Steve'}) MERGE (a)-[:FRIENDS {since:2006}]->(b)
  MATCH (a:Person {name:'Liz'}), (b:Person {name:'John'}) MERGE (a)-[:MARRIED {since:1998}]->(b)

于是点击左边栏中的Relationship Types下的东西得到:
在这里插入图片描述

3. 创建出生地点

建立不同类型节点之间的关系-人物和地点的关系

  MATCH (a:Person {name:'John'}), (b:Location {city:'Boston'}) MERGE (a)-[:BORN_IN {year:1978}]->(b);
  MATCH (a:Person {name:'Liz'}), (b:Location {city:'Boston'}) MERGE (a)-[:BORN_IN {year:1981}]->(b);
  MATCH (a:Person {name:'Mike'}), (b:Location {city:'San Francisco'}) MERGE (a)-[:BORN_IN {year:1960}]->(b);
  MATCH (a:Person {name:'Shawn'}), (b:Location {city:'Miami'}) MERGE (a)-[:BORN_IN {year:1960}]->(b);
  MATCH (a:Person {name:'Steve'}), (b:Location {city:'Lynn'}) MERGE (a)-[:BORN_IN {year:1970}]->(b)

创建节点的时候就建好关系

  CREATE (a:Person {name:'Todd'})-[r:FRIENDS]->(b:Person {name:'Carlos'})

最终形成图谱:
在这里插入图片描述

4. 图数据库查询

  1. 查询下所有在Boston出生的人物
  MATCH (a:Person)-[:BORN_IN]->(b:Location {city:'Boston'}) RETURN a,b

在这里插入图片描述
2. 查询所有对外有关系的节点

  MATCH (a)--() RETURN a

在这里插入图片描述
3. 查询所有有关系的节点,以及关系类型(type®)

  MATCH (a)-[r]->() RETURN a.name, type(r)

在这里插入图片描述
这里不清楚为什么,出不了图

  1. 查询所有有结婚关系的节点
  MATCH (n)-[:MARRIED]-() RETURN n

在这里插入图片描述
5. 查找某人的朋友的朋友

  MATCH (a:Person {name:'Mike'})-[r1:FRIENDS]-()-[r2:FRIENDS]-(friend_of_a_friend) RETURN friend_of_a_friend.name AS fofName

在这里插入图片描述

通过 Python 操作 Neo4j

neo4j模块:执行CQL ( cypher ) 语句

  # step 1:导入 Neo4j 驱动包
  from neo4j import GraphDatabase
  # step 2:连接 Neo4j 图数据库
  driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password")) 
  # 密码是重新设置的,记得改过来
  # 添加 关系 函数
  def add_friend(tx, name, friend_name):
      tx.run("MERGE (a:Person {name: $name}) "
            "MERGE (a)-[:KNOWS]->(friend:Person {name: $friend_name})",
            name=name, friend_name=friend_name)
  # 定义 关系函数
  def print_friends(tx, name):
      for record in tx.run("MATCH (a:Person)-[:KNOWS]->(friend) WHERE a.name = $name "
                          "RETURN friend.name ORDER BY friend.name", name=name):
          print(record["friend.name"])
  # step 3:运行
  with driver.session() as session:
      session.write_transaction(add_friend, "Arthur", "Guinevere")
      session.write_transaction(add_friend, "Arthur", "Lancelot")
      session.write_transaction(add_friend, "Arthur", "Merlin")
      session.read_transaction(print_friends, "Arthur")

输出结果:
在这里插入图片描述

py2neo模块:通过操作python变量,达到操作neo4j的目的

  # step 1:导包
  from py2neo import Graph, Node, Relationship
  # step 2:构建图
  g = Graph()
  # step 3:创建节点
  tx = g.begin()
  a = Node("Person", name="Alice")
  tx.create(a)
  b = Node("Person", name="Bob")
  # step 4:创建边
  ab = Relationship(a, "KNOWS", b)
  # step 5:运行
  tx.create(ab)
  tx.commit()

在执行代码的时候遇到了一点小问题创建Graph不成功,于是找到以下解决办法:

g = Graph(“bolt://localhost:7687”, user=“neo4j”, password=“password”)

输出结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值