当前位置:   article > 正文

基于neo4j图谱搭建问答系统_基于neo4j的水稻病虫害问答系统

基于neo4j的水稻病虫害问答系统

前言

承接前文,本文介绍如何根据已有的neo4j图谱来搭建一个简单的问答系统
ps:因为是基于neo4j图谱的,所以这个问题必须是在图谱中有答案才能进行回答。
完整项目github地址:https://github.com/Chtholly1/KG-and-QA-demo

正文

问答系统是NLP中最复杂的场景之一,根据查阅资料和个人的理解,一个简单的问答系统至少需要包含以下三个部分:

  1. 问题分类
  2. 关键词抽取
  3. neo4j查询

以下分别对这三部分进行介绍:

问题分类

当一个问句过来的时候,我们首先要对其进行初步的分类,比如:

问题:伊利丹·怒风的称号是什么?
解析提问的类别:title
问题:伊利丹·怒风的种族是什么?
解析提问的类别:race
  • 1
  • 2
  • 3
  • 4

这是一个典型的分类问题,我们一般有两种方法:
1.模板匹配:
比如说对于第一个问题,他的模板就应该是

xx的称号是什么?
  • 1

对于每个类别我们都可以枚举一些常见的模板,如:

#race
xx是什么族的
xx是什么种族的
xx的种族是什么
xx是啥族的
xx是啥种族的
xx的种族是啥
xx是xx族的吗
xx族有哪些人
xx族有哪些角色
哪些人是xx族的
哪些角色是xx族的
哪些是xx族的

#group
xx是什么势力的
xx的势力是什么
xx是啥势力的
xx的势力是啥
xx是xx势力的吗
xx势力有哪些人
xx势力有哪些角色
哪些人是xx势力的
哪些角色是xx势力的
哪些是xx势力的

#title
xx的头衔是什么
xx的称号是什么
xx被誉为什么
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

匹配模板也有两种思路:

  • "完美匹配"法,即模板在去掉"xx"等字符后,应该是提问的一个严格子串
  • 关键词匹配法,即只需要出现模板的一些关键词就认为模板匹配成功

显然第一种方法准确率更高,但召回率更低。
2.模型分类
分类问题当然能由经典的NLP模型来解决,自不必多说。
关键就是样本的构造和收集。
一个比较常规的思路就是

  1. 自己先构造一些常见模板,然后把模板的xx部分填充成真实的实体作为样本进行初步的训练,得到一个分类模型。
  2. 模型上线后,把用户的真实的提问作为新增样本,不断迭代分类模型。
关键词抽取

判断问题的所属类别以后,我们还需要知道用来查询的关键词,

问题:伊利丹·怒风的称号是什么?
解析提问的类别:title
  • 1
  • 2

如上,虽然知道了在问称号,但我们需要知道在问谁(伊利丹怒风)的称号。
关键词抽取的方法其实和分类问题是差不多的,一是模板匹配,二是NER模型。
初级阶段来说,模板匹配就能做的比较好了,因为关键词的集合是图谱中存在的有限集,而且发生语义的歧义的可能性也很小。
由此我们便完成了第二步:关键词抽取。

neo4j查询

理解问题后,我们最后还需要把理解的内容转换成neo4j支持的查询语言。
首先介绍一个概念,neo4j本质上是由"节点"和"关系"组成,而每个"节点"又可以具有多个"属性"。

简单提问

细心的同学应该发现了,就算在"race"这个大类下,其中还是存在两种不同的提问方式:

1.xx是什么种族的
2.xx种族有哪些角色。
  • 1
  • 2

显然这两个提问的结果是不一样的,所以对应的查询语言也不一致。
本质上这里还需要再做一个分类。在这里可以用一个比较取巧的方法:

当xx是一个角色名的时候,触发第一种查询方式。
当xx是一个种族名的时候,触发第二种查询方式。
  • 1
  • 2

一般来说,基于图谱来查询的话,简单的提问的结构是比较固定的,一般也就分为三种:

  1. A(节点)的"某个属性"/"某个关系"是什么?
  2. “某个属性”/"某个关系"为x的"节点"是什么?
  3. A(节点)和B(节点)的关系是什么?

所以对于确定好的大类的提问而言,大部分都可以分到这三种结构下面。

复杂提问

但在实际中问题可能要复杂很多,比如说复合问题:

1.种族为兽人且性别为男的角色有哪些?
2.麦迪文的徒弟的徒弟是谁?
  • 1
  • 2

对于复合问题,一个常规的想法就是问题拆解。
比如说第一个提问就可以拆解成两个简单提问并进行求交。
另外比较前沿的方法就是text2sql,顾名思义就是用模型把自然语言转换成查询语句的,因为是端到端的所以十分便利,但目前该技术准确率还不够高,感兴趣的读者可以自己去了解学习。

除了复合问题以外,还存在其他类型的复杂提问。总之问答系统是一个对技术和业务能力都有一定要求的复杂场景,而且落地和维护也较为繁琐。

展示

最后还是直观的展示下几个步骤,首先是代码

import re
import sys

from py2neo import Graph
from template_method import TempMethod

#链接neo4j图谱
graph = Graph("http://localhost:7474/", auth=("neo4j", '123456'))

#加载问题模板
c = TempMethod(graph, 'D:/NLP相关/知识图谱/wow/code/wow/question_template.txt')

#本次的问题
question = '伊利丹·怒风的种族是什么?'
print("提问:\n%s\n"%(question))
#判断问题的大类
question_type = c.match(question)
print("类别:\n%s\n"%(question_type))
#根据问题及分类进行关键词提取,并生成答案
query_res_list = c.generate_answer(question_type, question)
print()
#打印答案
print("答案:")
for query_res in query_res_list:
    for d in query_res.data():
        for key, val in d.items():
            sys.stdout.write(val+"、")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

输出效果:

提问:
伊利丹·怒风的种族是什么?

类别:
race

关键词提取:
['伊利丹·怒风']
['伊利丹']
答案:
恶魔、暗夜精灵(前)、
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/584461
推荐阅读
相关标签
  

闽ICP备14008679号