task03笔记

Datawhale 知识图谱组队学习 之 Task 3 Neo4j图数据库导入数据

特别鸣谢:QASystemOnMedicalGraph

目录

一、Neo4j简介

1.1 基本概念

Neo4j使用图相关的概念来描述数据模型,把数据保存为图中的节点以及节点之间的关系。数据主要由三部分构成:

  • 节点。节点表示对象实例,每个节点有唯一的ID区别其它节点,节点带有属性;
  • 关系。就是图里面的边,连接两个节点,另外这里的关系是有向的并带有属性;
  • 属性。key-value对,存在于节点和关系中

1.2 索引

  • 动机:Neo4j使用遍历操作进行查询。为了加速查询,Neo4j会建立索引,并根据索引找到遍历用的起始节点;
  • 介绍:默认情况下,相关的索引是由Apache Lucene提供的。但也能使用其他索引实现来提供。
  • 操作:用户可以创建任意数量的命名索引。每个索引控制节点或者关系,而每个索引都通过key/value/object三个参数来工作。其中object要么是一个节点,要么是一个关系,取决于索引类型。另外,Neo4j中有关于节点(关系)的索引,系统通过索引实现从属性到节点(关系)的映射。
  • 作用:
    • 查找操作:系统通过设定访问条件比如,遍历的方向,使用深度优先或广度优先算法等条件对图进行遍历,从一个节点沿着关系到其他节点;
    • 删除操作:Neo4j可以快速的插入删除节点和关系,并更新节点和关系中的属性。

1.3 Neo4j的优势

Neo4j 查询的高性能表现、易于使用的特性及其设计的灵活性和开发的敏捷性,以及坚如磐石般的事务管理特性,都充分说明了使用Neo4j是一个不错的选择。有关它的所有优点,总结起来,主要表现在以下几个方面。

  1. 闪电般的读/写速度,无与伦比的高性能表现;
  2. 非结构化数据存储方式,在数据库设计上具有很大的灵活性;
  3. 能很好地适应需求变化,并适合使用敏捷开发方法;
  4. 很容易使用,可以用嵌入式、服务器模式、分布式模式等方式来使用数据库;
  5. 使用简单框图就可以设计数据模型,方便建模;
  6. 图数据的结构特点可以提供更多更优秀的算法设计;
  7. 完全支持ACID完整的事务管理特性;
  8. 提供分布式高可用模式,可以支持大规模的数据增长;
  9. 数据库安全可靠,可以实时备份数据,很方便恢复数据;
  10. 图的数据结构直观而形象地表现了现实世界的应用场景。

二、Neo4j 数据导入

2.1 数据集简介

  • 数据源:39健康网。包括15项信息,其中7类实体,约3.7万实体,21万实体关系。

  • 本次组队学习搭建的系统的知识图谱结构如下:

知识图谱结构

图 2 知识图谱结构

  • 知识图谱实体类型

知识图谱实体类型

图 3 知识图谱实体类型

  • 知识图谱实体关系类型

知识图谱实体关系类型

图 4 知识图谱实体关系类型

  • 知识图谱疾病属性

知识图谱疾病属性

图 5 知识图谱疾病属性

  • 基于特征词分类的方法来识别用户查询意图

基于特征词分类的方法来识别用户查询意图

图 6 基于特征词分类的方法来识别用户查询意图

2.2 数据导入

    该项目是使用下方链接里的github项目文件运行的,数据均存放在data文件夹中,
    本节主要分析的build_graph.py文件导入使用的是disease.csv文件
    由于该代码是使用for循环读入的,因此需要导入数据的时间较慢
    除了windows环境下的导入约需2h,mac和linux系统下导入完成约小于1h
2.2.1 Neo4j 账号密码设置

要将 数据 导入 Neo4j 图数据库,首先需要 进入 build_graph.py 类中,在 类 MedicalGraph 中 的加入 本地 Neo4j 图数据库 的 账号和密码;

    class MedicalGraph:
        def __init__(self):
            ...
            self.graph = Graph("http://localhost:7474", username="neo4j", password="自己的")
            ...
2.2.2 导入 数据

运行 以下命令:

    python build_graph.py 

2.3 知识图谱展示

运行介绍之后,打开浏览器进入网址:http://localhost:7474/browser/,可以看到我们导入的数据的知识图谱

2.4 主体类 MedicalGraph 介绍

class MedicalGraph:
    def __init__(self):
        pass
    
    # 读取文件,获得实体,实体关系
    def read_file(self):
        psss
    # 创建节点
    def create_node(self, label, nodes):
        pass
    # 创建疾病节点的属性
    def create_diseases_nodes(self, disease_info):
        pass
    # 创建知识图谱实体
    def create_graphNodes(self):
        pass
    # 创建实体关系边
    def create_graphRels(self):
        pass
    # 创建实体关系边
    def create_relationship(self, start_node, end_node, edges, rel_type, rel_name):
        pass

2.5 主体类 MedicalGraph 中关键代码讲解

    1. 获取数据路径
    1. 链接 Neo4j 图数据库
    self.graph = Graph("http://localhost:7474", username="neo4j", password="自己设定的密码")
    1. for循环读取文件,获得实体,实体关系

这部分代码的核心就是读取 disease.csv 数据文件,使用的是文件列的信息,以此获取实体和实体关系信息。

  • 抽取的实体信息(列):
    • diseases 疾病
    • aliases 别名
    • symptoms 症状
    • parts 部位
    • departments 科室
    • complications 并发症
    • drugs 药品
  • 由函数建立实体之间的关系:
    • disease_to_symptom 疾病与症状关系
    • disease_to_alias 疾病与别名关系
    • diseases_to_part 疾病与部位关系
    • disease_to_department 疾病与科室关系
    • disease_to_complication 疾病与并发症关系
    • disease_to_drug 疾病与药品关系
  • disease 实体 属性信息:
    • name
    • age 年龄
    • infection 传染性
    • insurance 医保
    • checklist 检查项
    • treatment 治疗方法
    • period 治愈周期
    • rate 治愈率
    • money 费用

def read_file(self)
分析:用pandas读取完整文件,for循环处理DataFrame每一行的数据,取出每一行中各列的内容,如果属于disease的实体及其属性,统一存放在disease_dict字典中,最后将disease_dict一行的所有属性(key)对应的值(value)都存放在diseases_infos,其他抽取的实体信息单独存放在与疾病相关的关系列表中

  • 4.创建节点

这部分代码主要是为了创建不包含属性的 节点

def create_node(self, label, nodes):
使用graph.create()函数创建不同实体的node节点(diseases, aliases, symptoms, parts,departments, complications, drugs)
其中,Neo4j CQL的CREATE命令<==>graph.create(node)

  • 5.创建带有属性节点

def create_diseases_nodes(self, disease_info):
取出read_file()函数返回的diseases_info中disease相关的属性,创建属性的node节点

  • 6.创建知识图谱实体

def create_graphNodes(self)
调用create_node()函数创建实体节点

  • 7.创建知识图谱关系

def create_graphRels(self)
调用create_relationship函数创建实体之间的关系

  • 8.创建实体关系边
    def create_relationship(self, start_node, end_node, edges, rel_type, rel_name):
        """
        创建实体关系边
        :param start_node:
        :param end_node:
        :param edges:
        :param rel_type:
        :param rel_name:
        :return:
        """
        count = 0
        # 去重处理
        set_edges = []
        for edge in edges:
            set_edges.append('###'.join(edge))
        all = len(set(set_edges))
        for edge in set(set_edges):
            edge = edge.split('###')
            p = edge[0]
            q = edge[1]
            query = "match(p:%s),(q:%s) where p.name='%s'and q.name='%s' create (p)-[rel:%s{name:'%s'}]->(q)" % (
                start_node, end_node, p, q, rel_type, rel_name)
            try:
                self.graph.run(query)
                count += 1
                print(rel_type, count, all)
            except Exception as e:
                print(e)
        return    

Neo4j CQL MATCH命令<===>graph.run(MATCH命令) 查找
针对该函数的说明:

  • 传入的参数
  • start_node:“Disease”,
  • end_node:如"Alias"的相关实体,
  • edges: 如rel_alias, 其中拆取的q代表"Disease", p代表如"Alias"的相关实体,
  • rel_type:如"ALIAS_IS"的连接关系,rel_name:"别名"为连接的关系实体名
  • query = “match(p:%s),(q:%s) where p.name=’%s’and q.name=’%s’ create §-[rel:%s{name:’%s’}]->(q)”
    相当于match(p:‘disease’),(q:‘alias’) where p.name='disease’and q.name=‘alias’ create §-[rel:‘ALIAS_IS’{name:‘别名’}]->(q)

参考资料

  1. QASystemOnMedicalGraph
  2. 韩浩明.图数据库系统研究综述[J].计算机光盘软件与应用,2014,17(23):14-15.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值