写在前面
虽然网上有很多代码和论文,但我甚至找不到一个基于知识库的问答系统来实现逻辑的简单介绍。 当然,我找到了一个基于模板匹配的博客,见: https://blog.csdn.net/xyz1584172808/article/details/89319129(写得很好,整个问答系统的建设过程都很清楚。 然而,与基于知识库的问答相比,他的文章要少得多。我首先总结了他简单的实现过程,然后扩展到基于知识库的问答系统。
基于模板匹配的问答系统:
主要阶段有:
- 实体识别
- 多分类用户问题,实现用户自然语言问题→形式化问题模板
- 将实体识别作为问题模板的实参,到图数据库中查询问题的答案。
实体识别阶段:
比如刘德华演过哪些电影? 将其命名为实体识别后,就可以得到:刘德华nnt”,nnt其实是人的词性,
向模板映射用户自然语言问题:
例如某dict以下模板保存在中间(nm代表电影,nnt代表人物,ng代表电影类型,nnr不知道是什么): 0:nm 评分 1:nm 上映时间 2:nm 类型 3:nm 简介 4:nm 演员列表 5:nnt 介绍 6:nnt ng 电影作品 7:nnt 电影作品 8:nnt 参演评分 大于 x 9:nnt 参演评分 小于 x 10:nnt 电影类型 11:nnt nnr 合作 电影列表 12:nnt 电影数量 13:nnt 出生日期 刘德华演过些电影?”这个问题,他可以转化成模板7,也就是nnt 电影作品。我们将此转化为多分类问题,具体流程如下:首先可以使用cnn(或lstm什么都行)对刘德华演过什么电影?提取特征,连接全连接层,用这14个分类做一个loss,反向传播。同样,输入另一段训练语料,如刘德华出生日期,也可以作为训练语料。这样就可以训练一个模型,
这里共有14个问题模板 比如刘德华演过什么电影?在这个问题上,我们可以通过将其输入到我们刚刚训练过的模型中来获得相应的模板类型,即7。(当然,预测结果甚至可能是2、3这样的主语nm而不是nt是的,我们可以在这个时候做出限制。因为我们通过了ner能得到刘德华演过哪些电影?刘德华这个实体,也可以知道刘德华对应的实体类型是nnt,然后我们就可以只带了nnt选择预测概率最高的模板)
将实体传输到模板中,用图数据库查询答案:
比如刘德华演过什么电影?,通过以上步骤,我们可以得到模板nnt 刘德华演过什么电影?这句话中的实体刘德华(nnt),于是可以将nnt对应的刘德华填入模板nnt 电影作品”中,就可以得到一条查询语句“刘德华 电影作品,用图数据库查询句子就是
SELECT ?x WHERE { <刘德华> <参演电影> ?x }
非常像一条sql语句。 然后你可以找到刘德华主演的所有电影
上述方案的缺点:
- 假如模板库中有很多模板,那么分类的数量就会很大,而且
- ,可扩展性很差
- 实体种类很多,如果实体种类不能单独用词性标记,就不能使用上述方案的词性标记。例如,如果我想在计算机领域回答问题,二叉树不能简单地使用一个词性n”来指代。
新方案
以下方案将解决上述问题
工业环境下真实场景分析:
- ,比如PKUBASE知识库,包含了包含130万以上实体,涉及的实体类型有各方各面(军人、工人、电影、电视剧……),到目前为止,还没有统一的实体标准(如上述词性标记)来对实体进行大的分类。例如,一部电影:我们可以知道这部电影有一个共同的属性,如名字、谁参与了它、得分等,但如果一部电影有良好的社会影响呢?然后你必须把良好的社会影响添加到电影的属性中,那么其他属性或关系呢?然后你必须在电影的属性中添加良好的社会影响,那么其他属性或关系呢?(这些都是我自己说的,你可以理解)。,
- 但是!!,还有很多情况,比如:, 就像这样,例如,北京大学明确指向北京大学_(北京最强大的大学之一),而不仅仅是指北京大学 的问题了
解决方案
实体识别(此时没有实体链接):
继续使用bert-ner,比如阿根廷国家的政策是什么?,阿根廷国家的实体可以提取出来
实体链接:
现在,网络上实际上有实体链接词典来解决别名问题
- 阿根廷 阿根廷_(国家)
- 阿根廷 阿根廷_(足球国家队)
- 阿根廷 阿根廷_(篮球国家队)
- 阿根廷 阿根廷_(贸易组织成员)
- 阿根廷国家队 阿根廷_(足球国家队)
- 阿根廷国家队 阿根廷_(篮球国家队)
- 阿根廷国家队 阿根廷_(贸易组织成员)
说明一下: 第一列是实体名称,第二列是实体名称可能指向的具体(具体到类型)实体。其实我们可以解决别名(指代消解)的问题,但实际上我们还没有解决实体链接的问题。比如阿根廷打好球,用bert进行ner当我们得到阿根廷时,很容易知道阿根廷代表阿根廷。_(足球国家队),但机器直接看这句话是不知道的
- 阿根廷 阿根廷_(国家)
- 阿根廷 阿根廷_(足球国家队)
- 阿根廷 阿根廷_(篮球国家队)
- 阿根廷 阿根廷_(贸易组织成员) 选择哪一个。 这就要求我们进行物理链接:首先,我们可以在阿根廷踢了一个好球这句话中得到阿根廷,然后我们可以从物理链接库中得到所有物理名称阿根廷的指令
- 阿根廷 阿根廷_(国家)
- 阿根廷 阿根廷_(足球国家队)
- 阿根廷 阿根廷_(篮球国家队)
- 阿根廷 阿根廷_(贸易组织成员)
接下来,我们可以选择 ①:首先用cnn分别扫描阿根廷红场之战在哪一年踢?和阿根廷_(国家)这几个字,做一个字pairwise(模型),输出相似度。 然后分别扫描阿根廷踢好球和阿根廷_(足球国家队),输出相似性,依次类推(我就不说训练过程的设计了,可以用esim等模型) ②,它还制作文本相似性模型和特征。详细的特征取决于论文(lgb论文中最最好的,高于pairwise)
提取和链接属性
本文采用规则 模板匹配的方式,如1997年8月,将其转换为知识库中的标准格式,如1997年8月,然后匹配知识库中的所有属性(见论文)
使用文本相似度匹配模型选择候选查询路径
通过实体识别和实体链接,我们可以分析徐峥主演的电影有哪些?,得到徐峥_(演员)这个具体的实体,然后我们可以从知识库中带来徐峥_例如,所有的三元组(演员) (徐峥_(演员),表演,股票的颜色_(电影)) (徐峥_(演员),主演,春光灿烂的猪八戒_(电影))(徐峥_(演员),出演,爱情呼叫转移_(电影)) (徐峥_(演员),出演,夜店_(电影)) (徐峥_(演员),获得奖项,电影频道传媒大奖_(奖项)) (徐峥_(演员),获得奖项,电影金马奖最佳男主角_(奖项)) (徐峥_(演员),导演,我和我的祖国_(电影)) 只将"徐峥_(演员)"对应的所有关系拿出来 然后可以用esim(pairwise模型)去将"徐峥出演的电影有哪些"与“徐峥出演了”进行比对**(此处请注意,深度模型的输入一般都是自然语言,像(徐峥,出演)是不可以直接输入进模型的,需要将(徐峥,出演)转换为自然语言,即“徐峥出演了”)**,输出相似度。 接下来依次将(徐峥,获得奖项)、(徐峥、导演)转化为自然语言后和“徐峥出演的电影有哪些”进行比对,输出相似度值,取相似度最高的做为我们的“问题模板”。然后按第一套方案,用数据库查询语言进行查询就可以了。
总结:
第二套方案解决了实体链接、指代消解的问题,并且其选择问题模板的方式由多分类换为了相似度比对去选择模板。 但是第二套方案总体来说还是有很多优化的地方,比如实体链接部分可以尝试更多元化的方法(多去寻找特征、试验不同的深度学习模型,尝试ensemble)。还有就是根据文本相似度进行问题模板的选择那里也可以做如上改进,还有将元组转换为自然语言的方法我认为不是100%完美的。
还有的话,对于多跳问题(例如“俄罗斯的首都有多少人口?”,首先需要查俄罗斯的首都是哪个城市,然后还得查这个城市有多少人口)以及实体的属性问题,例如(q610:北京大学出了哪些哲学家 select ?x where { ?x <职业> <哲学家_(基础含义)> . ?x <毕业院校> <北京大学> . })我还没总结,留个坑以后来填~