基于语义解析的KBQA——代码和论文详细分析

news2024/11/18 5:31:39

根据论文:Semantic Parsing on Freebase from Question-Answer Pairs,分析其代码和步骤,以加强对这一流程的深入理解,重点关注模型的输入、输出和具体方法。

前言

提供阅读本文的前提知识,引用自Semantic Parsing on Freebase from Question-Answer Pairs这篇论文。

语义解析

知识库由大量的三元组组成,并且这些三元组的实体和实体关系都是形式化的语言。

比如(BarackObama, PlaceOfBirth, Honolulu),给定一个自然语言的问题 “Where was Obama born?”,我们面临的第一个挑战就是,如何建立问题到知识库的映射

语义解析KBQA的思路是通过对自然语言进行语义上的分析,转化成为一种能够让知识库理解的语义表示,进而通过知识库中的知识,进行推理(Inference)和查询(Query),得出最终的答案。

简而言之,语义解析就是将自然语言的问题,转化为一种能够让知识库“看懂”的语义表示,这种语义表示即逻辑形式(Logic Form)

逻辑形式

为了能够对知识库进行查询,我们需要一种能够“访问”知识库的逻辑语言,Lambda-DCS是一种经典的逻辑语言,它用于处理逻辑形式而实际操作中我们经常用SPARQL,它通常可以在Virtuoso engine上对Freebase进行查询。如果把知识库看作是一个数据库,逻辑形式则可以看作是查询语句的表示。

我们用 z 表示一个逻辑形式,用 k 表示知识库,e 表示实体,p 表示实体关系(有的也称谓语或属性)。逻辑形式分为一元形式(unary)和二元形式(binary)。对于一个一元实体 e ,我们可以查询出对应知识库中的实体;给定一个二元实体关系 p ,可以查到它在知识库中所有与该实体关系 p 相关的三元组中的实体对。

并且,我们可以像数据库语言一样,进行连接Join,求交集Intersection和聚合Aggregate(如计数,求最大值等等)操作。具体来说,逻辑形式有以下形式和操作:

有了上面的定义,我们就可以把一个自然语言问题表示为一个可以在知识库中进行查询的逻辑形式

比如对于问句 “Number of dramas starring Tom Cruise?”

它对应的逻辑形式是 count(Genre.Drama \cap Performance.Actor.TomCruise)

当自然语言问题转化为逻辑形式之后,通过相应的逻辑语言(转化为SPARQL query)查询知识库就可以得到答案。

所以接下来就是我们要学习和研究的重点:语义解析如何把自然语言问题正确地转化为相应的逻辑形式

1. 概要

该论文该方法来自斯坦福的 Jonathan Berant,发表于2013年的EMNLP会议,是一个经典的语义解析baseline。

论文在Freebase上提出训练一个语义解析器,并基于该语义解析器进行KBQA,不再依赖于代价大的标注逻辑形式,而直接从问题-答案对中学习。给定自然语言问句,KBQA最棘手的问题就是存在相关的大量可能的逻辑谓词,对于怎么从问题句子中降低可能的逻辑谓词(logical predicates),作者提出了两种方法:

(1)短语到谓词的映射(mapping):通过将大型文本语料库与Freebase对齐,构建一个语句到谓词的粗糙映射

(2)桥接操作(bridging operation):基于相邻谓词生成与之兼容的逻辑谓词

2. 模型

该模型为使用本文所将方法而实现的一个小的demo模型,具体流程和框架与原论文基本一致,其中2.1解析器方法会重点介绍论文中使用的Sempre源代码和方法

2.1 模型架构

输入:英语自然语言查询

输出:从Freebase中检索出的自然语言答案

示例: Who did Obama marry? -> (SBARQ (WHNP (WP Who)) (SQ (VBD did) (NP (NNP Obama)) (VP (VB marry))) (. ?))

-> {'subject': 'Obama', 'property': 'marry'}

-> SELECT ?valLabel WHERE { { wd:Q76 p:P26 ?prop . ?prop ps:P26 ?val . } SERVICE wikibase:label { bd:serviceParam wikibase:language "en"} }

-> Michelle Obama

2.2 解析器方法—Sempre 1.0

源代码文件框架

主要源文件:

  • Main.java:Sempre 主类,包含了 Sempre 的入口点。

  • Master.java:Sempre 主控类,负责调度和管理解析任务。

  • Session.java:Sempre 会话类,表示一个解析任务的会话。

  • Builder.java:Sempre 构建器类,用于构建语义解析器的各个组件。

解析器相关:

  • Parsers.java:解析器管理类,用于管理不同类型的解析器。

  • Parser.java:解析器接口,定义了解析器的基本行为。

  • BeamParser.java:Beam 解析器类,实现了基于 Beam Search 的解析算法。

语法和特征提取:

  • Grammar.java:语法类,用于管理语法规则。

  • FeatureExtractor.java:特征提取器类,用于从输入中提取特征。

  • FeatureVector.java:特征向量类,用于表示特征。

执行器相关:

  • Executor.java:执行器接口,定义了执行器的基本行为。

  • SparqlExecutor.java:SPARQL 执行器类,用于执行 SPARQL 查询。 其他支持类:

  • LanguageInfo.java:语言信息类,用于表示语言相关信息。

  • StringCacheServer.java:字符串缓存服务器类,用于管理字符串缓存。

  • FreebaseSearch.java:Freebase 搜索类,用于在 Freebase 中进行实体搜索。

输入:给定 i)一个知识库K ii)问题-答案对训练集\{(x i, y i)\}_{i=1}^{n}

输出:通过潜在逻辑形式z和知识库K将问题x映射到答案y上的语义解析器

整体是一个自底向上构造语法树的过程,树的根节点,就是该自然语言问题最终的逻辑形式表达。可以分为两个步骤:

  1. 1. 词汇映射(Lexicon):即构造底层的语法树节点。将单个自然语言短语或单词映射到知识库实体或知识库实体关系所对应的逻辑形式。作者通过构造一个词汇表(Lexicon)来完成这样的映射。

  2. 2. 构建(Composition):即自底向上对树的节点进行两两合并,最后生成根节点,完成语法树的构建。这一步有很多种方法,诸如构造大量手工规则,组合范畴语法(Combinatory Categorical Grammars,CCG)等等,本方法中作者采用了最暴力的方法:对于任何两个节点都可以执行上面所谈到的连接Join,求交Intersection,聚合Aggregate三种操作。以及使用独创的桥接操作进行结点合并。缺点是这种合并方式复杂度是指数级的,最终会生成很多棵语法树,因此还需要通过对训练数据进行训练,训练一个分类器,对语法树进行筛选

自然语言—>逻辑形式流程如下图所示:

  • 红色部分即逻辑形式
  • 绿色部分where was Obama born 为自然语言问题
  • 蓝色部分为词汇映射(Lexicon)和构建(Composition)的操作
  • 最终形成的语义解析树的根节点为语义解析结果

针对上面的方法,有三个待解决的细节问题:(1)如何训练分类器?(2)如何构建词汇表?(3)什么是桥接操作?

2.2.1 训练分类器

分类器的任务是计算每一种语义解析结果d(Derivation)的概率,对于对每个 d ∈ D(x),使用判别对数线性模型discriminative log-linear model进行建模,使用Softmax进行概率归一化,公式如下:

其中\phi(x,d_{i}) 是b维的参数向量,它是一个从语义解析结果d_{i}和x中提取出来的b维特征向量(该特征向量包含了构造该语法树所有操作的对应特征,每种操作的具体特征之后会提到),

对于训练数据对,训练的目标是最大化Log-likelihood损失函数,通过AdaGrad算法(一种动态调整学习率的随机梯度下降算法)进行参数更新。

2.2.2 构建词汇表

词汇表即自然语言与知识库实体或知识库实体关系的单点映射,这一操作也被称为对齐(Alignment)。

将自然语言实体映射到知识库实体相对比较简单,比如将“Obama was also born in Honolulu.”中的实体Obama映射为知识库中的实体BarackObama,可以使用一些简单的字符串匹配方式进行映射

但是要将自然语言短语如“was also born in”映射到相应的知识库实体关系,如PlaceOfBirth, 则较难通过字符串匹配的方式建立映射。

可以进行统计,如果有较多的实体对(entity1,entity2)作为主语和宾语出现在was also born in的两侧,并且在知识库中,这些实体对也同时出现在包含PlaceOfBirth的三元组中,那么我们可以认为“was also born in”这个短语可以和PlaceOfBirth建立映射。简而言之就是:如果一个句子两端实体和知识库谓词两端实体重复很多,则将这两者对齐。

比如(“Barack Obama”,“Honolulu”),(“MichelleObama”,“Chicago”)等实体对在文档中经常作为“was also born in”这个短语的主语和宾语,并且它们也都和实体关系PlaceOfBirth组成三元组出现在知识库中。

本论文在ClueWeb09上抽取15millions个三元组构成一个数据集,如(“Obama”, “was also born in”, “August 1961”),可以看出三元组的实体和关系都是自然语言的形式,取出其中的一个三元组子集,对里面的每一个三元组的主语实体和宾语实体通过字符匹配的方式替换为知识库的实体,并对数据进行归一化。

如(“Obama”, “was also born in”, “August 1961”) 经过预处理后转化为 (BarackObama, “was also born in”, 1961-08)。

接着对每一个三元组中的自然语言短语r_{1} 两边的实体对(entity1,entity2)进行统计。

注意⚠️ 由于自然语言短语具有多义性,r_{1}和知识库实体关系r_{2}的对应关系是多对多的,比如“was also born in”可能对应PlaceOfBirth或DateOfBrith,我们需要对每一个r_{1}进行区分。可以通过知识库查询到每一个实体的类型(type),比如1961-08的类型是date,而Honolulu的类型是place,我们对r_{1}两边的实体类型进行查询可以得到主语实体的类型t_{1}和宾语实体的类型t_{2},因此r_{1}可以进一步表示为r_{1}[t_{1},t_{2}],我们对其所在三元组两边的实体进行统计,得到实体对集合F(r_{1}[t_{1},t_{2}])。对齐构造主要如下图:

图中绿色字体为r_{1},蓝色字体为r_{2}。作者定义了词汇映射操作的三种特征用于训练分类器:对齐特征(Alignment features),文本相似度特征(Text similarity features),和词汇化特征(Lexicalized features),具体内容如下表所示:

其中文本相似度特征中的s_{2}指r_{2}的freebase name。

在实际使用中,我们可以通过词性标注(POS)和命名实体识别(NER)来确定哪些短语和单词需要被词汇映射(Lexicon),从而忽略对一些skipped words进行词汇映射。并且,作者还建立了18种手工规则,对问题词(question words)进行逻辑形式的直接映射,如“where,how many”映射为Type.Location 和 Count。

构建词汇表/对齐部分的代码位于文件:sempre/src/edu/stanford/nlp/sempre/paraphrase/Aligner.java

其中对齐操作在align()方法中:

public Alignment align(ParaphraseExample example, Params params) {
   example.ensureAnnotated();
   Alignment alignment = new Alignment(example);
   alignment.buildAlignment(example, params);
   example.setAlignment(alignment);
   return alignment;
}

构建对齐结果,包括计算同义词替换、删除、添加等操作在Alignment 内部类的buildAlignment()方法中:

public void buildAlignment(ParaphraseExample example, Params params) {
     computeIdentityAlignments(example);
     computePhraseTableAlignments(example);
     computeSubstitutionsAlignment(example);
     computeDerivationsAlignment(example);
     //this needs to be done last
     markDeletions(example);
     if(opts.useSyntax)
       computeSyntacticAlignment(example);
     if(opts.verbose>=1) {
       printFeaturesAndWeights(params);
    }
     score = featureVector.dotProduct(params);
  }

2.2.3 桥接操作

完成词汇表的构建后,仍然存在一些问题。比如,对于go,have,do这样的轻动词(light verb)难以直接映射到一个知识库实体关系上,其次,有些知识库实体关系极少出现,不容易通过统计的方式找到映射方式,还有一些词比如actress,实际上是两个知识库实体关系进行组合操作后的结果(actor \cap gender.female) 。因此需要找到一个额外的二元关系来将当前的逻辑形式连接起来,这就是桥接。

举个具体的例子,比如 “Which college did Obama go to?

假设“Obama”和“college”可被词汇映射映射为 BarackObamaType.University,这里"go to"却难以找到一个映射,所以这里我们需要去寻找一个中间二元关系b(即Education)使得上面的句子可以被解析为(Type.University \cap Education.BarackObama),如下图所示:

具体来说就是给定两个一元逻辑形式z_{1}, z_{2},它们的类型分别为t_{1}, t_{2},对于每个二元关系b如果它的主语宾语类型和t_{1}, t_{2}相同,则在b对应的实体类型满足(t_{1}, t_{2})的条件下,生成逻辑形式z_{1} \cap b.z_{2}

桥接部分的代码位于:sempre/src/edu/stanford/nlp/sempre/BridgeFn.java,其中

  • bridgeUnary()方法处理一元关系的桥接,它根据候选上下文和问题上下文的类型信息,以及二元关系的信息,将一元关系与二元关系连接起来;

  • bridgeEntity 方法处理实体的桥接操作,它根据问题上下文的类型信息和二元关系的信息,将实体与相应的二元关系连接起来;

  • injectIntoCvt方法处理将实体注入到复合关系中的桥接操作,它找到复合关系中的待填充位置,并将实体与相应的二元关系连接起来。

3. 模型代码

模型主要实现代码位于nlquery代码的nlquery/nlquery/nlquery.py文件,其中:

NLQueryEngine类包含了整个查询流程的实现:

  • __init__方法会创建一个StanfordServerParser对象,用于将自然语言问题解析成树状结构。

  • subject_query方法的作用是将匹配到的上下文转换为查询参数,并执行查询操作。这个方法主要用于处理主语查询,即从自然语言问题中提取出主语、动词动作、属性等信息,然后根据这些信息执行查询操作,最终返回查询结果。

  • find_entity_query 方法的作用是将匹配到的上下文转换为查询参数,并执行查询以找到实体。该方法通常用于解析自然语言查询,提取查询中的实体、属性和限定条件,并将其转换为可以用于查询实体的参数。最终,该方法将返回一个包含查询结果的 Answer 对象。

  • get_property 方法的作用是获取给定主题的属性。该方法通常用于根据给定的主题和属性查询相应的信息,比如查询某个人的年龄、职业等属性。根据查询的结果,该方法会返回一个包含查询结果的 Answer 对象。

  • preprocess 方法的作用是对查询语句进行预处理,主要是添加必要的标点符号,确保查询语句的格式正确。通常情况下,查询语句应以问号结尾,如果查询语句缺少问号,则该方法会自动在末尾添加问号。

4.细节

  • 对于知识库的存储,常见采用的是Virtuoso SPARQL engine,配合lambda-DCS进行查询。

  • 知识库存储也可采用jena+sparql框架实现,环境搭建https://jena.apache.org/download/

3. 参考/代码资料

  • 论文阅读:Semantic Parsing on Freebase from Question-Answer Pairs-CSDN博客

  • 解析器Sempre第一版代码: Sempre 1.0 Webquestions training · Issue #47 · percyliang/sempre · GitHub

  • KBQA_Demo代码:GitHub - ayoungprogrammer/nlquery: Natural Language Engine on WikiData

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1479172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python利用pandas对数据进行特定排序

更多Python学习内容:ipengtao.com 在数据分析和处理过程中,排序是一项常见而重要的操作。Python中的pandas库提供了丰富的功能,可以方便地对数据进行各种排序操作。本文将详细介绍如何利用pandas对数据进行特定排序,包括基本排序、…

ODOO12设置收发邮件服务器教程

一、设置-技术 二、设置–技术–发件服务器 信息填写完整后,点击‘测试连接’,若提示成功,则发件服务器设置成功。 三、设置–技术–收件服务器 四、设置–参数–系统参数 修改之前的email系统参数: mail.catchall.alias: 收件服…

vivo 在离线混部探索与实践

作者:来自 vivo 互联网服务器团队 本文根据甘青、黄荣杰老师在“2023 vivo开发者大会"现场演讲内容整理而成。 伴随 vivo 互联网业务的高速发展,数据中心的规模不断扩大,成本问题日益突出。在离线混部技术可以在保证服务质量的同时&…

在 Linux 环境下安装 Kibana

目录 一、Kibana 是什么 二、在 Linux 环境下安装 Kibana 1、下载安装包 2、解压 3、修改 Kibana的配置文件 config/kibana.yml 4、启动 5、浏览器登录 Kibana 6、测试查询 一、Kibana 是什么 Kibana 是通向 Elastic 产品集的窗口。 它可以在 Elasticsearch 中对数据进…

postman切换成黑色主题

postman安装以后默认是白色背景,如果想要切换成黑色的,大家可以按照下图箭头指示来操作。 1打开设置 2在Themes页面选择黑色主题

ElasticSearch之Completion Suggester

写在前面 通过completion suggester可以实现如下的效果: 其实就是做的like xxx%这种。通过FST这种数据结构来存储,实现快速的前缀匹配,并且可以将es所有的数据加载到内存中所以速度completion的查询速度非常快。 需要注意,如果…

Docker技术概论(2):Docker环境的搭建

Docker技术概论(2) Docker环境的搭建 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blo…

贪心算法(算法竞赛、蓝桥杯)--修理牛棚

1、B站视频链接&#xff1a;A27 贪心算法 P1209 [USACO1.3] 修理牛棚_哔哩哔哩_bilibili 题目链接&#xff1a;[USACO1.3] 修理牛棚 Barn Repair - 洛谷 #include <bits/stdc.h> using namespace std; const int N205; int m,s,c,ans; int a[N];//牛的位置标号 int d[N…

C/C++语言文字小游戏(荒岛求生)

游戏背景 玩家在荒岛上&#xff0c;需要寻找食物、水源、避难所等资源来生存。 玩家需要避免危险&#xff0c;如野兽、植物、天气等&#xff0c;否则会失去血量或生命。 玩家可以在荒岛上遇到其他生存者&#xff0c;可以选择合作或对抗。 游戏目标是生存一定时间或找到生存的出…

MySql-多表设计-多对多

目录 多对多 多对多 多对多的关系在开发中属于也比较常见的。比如&#xff1a;学生和老师的关系&#xff0c;一个学生可以有多个授课老师&#xff0c;一个授课老师也可以有多个学生。在比如&#xff1a;学生和课程的关系&#xff0c;一个学生可以选修多门课程&#xff0c;一个…

Linux——haproxy搭建Web群集

一、haproxy概述 HAProxy 提供高可用性、负载均衡以及基于TCP和HTTP的应用代理&#xff0c;支持虚拟主机&#xff0c;它是免费、快速并且可靠的一种负载均衡解决方案。适合处理高负载站点的七层数据请求。类似的代理服务可以屏蔽内部真实服务器&#xff0c;防止内部服务器遭受攻…

Dockerfile(5) - CMD 指令详解

CMD 指定容器默认执行的命令 # exec 形式&#xff0c;推荐 CMD ["executable","param1","param2"] CMD ["可执行命令", "参数1", "参数2"...]# 作为ENTRYPOINT的默认参数 CMD ["param1","param…

iSlide插件2024免费版(包含52 个PPT设计辅助功能,9 大在线资源库,以及超 50 万 专业)

一、功能介绍 iSlide是一款专为PowerPoint设计的插件&#xff0c;它集合了众多设计与效率提升的功能&#xff0c;帮助用户更快速、更美观地制作演示文稿。 主题设计&#xff1a;提供多种设计主题&#xff0c;用户只需一键应用&#xff0c;即可为幻灯片赋予统一的视觉风格。智…

php PhpSpreadsheet 读取日期变数字问题解决

问题描述&#xff1a; 使用PhpSpreadsheet 读取表格数据&#xff0c;日期格式读取后变成数字&#xff0c;如下图&#xff1a; 解决方案&#xff1a; $cell $sheet->getCell(H . $row)->getValue(); $toTimestamp \PhpOffice\PhpSpreadsheet\Shared\Date::excelToTimes…

学习大数据,所必需的java基础(6)

文章目录 集合Set集合介绍HashSet集合的介绍和使用LinkedHashSet的介绍以及使用哈希值哈希值的计算方式HashSet的存储去重的过程 Map集合Map的介绍HashMap的介绍以及使用HashMap的两种遍历方式方式1&#xff1a;获取key&#xff0c;然后再根据key获取value方式2&#xff1a;同时…

STL常见容器(set/multiset)---C++

STL常见容器目录&#xff1a; 7. set/multiset 容器7.1 set/multiset 基本概念7.2 set构造和赋值7.3 set大小和交换7.4 set插入和删除7.5 set查找和统计7.6 set和multiset区别7.6.1 pair对组创建7.6.2 set和multiset区别 7.7 set容器排序7.7.1 内置数据类型7.7.2 自定义数据类型…

React中对表格实现列表的拖拽排序

1. 效果:推拽手柄列 2. 实现: react中我们需要两个包来实现 ‘array-move’‘react-sortable-hoc’Installation Use npm $ npm install react-sortable-hoc --save 引入 import { arrayMoveImmutable } from array-move import { SortableContainer, SortableElement, Sort…

智能汽车软硬件产品CES展示汽车技术新亮点

智能汽车是汽车产业发展的新趋势&#xff0c;是未来汽车发展的必然方向。智能汽车是指搭载了先进的传感器、控制器、执行器等部件&#xff0c;并融合了人工智能、自动驾驶等技术&#xff0c;能够实现部分或完全自动驾驶、智能网联等功能的汽车。 近年来&#xff0c;智能汽车技…

CDN原理探究

来源于百度&#xff1a; https://baike.baidu.com/item/%E5%86%85%E5%AE%B9%E5%88%86%E5%8F%91%E7%BD%91%E7%BB%9C/4034265?frge_ala 通过上图&#xff0c;我们可以了解到&#xff0c;使用了CDN缓存后的网站的访问过程变为&#xff1a; 用户向浏览器提供要访问的域名&#xff…

基于springboot实现的健康监控管理系统

一、系统架构 前端&#xff1a;html | bootstrap | jquery | css 后端&#xff1a;springboot | thymeleaf | mybatis 环境&#xff1a;jdk1.8 | mysql | maven 二、代码及数据库 三、功能介绍 01. 体检测评 02. 运动处方 03. 运动处方明细 04. 运动处方-打卡…