当前位置:   article > 正文

KBQA知识总结(学习笔记)

KBQA知识总结(学习笔记)

KBQA知识总结

1.KBQA

1.1 概念

基于知识图谱的问答(KBQA)–knowledge base question answering,通过对问题进行语义理解及解析,通过知识库进行查询。[1]

1.2 概述[4]

问答系统历史:基于模板的问答专家系统----->基于信息检索的问答----->基于社区的问答----->基于知识库的问答(受益于维基百科等)

问答形式分类:一问一答,交互式问答,阅读理解。

现有的成果: Wolfram Alpha;答题机器人:日本的‘多达一’高考答题机器人、863:基于大数据的类人智能关键技术与系统;

评测数据集:
1.QALD,知识库问答测评。QALD的测评指标:准确率、召回率和F值
2.WebQuestions(5810个问题)
3.FREE917

基于深度学习的问答方法:基于分布式表示(DL)的知识库问答;LSTM、attentionModel、memory network。
问句与答案计算相似度

传统的问答方法:符号表示;基于关键词、逻辑表达式、文本蕴含推理。
问句短语:
wh—短语:who 、when、where、what、which、why、how
wh+名词(形容词,副词):which shool ,how long

问答质量评估原则:相关度、正确度、精炼度、完备度、简单度、合理度

答案评估:正确、错误,不完全

问答系统基本组件:数据预处理,问题分析,数据匹配,查询创建,排序,结果生成与返回

答案的处理:抽取、组合、摘要、推理

基于知识图谱的问答的基本需求:支持自然语言问句查询,支持多种问题方式,准确率覆盖率高,维护代价低、查询速度快、面对大数据可扩展性好。

技术挑战:如何将问题映射到答案

基于模板的问答:TBSL架构
step1:模板生成:
步骤:获取自然语言问题的POStag信息---->基于POStag信息,语法规则表示问句---->利用domian-dependent词汇和domian-independent词汇来辅助分析问题------>最后将语义转化为一个SPARAQL模板
step2:模板匹配与实例化,实体识别与属性检测:
有了SPARAQL模板后,就要将自然语言问句与知识库的本体概念建立映射关系,对于resources和classes:实体识别常用方法:用Wordnet定义知识库中标签的同义词;计算字符串相似度(trigram,levenshtein和子串的相似度);对于property labels还要和存储在BAO模式库中的自然语言表示做比较;最高排位的实体将作为填充查询槽位的候选答案。

2.KBQA的基本要素

输入:自然语言问句,例如“姚明的老婆是谁?”,“姚明的身高多少?”
输出:知识图谱里的实体或者关系,例如“叶莉”,“2米29”
评价标准:召回率,准确率,F1-Score.[1]
基于知识图谱的问答的基本需求:支持自然语言问句查询,支持多种问题方式,准确率覆盖率高,维护代价低、查询速度快、面对大数据可扩展性好。

3.KBQA的方法

实现KBQA的方法大致可以分为两大类:

3.1KBQA的最基础方法–基于模板方法:[1]
3.1.1该方法的步骤:

自然语言查询–>意图识别(Intention Recognition)–>实体链指(Entity Linking)+关系识别(Relation Detection) -->查询语句拼装(Query Construction)–>返回结果选择(Answering Selection)
下面简单介绍下各个步骤的内容:
意图识别(Intention Recognition):预先准备好意图模板,可以通过相似度来匹配,也可以通过机器学习里的分类问题来解决,这个是所有问答系统都要面临的问题。
实体链指(Entity Linking)+关系识别(Relation Detection):将查询语句中出现的实体和关系映射到知识图谱里,本质是一个NER问题,只是需要将NER结果进一步链接到图谱。
参考论文:
Entity Linking: Finding Extracted Entitiesin a Knowledge Base
Improved Neural Relation Detection forKnowledge Base Question Answering
查询语句拼装(Query Construction):需要根据底层知识图谱的查询语言,拼装成对应的query来查询(sparq等),最简单的方法就是预先定义好查询模板,根据之前解析出来的(意图,实体,关系)填进模板查询即可。
返回结果选择(Answering Selection):图谱查询之后的结果可能存在多个,需要选择一个最合适的答案,可以预先指定排序规则去选择答案。

3.1.2 基于模板的优缺点:

基于模板的优点:
查询响应速度快
准确率高,可以回答复杂查询
基于模板的缺点:
要满足用户的各种问法,需要建立庞大的模板库,这个过程是很耗精力的

3.1.3 可以优化的点:

以上步骤最大的问题在于,需要人工事先准备模板,需要很大的工作量,是否可以自动生成模板?
参考论文:Automated Template Generation for Question Answering over KnowledgeGraphs.[1]

3.2基于语义解析

还未学习到,目前是通过使用正则表达式的方式来解析自然语言,并将解析的结果和我们预定义的模板进行匹配,实现了一个简易的KBQA。现在在学习基于REfO的简单知识问答,之后考虑引入其他的方法来改善系统的性能,然后逐渐减少正则规则在整个系统中的比重。

3.3基于深度学习

4.KBQA Demo

4.1KBQA Demo1-基于REfO的KBQA实现及示例 [2]

Lacking a proper name, REfO stands for “Regular Expressions for Objects”.

用Python完成一个简易的问答程序,参考了王昊奋老师发布在OpenKG上的demo“基于REfO的KBQA实现及示例”。
查询结果为空,回答“I don’t know.”;不能理解问句,回答“I can’t understand.”。

4.1.1 基本流程

此demo是利用正则表达式来做语义解析。我们需要第三方库来完成初步的自然语言处理(分词、实体识别),然后利用支持词级别正则匹配的库来完成后续的语义匹配。
分词和实体识别(人名和电影名)我们用jieba来完成。jieba是一个轻量级的中文分词工具,有多种语言的实现版本。对于分词,在实验环境中,jieba还是勉强能用。在我们这个demo当中,有些经常会被使用的词语并不能被正确切分。比如:“喜剧电影”、“恐怖电影”、“科幻电影”、“喜剧演员”、“出生日期”等,在分词的时候,jieba把它们当作一个词来处理,我们需要手动调整词语的频率使得“喜剧电影”能被切分为“喜剧”和“电影”。至于实体识别,jieba对于人名的识别精度尚可接受,但是电影名称的识别精度太低以至于完全不可用。因此,我们直接把数据库中的人名和电影名导出,作为外部词典;使用jieba的时候加载外部词典,这样就能解决实体识别的问题。
将自然语言转为以词为基础的基本单位后,我们使用REfO(Regular Expressions for Objects)来完成语义匹配。具体实现请参考OpenKG的demo或者本demo的代码。
匹配成功后,得到其对应的我们预先编写的SPARQL模板,再向Fuseki服务器发送查询,最后将结果打印出来。

4.1.2 代码文件说明

代码已放到github(https://github.com/SimmerChan/KG-demo-for-movie)中,本项目的目录结构如下:

kg_demo_movie/
   crawler/
      movie_crawler.py
      __init__.py
      tradition2simple/
         langconv.py
         traditional2simple.py
         zh_wiki.py
         __init__.py
   KB_query/
      jena_sparql_endpoint.py
      query_main.py
      question2sparql.py
      question_temp.py
      word_tagging.py
      external_dict/
         csv2txt.py
         movie_title.csv
         movie_title.txt
         person_name.csv
         person_name.txt
         __init__.py
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • "crawler"文件夹包含的是我们从"The Movie DB"获取数据的脚本。
  • "KB_query"文件夹包含的是完成整个问答demo流程所需要的脚本。
    ·"external_dict"包含的是人名和电影名两个外部词典。csv文件是从mysql-workbench导出的,按照jieba外部词典的格式,我们将csv转为对应的txt。
    ·“word_tagging”,定义Word类的结构(即我们在REfO中使用的对象);定义"Tagger"类来初始化词典,并实现自然语言到Word对象的方法。
    ·“jena_sparql_endpoint”,用于完成与Fuseki的交互。
    ·“question2sparql”,将自然语言转为对应的SPARQL查询。
    ·“question_temp”,定义SPARQL模板和匹配规则。
    ·“query_main”,main函数。
    在运行"query_main"之前,读者需要启动Fuseki服务(我寄几是简单安装部署后,直接上传.nt数据到Fuseki),具体方法请参考原作者文章。
4.1.3 总结

我们通过使用正则表达式的方式来解析自然语言,并将解析的结果和我们预定义的模板进行匹配,最后实现一个简易的KBQA。方法没有大家想象的那么“高大上”,没有统计方法、没有机器学习也没有深度学习。正则的好处是,易学,从事相关行业的人基本都了解这个东西;其次,可控性强或者说可解释性强,如果某个问题解析错误,我们只要找到对应的匹配规则进行调试即可;最后,正则冷启动比较容易,在没有数据或者数据极少的情况下,我们可以利用正则规则马上上线一个类似上述demo的初级的问答系统。在现实情况中,由于上述优点,工业界也比较青睐用正则来做语义解析。正则方法的缺陷也是显而易见的,它并不能理解语义信息,而是基于符号的匹配。换个角度说,用正则的方法,就需要规则的设计者能够尽可能考虑到所有情况,然而这是不可能的。暂且不考虑同义词、句子结构等问题,光是罗列所有可能的问题就需要花费很大的功夫。尽管如此,在某些垂直领域,比如“音乐”,“电影”,由于问题集合的规模在一定程度上是可控的(我们基本能将用户的问题划定在某个范围内),正则表达式还是有很大的用武之地的。在冷启动一段时间,获得了一定用户使用数据之后,我们可以考虑引入其他的方法来改善系统的性能,然后逐渐减少正则规则在整个系统中的比重。如果读者想深入研究KBQA,可以参考专栏“揭开知识库问答KB-QA的面纱”,该专栏的作者详细介绍了做KBQA的方法和相关研究。

4.2KBQA Demo1-基于REfO的KBQA实现及示例[8]

基于浙江大学在openKG上提供的 基于REfO的KBQA实现及示例。
具体实现:
基于REfO的简单知识问答的原理很简单,就是通过REfo提供的匹配能力,在输入的自然语言问题中进行匹配查找。如果找到我们预先设定的词或词性组合,那么就认为该问题与这个词或词性组合匹配。而一个词或词性的组合又对应着一个SPARQL查询模板,这样我们就借助REfO完成了自然语言到查询模板的转换。得到查询模板后,我们就利用Jena fuseki 服务器提供的端口进行查询得到返回的结果。
模块一 word_tagging部分
该部分利用jieba分词对中文句子进行分词和词性标注。将词的文本和词性进行打包,视为词对象,对应 :class:Word(token, pos)。

class Word(object):    
    def __init__(self, token, pos):
        self.token = token
        self.pos = pos 
class Tagger:          
    def __init__(self, dict_paths):
        # TODO 加载外部词典
        for p in dict_paths:
            jieba.load_userdict(p)
                       
    def get_word_objects(self, sentence):
        """ Get :class:WOrd(token, pos) """            
        return [Word(word.encode('utf-8'), tag) for word, tag in pseg.cut(sentence)]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

模块二 rules 部分
该部分为程序核心,负责将自然语言转换为SPARQL模板。
下面为rules的程序入口,customize_rules 函数:

def customize_rules():
    # some rules for matching
    # TODO: customize your own rules here
    person = (W(pos="nr") | W(pos="x") | W(pos="nrt"))
    movie = (W(pos="nz"))
    place = (W("出生地") | W("出生"))
    intro = (W("简介") | W(pos="介绍"))
                                
    rules = [      
                                
        Rule(condition=W(pos="r") + W("是") + person | \ 
                       person + W("是") + W(pos="r"),
             action=who_is_question),
                            
        Rule(condition=person + Star(Any(), greedy=False) + place + Star(Any(), greedy=False),
             action=where_is_from_question),
                            
        Rule(condition=movie + Star(Any(), greedy=False) + intro + Star(Any(), greedy=False) ,
             action=movie_intro_question)
                            
    ]         
    return rules
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

该函数中我们设置了一些简单的匹配规则,例如我们设置 ‘’’movie = (W(pos=”nz”))’’‘,即movie 的词性应该是nz。其中的W()是我们在继承REfO的Predicate方法的基础上扩展更新了match方法。您可以简单的把它理解为re中compile后的match,只不过多个W()间出现的顺序可以变化。这样通过多个定制的W()和Star(Any(), greedy=False)(相当于.*?)这种通配符的组合,我们就定义了一组匹配规则,当遇到符合该规则的句子时,就选取该规则后action对应的查询模板。
例如当输入为“周星驰是谁”这样的问题时,会匹配到rules 中的 第一条规则。而后执行该规则后对应的action,who_is_question。而who_is_question对应的查询模板为:

def who_is_question(x):
    select = u"?x0"               
         
    sparql = None
    for w in x:
        if w.pos == "nr" or w.pos == "x":
            e = u" ?a :actor_chName '{person}'. \n \ ?a :actor_bio ?x0".format(person=w.token.decode("utf-8"))
         
            sparql = SPARQL_TEM.format(preamble=SPARQL_PREAMBLE,
                                       select=select,
                                       expression=INDENT + e)
            break
    return sparql
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

有了查询模板后,我们通过SPARQLWrapper 模块的SPARQLWrapper 执行该查询,并对返回的结果进行转换得到回答。对应的代码如下:

from SPARQLWrapper import SPARQLWrapper, JSON    
from utils.word_tagging import Tagger
from utils.rules import customize_rules                   
                 
if __name__ == "__main__":    
    print("init...........")    
    sparql_base = SPARQLWrapper("http://localhost:3030/kg_demo_movie/query")
    #加载外部词典,提升分词准确性和词性标注准确性
    tagger = Tagger(['data/actorName.txt', 'data/movieName.txt'])
    #初始化并获取规则列表
    rules = customize_rules()   
    print("done \n")    
                 
    while True:    
        print("Please input your question: ")    
        default_question = raw_input()    
        # 获取wordclass
        seg_list = tagger.get_word_objects(default_question)
                 
        for rule in rules:    
            # 将规则列表应用到问题上得到查询模板
            query = rule.apply(seg_list)    
            if query:    
                # 设置查询相关
                sparql_base.setQuery(query)    
                sparql_base.setReturnFormat(JSON)         
                # 得到返回结果并做转换
                results = sparql_base.query().convert()   
                 
                if not results["results"]["bindings"]:    
                    print("No answer found :(")    
                    continue    
                for result in results["results"]["bindings"]:
                    print "Result: ", result["x0"]["value"]
  • 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
  • 31
  • 32
  • 33
  • 34
4.3KBQA Demo2-从零开始搭建一个小型知识图谱,并实现语义搜索和KBQA功能 [3]

Z_knowledge_graph 从零开始的知识图谱生活 GitHub主页
(看到这篇博客窝就明白了任重而道远,且仅是一部分道路)
简介
为了构建中文百科类知识图谱,我们参考漆桂林老师团队做的zhishi.me。目标是包含百度百科、互动百科、中文wiki百科的知识,千万级实体数量和亿级别的关系数目。目前已完成百度百科和互动百科部分,其中百度百科词条4,190,390条,互动百科词条4,382,575条。转换为RDF格式得到三元组 128,596,018个。存入 neo4j中得到节点 16,498,370个,关系 56,371,456个,属性 61,967,517个。

目录
希望在该图谱上尝试应用以下技术:

  • 百度百科与互动百科的知识抽取

     半结构化数据
     	百度百科爬虫
     	互动百科爬虫
     非结构化数据
     	微信公众号爬虫
     	虎嗅网爬虫
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 非结构化文本的知识抽取

     基于Deepdive的知识抽取
     制作类似于NYT的远程监督学习语料--baidu_6w
     神经网络关系抽取
    
    • 1
    • 2
    • 3
  • 知识存储

     D2RQ 的使用
     Jena 的使用
     Neo4j 的使用
    
    • 1
    • 2
    • 3
  • 知识融合

     Silk 实战
    
    • 1
  • 自底向上的本体构建技术(TODO)

  • 知识表示(TODO)

     TransE
    
    • 1
  • 知识挖掘(TODO)

  • KBQA

     基于 REfO 的简单KBQA
    
    • 1
  • 语义搜索

     基于elasticsearch 的简单语义搜索 支持实体检索、实体属性检索和条件检索
    
    • 1
4.4KBQA Demo3-基于Freebase的问答研究 [5]

问答(QA)是信息检索和自然语言处理(NLP)领域的一门计算机科学学科,它涉及构建能自动回答人类用自然语言提出的问题的系统。[1]QA系统能通过映射,将问题映射到知识库中去,直指答案,通过这样的方式来为用户反馈答案。而KBQA使用的时候新的问题表达形式——模板,能够通过百万级的QA语料库进行学习,之后生成大量的模板,用于后续的问题识别。
研究上,一个QA系统通常设计成回答某一特定类型的问题,而这其中,最重要的问题类型之一就是——基于事实的问题。基于事实的问题问的是某个实体的一些个客观事实。而基于事实的问题中,又有一种特殊的问题——二元事实问题(BFQ)。二元事实问题问的是某个实体的某些个属性。举个例子,檀香山有多少人?主要采用KBQA的方式去解决基于Freebase的二元事实问题,KBQA的特点就是通过模板了解问题,通过这样的方式能够识别出问题的更多谓词,系统反馈答案,映射的时候,能够更好地识别问题的具体意图。

4.5KBQA Demo4-简单构建基于RDF和SPARQL的KBQA(知识图谱问答系统)[6]

流程原理:
该问答系统可以解析输入的自然语言问句,主要运用REFO库的"对象正则表达式"匹配得到结果, 进而生成对应 SPARQL 查询语句,再通过API请求后台基于TDB知识谱图数据库的 Apache Jena Fuseki 服务, 得到结果。
实际过程:

  1. 预定义 3 ​类共 5 ​个示例问题,​包括:
      ● “谁是苑茵?”,
      ● “丁洪奎是谁?”,
      ● “苏进木来自哪里?”,
      ● “苑茵哪个族的?”,
      ● “苑茵是什么民族的人?”.
  2. 利用结巴分词对中文句子进行分词, ​同时进行词性标注;
  3. 将词的文本和词性打包, ​视为"词对象",对应 :class:Word(token,​ ​pos)​;
  4. 利用 REfO ​模块对词进行对象级别 (object-level) ​的正则匹配,判断问题属于的​种类​并产生对应的 SPARQL,对应 :class:Rule(condition,​ ​action)​;
  5. 如果成功匹配并成功产生 SPARQL ​查询语句, ​立刻请求 Fuseki ​服务并返回结果,打印相关内容;
4.6案例demo

5.KBQA 参考

1.知识图谱的问答(基于模板方法 ) T.20180116

2.实践篇(五):KBQA Demo T.20180128

3.从零开始搭建一个小型知识图谱,并实现语义搜索和KBQA功能

4.KBQA知识问答概述

5.基于Freebase的问答研究 T.2018-3-27

6.简单构建基于RDF和SPARQL的KBQA(知识图谱问答系统)
Demo1 T.2018-08-23

Demo2 T.20200116

7.七篇和KBQA多多少少有些相关的论文 T.20181019

8.基于REfO的KBQA实现及示例

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/583368
推荐阅读
相关标签
  

闽ICP备14008679号