# 利用Neo4j+Elasticsearch制作新冠肺炎疫情聊天机器人 **Repository Path**: BentoMan/Chatbot ## Basic Information - **Project Name**: 利用Neo4j+Elasticsearch制作新冠肺炎疫情聊天机器人 - **Description**: 该项目利用Neo4j和ElasticSearch制作了一个关于新冠肺炎疫情的聊天机器人,旨在解决许多人关于新冠肺炎疫情的小疑问。 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 10 - **Forks**: 5 - **Created**: 2020-11-20 - **Last Updated**: 2025-07-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 利用Neo4j+Elasticsearch制作新冠肺炎疫情聊天机器人 #### 介绍 该项目利用Neo4j和ElasticSearch制作了一个关于新冠肺炎疫情的聊天机器人,旨在解决许多人关于新冠肺炎疫情的小疑问。 #### 使用工具 **1.Neo4j** Neo4j是一个高性能的,NOSQL图形数据库,保存的数据主要为以下形式。 ![Neo4j](https://images.gitee.com/uploads/images/2020/1123/113019_579c41bd_7878388.png "屏幕截图.png") **2.ElasticSearch** 通过[Elasticsearch](http://https://www.elastic.co/cn/elasticsearch/),我们能够非常快速地执行及合并多种类型的搜索(结构化数据、非结构化数据、地理位置、指标)。 本项目通过ElasticSearch的搜索方式,开发了实体检索、实体的属性检索、多跳查询、根据属性值查询实体这四种功能。 **3.Jieba** 中文分词工具 **4.Vue** Vue是一套用于构建用户界面的渐进式框架。 本项目使用Vue框架来搭建前端。 **5.Django** Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。 使用 Django,只要很少的代码,Python 的程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容,并进一步开发出全功能的 Web 服务。 本项目使用Django搭建后端,并实现前后端分离。 **6.腾讯智能闲聊api** 为了让我们的聊天功能更加全面,我们在自身实现新冠肺炎智能问答的同时,通过调用腾讯的闲聊api,实现闲聊功能。 #### 功能介绍 **1.实体检索** **实体检索即输入实体名称,返回该实体的所有属性和属性值。** 示例输入:新冠病毒、新冠肺炎、密切接触者 ![实体检索](https://images.gitee.com/uploads/images/2020/1123/135734_a2a3ffe9_7878388.png "屏幕截图.png") **2.实体的属性检索** **输入实体名称和一个属性名称,如果该实体存在该属性值,则返回该属性值。** 示例输入:新冠肺炎的传染源、购物的注意事项有哪些、疫情期间感到焦虑怎么办 ![实体的属性检索](https://images.gitee.com/uploads/images/2020/1123/140246_a1858ee8_7878388.png "屏幕截图.png") **3.多跳查询** **多跳查询即形如"姚明的女儿的身高"的查询,即"姚明:女儿"查询得到的是实体"姚明"的一个属性。** **但同时这个属性值也作为一个实体存在于数据集中,那么就可以接着对该实体继续查询其属性。** 示例输入:广东的省会的感染人数 ![多跳查询](https://images.gitee.com/uploads/images/2020/1123/140734_1e2a07d0_7878388.png "屏幕截图.png") **4.根据属性值查询其实体** **输入隐含多对 [属性名 operator 属性值]的自然语言问句, 它们之间的关系可以是 AND,OR,NOT,** **同时属性值可以是等于,大于,小于一个输入值,返回满足这些属性限制的实体。** 示例输入:累计确诊超过 1500 的中国省份或美国州 ![根据属性值查询其实体](https://images.gitee.com/uploads/images/2020/1123/141407_dd94d96c_7878388.png "屏幕截图.png") **5.模糊匹配** **同一个问题有多种问法,我们设置同义词库将问题映射成标准问法,从而可以在 Elasticsearch 搜索** 示例输入:新冠病毒是如何传播的、新冠病毒怎么传播、新冠病毒的传播路径 三种输入会映射成一种问法: **新冠病毒的传播方式** ![模糊匹配1](https://images.gitee.com/uploads/images/2020/1123/141809_9d5de7bb_7878388.png "屏幕截图.png") ![模糊匹配2](https://images.gitee.com/uploads/images/2020/1123/141856_821f427f_7878388.png "屏幕截图.png") **6.闲聊模式** **为了保证问答机器人对答的流畅性,我们加入了腾讯智能闲聊机器人的 API。当搜索不到问题的答案时,则调用闲聊机器人 API。** ![闲聊模式](https://images.gitee.com/uploads/images/2020/1123/142114_91d8fb16_7878388.png "屏幕截图.png") #### 项目流程 **1.数据准备** **1.1从[openKG](http://openkg.cn/group/coronavirus)中拿到新冠肺炎疫情的三元组数据,并导入到neo4j中,效果图如下。** **1.2爬取丁香园、世界卫生组织官网关于新冠肺炎的问答集** ![爬取结果](https://images.gitee.com/uploads/images/2020/1123/145425_53b46f59_7878388.png "屏幕截图.png") **1.3将Neo4j的数据和爬取到的问答集转成三元组格式(实体名:属性名:属性值)** ![三元组](https://images.gitee.com/uploads/images/2020/1123/145607_6ce6ab09_7878388.png "屏幕截图.png") **1.4将三元组数据集转换为json格式** Elasticsearch 要求文档的输入格式为 json。将实验数据集转化为 json 格式后,每个实体 对应一个 json 的 object,也即 Elasticsearch 中的一个文档。 ![json格式](https://images.gitee.com/uploads/images/2020/1123/150023_bdf3dd95_7878388.png "屏幕截图.png") **1.5属性同义词拓展** 为了确保能够进行模糊匹配,下面的文件中每一行的第一个词为数据中存在的属性,后面的为后来添加的同义的属性词。 在解析查询语句的时候,如遇到同义的属性词,可将其映射到数据集中存在的属性上。 ![同义词拓展](https://images.gitee.com/uploads/images/2020/1123/152035_64b6d51a_7878388.png "屏幕截图.png") **2.导入Elasticsearch** **2.1导入准备** 在将数据集导入 elasticsearch 之前,需要考虑其在 elasticsearch 中存储的方式。 ![json格式](https://images.gitee.com/uploads/images/2020/1123/150023_bdf3dd95_7878388.png "屏幕截图.png") 2.1.1其中,所有属性除了"确诊人数"这个属性之外,都存在一个名为"po"的 list 对象中。 每个属性及其属性值作为一个小的 object,分别用键"pred"和"obj"来标识属性名和属性值。 2.1.2之所以要将"确诊人数"单独考虑,而不是和其它属性一样也存储在 list 中,是因为这个属性要支持范围搜索,即"确诊人数>1000"这样的搜索。 因此要求它们在存储时的数据类型为 integer,而 list 中的所有属性的属性值的存储类型都为 keyword(不分词的 string,只支持全文匹配) 2.1.3之所以每一对(属性名,属性值)存储为一个 object,并放入一个 list 中,是因为这是 elasticsearch 定义的一种 nested object 的数据类型。 这种数据类型能存储大量拥有相同的 key 的对象,并且可以对之进行有效的检索。这样,不论数据集中有多少种种类不同的属性,都可以以相同的格式存储。 2.1.4之所以不是每一个三元组存储为一篇文档,而是一个实体相关的所有属性及属性值存储为一篇文档。 是因为要支持通过多对(属性,属性值)联合检索满足要求的实体,以这种格式存储,能提高检索效率。 示例:新冠肺炎病毒的传入源和传出源是什么? **2.2数据导入** 我们通过命令行,使用 Elasticsearch 中的 Bulk 进行批量导入,将特定处理好的数据导入到 ElasticSearch 中,具体格式如下例。 ![数据导入](https://images.gitee.com/uploads/images/2020/1123/160957_2a6692bc_7878388.png "屏幕截图.png") **3.自然语言转化为 Logical form** **3.1解析自然语言** 首先,对于输入的自然语言问句,识别出其中出现在知识库中的实体名,属性名以及属性值识别的流程如下。 **3.1.1分词** 分词工具例如 jieba 分词支持自定义词典,可以将分词算法的词典替换成所有实体名,根据实体名对自然语言问句进行分词处理。 **3.1.2从知识库中匹配属性** **3.1.3从知识库中匹配实体** **3.1.4从知识库中匹配属性值** **3.2生成Logical Form** 在识别出查询中所有的实体名,属性名和属性值后,依据它们的数目及位置,确定查询的类型,以便映射到的对应的logical form。 ![Logical Form](https://images.gitee.com/uploads/images/2020/1123/163302_22d9582d_7878388.png "屏幕截图.png") **3.3Logical form 翻译成 ES 查询语句** ![ES语句](https://images.gitee.com/uploads/images/2020/1123/163857_29536d7c_7878388.png "屏幕截图.png") **4.模型优化** **4.1模糊匹配** 每个人聊天风格千差万别,如何做到不同的人搜索都能得到正确答案,因此,在这里使用了模糊匹配的方式进行识别。 ![模糊匹配1](https://images.gitee.com/uploads/images/2020/1123/141809_9d5de7bb_7878388.png "屏幕截图.png") ![模糊匹配2](https://images.gitee.com/uploads/images/2020/1123/141856_821f427f_7878388.png "屏幕截图.png") **4.2闲聊机器人Api** 若数据库中无用户问题答案,COVID-19知识问答机器人应如何作出响应,因此,我们调用了腾讯闲聊机器人Api,帮助我们的聊天更加多样化。 ![闲聊模式](https://images.gitee.com/uploads/images/2020/1123/142114_91d8fb16_7878388.png "屏幕截图.png") **5.代码地址** **https://github.com/Hefan-scut/COVID-19-Chatbot/** **6.项目展望** 可以使用 **NER和NRE模型** 对三元组数据进行实体识别和关系提取,转换成三元组,动态训练,动态输入,变成一个可以接受环境变化的聊天机器人。