likes
comments
collection
share

数据库的自然语言接口——构建NLIDB的基础知识

作者站长头像
站长
· 阅读数 9

本章的主要目的是帮助读者形成对NLIDB的高层理解,并更好地理解和利用本书中介绍的技术和方法。我们首先在第2.1节描述了一个示例数据库以及针对数据库的示例输入问题。然后在介绍本书剩余部分将要使用的术语之前,我们介绍了基线NLIDB的常见架构(第2.2节)。最后,在第2.3节中,我们描述了一个基本的逐步构建过程,以构建针对示例数据库处理示例问题的基线NLIDB。

示例数据库

考虑一个具有图2.1所示模式的数据库。这个简单的数据库只包括三个表,每个表有两到三列。即使对于这样一个简单的数据库,人们也可以问关于单个高中学生或他们之间关系的各种各样的问题。表2.11列出了针对数据库的一些可能的输入问题以及可以从数据库中检索正确输出的相应SQL查询。可以看到,尽管这些问题长度相似,但相应的SQL语句的复杂性差异很大。在本章的其余部分,我们描述了构建基本NLIDB的步骤,该NLIDB以这些问题作为输入,并将其转换为对数据库的SQL查询。我们还将讨论构建这样一个NLIDB的关键挑战,提供额外的示例。

数据库的自然语言接口——构建NLIDB的基础知识

数据库的自然语言接口——构建NLIDB的基础知识

自然语言接口数据库的解剖

数据库的自然语言接口——构建NLIDB的基础知识

图2.2描述了基于管道的基本NLIDB的关键组件以及它们之间的连接。如图所示,NLIDB的核心包括三个主要组件:第一个组件是查询理解,它将给定的自然语言问题转换为内部逻辑表示,通常称为查询解释。第二个组件是查询翻译,它将每个查询解释转换为相应的结构化查询,然后可以针对底层数据存储执行。最后一个组件是结果显示,将执行的查询结果返回给用户。在本书的后面部分,我们将介绍最近的方法,其中关键组件,特别是查询理解和查询翻译,被构建成一个单一的端到端模型。

除了前述的三个核心组件外,现实世界中的NLIDB通常还包括其他组件。首先,查询理解和查询翻译可能依赖于外部知识来更好地解释输入问题。外部知识可以基于底层数据库或外部来源(例如,DBPedia)自动构建。外部知识也可以直接由用户提供,例如同义词词典。其次,NLIDB还可以包括交互生成,以生成其答案的解释,并从用户那里获得反馈。解释通常与结果一起显示。用户反馈可以是隐式的(例如,根据用户行为如查询历史归纳得出)或显式的(例如,通过UI交互提供的用户输入)。

构建一个NLIDB

在本节中,我们逐步描述了如何在基于管道的NLIDB中构建上述关键组件。在第4章中,我们将讨论如何将关键组件的功能构建成一个单一的端到端模型。在实际应用中,NLIDB可能会采用这两种方法的组合,以最佳平衡诸如质量和运行时效率等多个因素。

查询理解

一个简单而有效的方法是在更基本的句法结构分析的基础上构建查询理解,例如词性标注和依存句法分析。图2.3、2.4、2.5和2.6显示了表2.1中示例输入问题的依存句法树,以及各个句法树的词性标记。现在我们详细描述如何利用这样的句法结构来生成查询解释。

数据库的自然语言接口——构建NLIDB的基础知识

解析树节点分类

第一步是识别可以映射到查询组件的解析树节点,并根据它们可以映射到的相应SQL组件将它们分类为不同类型。表2.2总结了常见类型的解析树节点和它们可能映射到的相应SQL组件。 解析树节点的类型高度依赖于其词性标记(POS)。一般来说,普通名词(例如,NN,NNS)通常是Name节点;专有名词(例如,NNP,NNPS)通常是Value节点;限定词(DET)通常是Quantifier节点;形容词(JJ)通常是Quantifier节点;动词(例如,VB)通常是Select节点或Function节点。

数据库的自然语言接口——构建NLIDB的基础知识

解析树节点映射

第二步是将所有解析树节点映射到相应的数据库构件中。这种映射的结果称为查询树,是一种特定类型的查询解释。对于所有类型的节点的映射过程,不包括Name节点和Value节点,通常与底层数据库无关,并依赖于简单的映射规则,例如表2.3中的规则。

Name节点和Value节点的映射可能更加复杂。这种映射不仅依赖于底层数据库本身,而且通常需要考虑整个查询,并且有时需要用户输入来解决可能的歧义或弥合输入问题与底层数据库之间的语义差距。例如,如果用户提出的问题是“John在哪个年级?”并且在图2.1中的示例数据库中存在多个名为“John”的学生,则系统可能会返回所有学生的信息,或者请求用户输入以决定感兴趣的学生。

促进Name和Value节点映射的一种方式是构建一个翻译索引。翻译索引实质上是数据库构件的语义索引,包括关系和属性的名称以及实际值。它为每个数据库构件生成变体,并维护一个允许值的逆向查找的映射。变体的生成可以基于一系列简单的映射字典、领域特定的本体论和更复杂的自动变体生成。

数据库的自然语言接口——构建NLIDB的基础知识

表2.4展示了与图2.1中示例数据库对应的可能翻译索引的片段。Highschooler关系的变体基于预定义的映射字典,Highschooler.grade属性的值的变体来自教育领域的本体论,Highschooler.name属性的值的变体基于Person类型的自动变体生成。这样的翻译索引有助于弥合输入问题和底层数据库之间的语义差距。此外,每个变体通常还与一个置信水平相关联,指示映射的正确性。系统可以利用这样的信息来解决多种可能解释时的歧义。例如,给定输入问题“列出所有高中学生的名字?”,根据翻译索引,我们可以将“高中生”映射到Highschooler并具有很高的置信度,“学生”映射到Highschooler并具有较低的置信度。在这种情况下,我们将前者的映射排在后者之前。

图2.7、2.8和2.9分别展示了表2.1中问题Q1、Q2和Q3的可能解析树节点映射。我们保留相应解析树节点的依存关系以用于下一步——查询翻译。为简单起见,我们删除了所有未映射到数据库构件的解析树节点,除了任何根节点。

数据库的自然语言接口——构建NLIDB的基础知识

除了使用映射规则和翻译索引外,还可以构建更复杂的关键词映射,例如基于词嵌入和深度神经网络的方法。我们将在第4章中更详细地描述这些技术。

查询树重构

对于与简单选择查询对应的输入问题,上述两个步骤已经足够。然而,在某些情况下,为了方便查询翻译,我们可能需要调整查询树结构,以考虑(1)可能存在的解析树错误和(2)原始输入问题中的遗漏,以便促进查询翻译,正如先前提出的那样。

例如,图2.10展示了与表2.1中的问题Q5相对应的查询树。在原始问题中,“超过5个朋友”这个表达方式更为简洁,也可以说更自然地表达了“朋友的数量超过5个”的语义。由于该表达隐含地描述了聚合,因此对应于前一表达的查询子树不包含函数节点。因此,直接将查询树转换为SQL子句将导致错误地省略聚合函数。解决此问题的一种方法是重构查询树,添加被省略的计数函数节点,并移动节点,使得名称节点出现在操作符节点之前,得到调整后的查询树如图2.11所示。

数据库的自然语言接口——构建NLIDB的基础知识

查询翻译

查询翻译是在查询树之上操作的,它生成最终可执行的结构化查询。根据查询树,确定最终可执行的结构化查询的查询类型,并且针对每种类型可能应用不同的查询翻译过程。

简单的SELECT查询

当查询树既不包含函数节点也不包含量词节点时,相应的结构化查询将是一个简单的SELECT查询,不包含聚合函数或子查询。对于这样的查询,使用以下步骤进行翻译是直接的:

SELECT子句: 将与Select节点下的属性名称相对应的每个Name节点(NN)添加到SELECT子句中。

FROM子句: 将与关系名称相对应的每个Name节点(NN)添加到FROM子句中。

WHERE子句: 对于每个操作符节点(ON),根据附加到节点的Name节点-Value节点对向WHERE子句添加谓词。对于未连接到操作符节点(ON)的每个Value节点(VN),使用“=”函数添加一个谓词。

JOIN子句: 如果在FROM子句中添加了多个关系,则根据数据库架构(参见第3.2节中主键和外键的定义),为每对关系之间的外键-主键添加一个JOIN子句。这一步也称为联接路径推断。

根据上述过程,我们可以从诸如图2.7和2.8所示的查询树中获取输入问题Q1和Q2的正确SQL语句。

简单聚合查询

简单聚合查询是指包含一个或多个聚合函数但没有子查询的查询。当查询树仅包含一个函数节点且没有量词节点时,相应的查询通常是一个简单的聚合查询。图2.1中的Q3和Q4都是简单的聚合查询。简单聚合查询的翻译比简单SELECT查询略微复杂一些。

SELECT子句: 将Select节点下没有与Function节点(FN)连接的每个Name节点(NN),对应于属性名称,添加到SELECT子句中;如果仅有一个Function节点(FN)到根节点的路径仅包含一个Name节点,则将相应的SQL函数添加到SELECT子句中。

FROM子句: 将与关系名称相对应的每个Name节点(NN)添加到FROM子句中。

WHERE子句: 对于每个操作符节点(ON),根据附加到节点的Name节点-Value节点对向WHERE子句添加谓词。对于未连接到操作符节点(ON)的每个Value节点(VN),使用“=”函数添加一个谓词。

JOIN子句: 如果在FROM子句中添加了多个关系,则需要为关系添加JOIN子句。除非问题明确定义了连接条件,否则我们根据数据库架构检查关系之间的路径,并相应地添加JOIN子句。这一步也称为联接路径推断。

ORDER BY子句: 如果函数节点(FN)对应于max或min,则添加ORDER BY count( ) DESC LIMIT 1用于max,以及ORDER BY count( ) ASC LIMIT 1用于min。

HAVING子句:如果函数节点(FN)连接到一个操作符节点(ON),则将相应的谓词添加到HAVING子句中。

外部知识

为了正确执行查询理解,NLIDB需要理解底层数据库,并了解用户对应于底层数据库的领域可能具有的常见知识。

与NLIDB相关的外部知识包括:

  1. 语言知识,如WordNet [13](英语的词汇数据库)和FrameNet [14](提供单词的语义框架);
  2. 世界知识,提供有关实体特定实例的显式知识,例如YAGO [15]、Freebase [16]、DBPedia [3]和Wikidata [17]提供的知识(例如,“美国的首都是华盛顿特区”);
  3. 常识知识,例如ConceptNet [18]描述的隐含一般事实(例如,“房子通常有窗户”);
  4. 领域知识,包括特定领域的事实,也称为领域特定本体论,例如生物医学领域的国际疾病分类[19]和金融领域的金融业务本体[20]。

在2.3.1节介绍的翻译索引是捕获外部知识的一种简单方式。我们可以根据底层数据库和外部资源构建翻译索引。例如,在表2.4中显示的翻译索引中,“Highschooler.grade = 9”中,“grade 9”和“9th grader”等变体可以根据领域知识和底层数据库架构[21]自动生成,而“freshman”等变体需要通过映射字典显式添加。这种外部知识是使NLIDB能够处理具有底层数据库中不可用的世界知识的问题的关键,例如“Who are all the freshmen?”中的“新生”概念。

在7.1节中,我们将讨论解决NLIDB中歧义问题的技术,通常通过利用外部知识。我们可以将外部知识作为一个单独的组件,如翻译索引,或作为考虑外部知识的机器学习模型的一部分,在更复杂的方式中考虑外部知识。

交互生成

在理想的情况下,NLIDB能够处理任意的输入问题,并正确地将它们转换为相应的结构化查询。然而,在现实中,NLIDB经常遇到无法处理的输入问题。在这种情况下,与许多以人为中心的人工智能系统一样,系统向用户解释它能够理解和不能理解的内容,并积极征求用户的反馈,该反馈可能是显式给出的,也可能是隐式的。

拼写纠正和查询自动完成是减少模糊和错误问题的常见技术。此外,一个常见的挑战经常导致NLIDB失败,即缺乏领域特定的知识,因为提前注入到NLIDB中的外部知识可能不足以满足需求。例如,迄今为止描述的示例NLIDB无法处理输入问题“谁是最受欢迎的高中学生?”,因为它无法对“最受欢迎的”进行分类和映射到相应的解析树节点。在这种情况下,它可以调用交互生成来通知用户它不理解术语“最受欢迎的”。然后,它可以要求用户重新表达问题,更明确地表达“最受欢迎的”语义,例如“谁是高年级拥有最多朋友的学生?”或“谁是被最多学生喜欢的高年级学生?”。每个查询重构都可以添加到其外部知识中,以更好地处理未来的查询。第7章将更详细地讨论用于查询消歧和查询建议的交互技术。

此外,即使NLIDB已成功理解并翻译了输入问题,系统也可以支持用户与返回的结果进行额外的交互,下面将详细介绍。

结果生成

一旦成功获取了结构化查询,系统将查询发送到数据存储中,然后执行查询并将执行结果返回。结果生成然后将结果返回给用户,可能还会提供额外的信息,取决于执行结果。

非空结果

如果查询的执行结果不为空,结果生成可以直接将结果行返回给用户。此外,如前文所述,它可能支持以下附加交互,以改善系统的可用性:

结果描述:为了提供更自然的交互体验并帮助用户更好地理解答案,可以返回结果的自然语言描述,而不是以表格形式的原始输出。

结果可视化:结果可以可视化,以帮助用户更好地理解和与查询答案交互。

结果解释:可以提供关于结果获取方式的解释,以帮助用户更好地理解和信任返回的结果。对于输入问题,最基本的解释可以通过突出显示映射到数据库构件或非平凡查询片段的原始输入问题中的关键词来生成。

结果探索:可以提供额外的用户交互,如对查询结果进行排序和钻取,以允许用户在不需要发出其他查询的情况下进一步探索查询结果。

在第6章中,我们将全面审查从数据生成文本的技术,通常用于结果描述。在第7章中,我们将更详细地讨论与结果可视化、解释和探索相关的技术。

数据库的自然语言接口——构建NLIDB的基础知识

空结果

如果执行结果为空,向用户解释导致空结果的可能原因非常重要。空结果的一个可能原因是输入问题的翻译查询错误。通过利用之前描述的解释技术,用户可以检查系统对原始输入问题的查询理解是否正确反映了原始输入问题的语义。空结果的另一个可能原因是原始输入问题的答案确实为空。在这种情况下,系统可以提供额外的帮助来帮助用户获取非空结果。系统可以根据查询历史提供查询建议,例如之前发出的类似查询的非空结果。系统还可以通过查询放宽来帮助,可能基于用户交互(例如,类似于IQR [22])。

图2.12显示了上述不同选项的示例。通过突出显示执行的查询结果的自然语言描述和空结果的替代查询来解释查询理解。

数据库的自然语言接口——构建NLIDB的基础知识

总结

在本章中,我们介绍了一个NLIDB的常见架构,它包括查询理解和查询转换,并提供了一个逐步构建基本实现的指南。我们还讨论了如何通过利用用户反馈和外部知识来扩展这样一个基线实现,以处理查询理解和结果显示中的挑战。在本书的其余部分,我们将更深入地讨论相关主题。具体而言,在第4章中,我们将深入讨论与查询理解和转换相关的各种现代技术,包括端到端神经模型,在第6章中,我们将介绍从数据生成自然语言的方法。在第5章中,我们将讨论评估NLIDB各个方面的方法。最后,在第7章中,我们将回顾NLIDB中各种交互性方面,包括对话式NLIDB以及适用于提高NLIDB效果和效用的常见交互技术。

我们将任何感兴趣的读者引荐到一本较早的书籍[2],其中对传统的NLIDB进行了全面的讨论。