基于知识图谱的问答系统简单流程理解(开放型知识图谱、实体类型较多的图谱)

写在前面

虽然网上代码一大堆,论文一大堆,但是我连一篇实实在在介绍基于知识库的问答系统实现逻辑简单介绍的都找不到。
当然,基于对模板匹配的博客我倒是找到了一篇,见:
https://blog.csdn.net/xyz1584172808/article/details/89319129(写的非常好,整个问答系统的搭建流程都说明白了。)
但是他这篇文章相较于基于知识库的问答来说少了很多东西,我首先总结一下他这篇简单的实现流程,然后再引申到基于知识库的问答系统。

基于模板匹配的问答系统:

先说明一下:基于模板和基于知识库其实非常相似

阶段主要有:

  • 实体识别
  • 将用户的问题进行多分类,进而实现“用户自然语言问题→形式化问题模板”
  • 将实体识别作为问题模板的实参,去图数据库中查询问题的答案。

实体识别阶段:

例如:“刘德华演过哪些电影呀?”
对其进行命名实体识别,就可以得到:“刘德华”,且也能将它标注为“nnt”,nnt实际上就是“人”的词性,这个实体识别过程就相当于一个分词+词性标注过程。(这个过程可以用bert来做,就不会产生用jieba分词把词分错的问题了。比如卧虎藏龙 分成了 卧虎 藏龙两个词)
注意,电影在此处不是个实体,它应该包含在“演过哪些电影”这个问题之中(更简单的理解就是“演过的电影”是一个关系)

用户自然语言问题向模板的映射:

例如某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,反向传播。同样的,输入另一段训练语料,比如“刘德华的出生日期”,也可以做训练语料。这样就能训练一个模型,这个模型的作用是:输入一句话,比如“卧虎藏龙的电影类型是什么?”,然后他就会将这句话映射到模板10(也就是nnt 电影类型)上

测试阶段:
此处共有14个问题模板
那么,比如“刘德华演过哪些电影呀?”这个问题,我们将它输入到我们刚刚训练好的模型里,就可以得到这句话对应的模板类型,也就是7了。(当然,预测结果甚至有可能是2、3这类主语是nm而不是nt的,这时我们就可以做一个限制。由于我们通过ner能得到“刘德华演过哪些电影呀?”中刘德华这个实体,同时也能知道“刘德华”所对应的实体类型为nnt,那么我们就可以只在带有nnt的模板中,选择预测概率最高的)

将实体传入模板中,用图数据库查询语句查答案:

例如“刘德华演过哪些电影呀?”,通过上面的步骤,我们可以得到模板“nnt 电影作品”,也可以得到“刘德华演过哪些电影呀?”这句话中的实体刘德华(nnt),于是可以将nnt所对应的“刘德华”填入到模板“nnt 电影作品”中,就可以得到一条查询语句“刘德华 电影作品”了,用图数据库查询语句就是

     SELECT ?x WHERE
     {
        <刘德华>    <参演电影>    ?x
    }

非常像一条sql语句。
然后就可以查到刘德华参演的所有电影了

至此,已经将这套简单的方案完全介绍完成

上面那套方案的缺点:

  • 如果模板库中模板很多的话,那么分类的类别数量会非常大,而模型在大量分类种类数的情况下表现一般都不会好
  • 模板库中如果新添加了模板,那么就需要重新训练一遍问题-模板映射模型,可扩展性非常差
  • 实体种类特别多,且实体种类不能单单用词性标注的情况下,上面这套方案的“词性标注”就没办法用了。比如我要做计算机领域的答疑,那么“二叉树”肯定不能简单只用一个词性“n”来指代。

新方案

下面的方案将解决上面提到的那几个问题

工业环境下真实场景分析:

  • 开放领域的图谱一般都非常大,实体类型非常多,比如PKUBASE知识库,包含了包含130万以上实体,涉及的实体类型有各方各面(军人、工人、电影、电视剧……),至现在还没有一个统一的实体标准(就比如上面提到的词性标注)来对实体有一个大的分类,比如一个电影:我们可以知道电影有名字、谁参演了、评分之类的通用属性,但是万一有个电影有“好的社会影响”呢?那你还得把好的社会影响再添到“电影”的属性中去,那么再来个其他的属性或者关系呢?(这些都是我自己叨叨的,大家能看懂就看懂吧)。最好的方法就是单个实体单独拿来说事:比如“姚明的成就是啥啥啥”,而不要用“nr的成就是啥啥啥”
  • 但是!!!!,还有很多情况,比如:①“北京大学”和“北大”都可以代指“北京大学” ②“小苹果”既可以代指“小苹果_歌曲”,也可以代指“小苹果_水果”
    像这种情况,就最好将一个词B的各种代称,都指向B,且这个指向一定要非常明确,比如“北大”,就明确的指向“北京大学_(北京最厉害的高校之一)”,而不单单只是指向“北京大学”,这就涉及到 “实体链接”(及指代消解) 的问题了

解决方案

实体识别(此时未实体链接):

继续使用bert-ner,例如“阿根廷国家的政策是什么?”,可以抽取到“阿根廷国家”这个实体

实体链接:

现在,网络上实际上是有实体链接词典去解决那种“别名的问题了”

  • 阿根廷 阿根廷_(国家)
  • 阿根廷 阿根廷_(足球国家队)
  • 阿根廷 阿根廷_(篮球国家队)
  • 阿根廷 阿根廷_(贸易组织成员)
  • 阿根廷国家队 阿根廷_(足球国家队)
  • 阿根廷国家队 阿根廷_(篮球国家队)
  • 阿根廷国家队 阿根廷_(贸易组织成员)

说明一下:
第一列是实体名称,第二列是实体名称可能指向的具体(具体到类型)的实体。这样实际上我们就可以解决“别名”(指代消解)问题,但是实体链接问题我们实际上还是没有解决。比如“阿根廷踢了一场好球”,用bert进行ner后拿到了阿根廷,我们人工来看的话很容易就知道这句话里阿根廷代表“阿根廷_(足球国家队)”,但是机器直接看这句话的话是不知道应该从

  • 阿根廷 阿根廷_(国家)
  • 阿根廷 阿根廷_(足球国家队)
  • 阿根廷 阿根廷_(篮球国家队)
  • 阿根廷 阿根廷_(贸易组织成员)
    中选哪一个的。
    这就需要我们进行实体链接了:首先我们能拿到“阿根廷踢了一场好球”这句话中的“阿根廷”,然后我们能从实体链接库中将实体名为“阿根廷”的指代全部拿到,就是这个
  • 阿根廷 阿根廷_(国家)
  • 阿根廷 阿根廷_(足球国家队)
  • 阿根廷 阿根廷_(篮球国家队)
  • 阿根廷 阿根廷_(贸易组织成员)

接下来,我们可以选择
深度文本匹配模型:首先用cnn去分别扫描“阿根廷红场之役在哪一年踢的?”及“阿根廷_(国家)”这几个字,做一个pairwise(模型),输出一下相似度。
然后再分别扫描“阿根廷踢了一场好球”及“阿根廷_(足球国家队)”,输出相似度,依次类推(关于训练过程的设计我就不说了,可以用esim等模型)
lgb,也是做文本相似度模型,做特征,详细的特征需要看论文(lgb在论文里是最优的,高于pairwise)
取相似度最高的top-n个实体作为候选实体

属性抽取并链接

论文中采用的是规则+模板匹配的方式,比如1997年八月,用规则将其转成知识库中规范的格式,比如1997年8月,然后对知识库中的所有属性进行匹配(具体看论文吧)

使用文本相似度匹配模型去选择候选查询路径

通过实体识别以及实体链接,我们可以分析“徐峥出演的电影有哪些?”,得到“徐峥_(演员)”这个具体的实体,然后我们就可以从知识库中将带有“徐峥_(演员)”的所有的三元组都拿到,例如
(徐峥_(演员),出演,股票的颜色_(电影))
(徐峥_(演员),出演,春光灿烂猪八戒_(电影))
(徐峥_(演员),出演,爱情呼叫转移_(电影))
(徐峥_(演员),出演,夜店_(电影))
(徐峥_(演员),获得奖项,电影频道传媒大奖_(奖项))
(徐峥_(演员),获得奖项,电影金马奖最佳男主角_(奖项))
(徐峥_(演员),导演,我和我的祖国_(电影))
只将"徐峥_(演员)"对应的所有关系拿出来
徐峥_(演员),出演;获得奖项;导演
然后可以用esim(pairwise模型)去将"徐峥出演的电影有哪些"与“徐峥出演了”进行比对**(此处请注意,深度模型的输入一般都是自然语言,像(徐峥,出演)是不可以直接输入进模型的,需要将(徐峥,出演)转换为自然语言,即“徐峥出演了”)**,输出相似度。
接下来依次将(徐峥,获得奖项)、(徐峥、导演)转化为自然语言后和“徐峥出演的电影有哪些”进行比对,输出相似度值,取相似度最高的做为我们的“问题模板”。然后按第一套方案,用数据库查询语言进行查询就可以了。

总结:

第二套方案解决了实体链接、指代消解的问题,并且其选择问题模板的方式由多分类换为了相似度比对去选择模板。
但是第二套方案总体来说还是有很多优化的地方,比如实体链接部分可以尝试更多元化的方法(多去寻找特征、试验不同的深度学习模型,尝试ensemble)。还有就是根据文本相似度进行问题模板的选择那里也可以做如上改进,还有将元组转换为自然语言的方法我认为不是100%完美的。

还有的话,对于多跳问题(例如“俄罗斯的首都有多少人口?”,首先需要查俄罗斯的首都是哪个城市,然后还得查这个城市有多少人口)以及实体的属性问题,例如(q610:北京大学出了哪些哲学家
select ?x where { ?x <职业> <哲学家_(基础含义)> . ?x <毕业院校> <北京大学> . })我还没总结,留个坑以后来填~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章