语义解析:自然语言生成SQL与知识图谱问答实战
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.2.1 NL2SQL任务及方法

NL2SQL(Natural Language to SQL),也叫Text2SQL。简单来说,NL2SQL的任务就是在给定数据库(Context)的情况下,将用户的自然语言查询语句转化为可执行的SQL语句。这个任务在NLP领域中属于语义解析(Semantic Parsing)范畴。本小节将根据数据库中表的数量以及数据领域等维度对NL2SQL任务进行分类,介绍NL2SQL任务中的一些重要节点和前沿进展,并且结合当前工业界的一些产品,介绍NL2SQL技术的相关应用情况。

1.NL2SQL的任务

首先我们以一个简单的SQL查询场景为例,向大家直观地展示NL2SQL的任务。表1-1是会员信息表,表中内容包括会员属性的常见字段,如姓名(Name)、性别(Sex)、所在城市(City)、身高(Height)。用户想要从表中查询和获取相关会员的多种信息。

表1-1 会员信息表

针对上面的会员信息表,用户可以使用如下自然语言查询语句。

问题:北京男会员的平均身高是多少?

NL2SQL系统需要能够理解上述问句的含义,并结合给定数据库(即上面的会员信息表)将上面的问句转换成如下SQL查询语句:

根据SQL执行结果将适当的信息返回给用户,这就是NL2SQL系统所要完成的主体任务。

2.NL2SQL分类

接下来从表格数量、数据领域、对话轮数几个维度来对NL2SQL任务进行分类。按照数据库中表的数量,NL2SQL可以分为单表NL2SQL和跨表NL2SQL。

1)单表NL2SQL:数据库中只包含一张表(单表数据库)。

2)跨表NL2SQL:数据库中包含多张表。

目前很多表格问答(比如WikiSQL)任务属于单表NL2SQL任务,比较简单。而跨表NL2SQL任务由于涉及多张表的复杂信息,并且需要考虑表的主外键连接,因此仍然是待攻克的前沿难题。

表1-1所展示的示例只涉及一张表,很明显属于单表NL2SQL任务。我们以其为基础,通过扩展得到表1-2和表1-3所示的跨表NL2SQL任务示例。

表1-2 跨表NL2SQL任务示例(会员消费表)

表1-3 跨表NL2SQL任务示例(会员信息表)

在上述跨表NL2SQL任务场景里,除了开始的会员信息表以外,还增加了会员消费表,两张表之间通过会员编号(member_id)列进行主外键连接。如果用户用自然语言查询“北京男会员的平均消费情况”,则该查询请求将涉及两张表的联合查询,情况会比单表查询复杂一些。这对NL2SQL系统的跨表语义理解能力提出了挑战。相比单张表,多张表涉及的信息量更大,各表之间的字段可能存在表述相似的情形,如何提升模型处理更大量表格信息的能力,以及从众多相似字段中更精准地识别目标字段的能力,是跨表NL2SQL技术需要解决的问题。

按照数据领域可以分为单域NL2SQL和跨域NL2SQL。

1)单域NL2SQL:系统只能应用于单个领域,无法有效处理不同领域的数据。

2)跨域NL2SQL:系统可以处理不同领域的数据,例如NL2SQL系统可以将电网领域的数据训练的模型有效地迁移到人力资源领域。

相比单域NL2SQL系统,跨域NL2SQL系统的搭建具有不小的难度和挑战。在不同的领域场景中,用户的自然语言表述风格会有很大的不同。例如:

问题1北京男会员平均花了多少钱?

问题2湖北省有多大?

在NL2SQL系统中,为了适应不同领域、不同语言的表达风格和内容,模型需要学习用户自然语言问句中的常见“模式”,即问法、风格、常见指代等,这就需要大量领域内的标注数据集来让模型学习这些“模式”。例如在上述两个问题中,用户的自然语言查询语句中提及的列名(字段)并没有出现在数据库中。其实上述两个问题分别要查询的是“消费金额”和“占地面积”。这就要求我们的系统具备众多不同的领域知识,才能在迁移至新的领域时不至于出现“理解”偏差。而寄希望于模型兼顾所有领域的知识,这其实是一件非常难以应对的挑战。

按照交互方式可以分为单轮NL2SQL与多轮NL2SQL。

1)单轮NL2SQL系统:比如“一问一答”交互方式,用户和系统的交互只有一轮。

2)多轮NL2SQL系统:比如“对话式”交互方式,用户和系统的交互不止一个问题,存在多轮交互,并且可能多个问题之间存在相互关联的上下文信息。

多轮NL2SQL系统与单轮NL2SQL系统的主要区别是在理解当前查询的基础上,系统对历史查询能够有较合理的“回溯”,利用历史信息辅助当前信息给出更精准的回答。

图1-6所示为一个多轮NL2SQL系统的基本演示。可以直观地看到,对于用户给出的查询“那看看他们的消费能力吧。”,系统必须结合前一次的查询结果,才能够将“他们”准确地对应到“2315个客户”,从而完成正确的推理和精准的展示。

图1-6 多轮NL2SQL系统演示

3.NL2SQL领域的经典算法

NL2SQL作为前沿领域任务,它的发展也会带来与之相关的数据竞赛的蓬勃发展。在各个领域的数据竞赛中,SOTA(State-Of-The-Art)算法模型一般代表着该领域最先进的算法解决方案。因此,下面通过介绍NL2SQL相关竞赛中的SOTA方案来展现NL2SQL领域的前沿进展。

(1)X-SQL

X-SQL模型来自WikiSQL数据集的历史SOTA解决方案,作者为微软团队的开发者。该算法是一个限定于单表NL2SQL任务的模型架构,推出后随即成了众多单表NL2SQL数据集上的流行解决方案,因此十分具有代表性。

WikiSQL中的SQL查询语句形式较为简单,因此可以较容易地尝试将SQL语句的不同部分采用多任务(Multi-Task)的方式进行分别“预测”。X-SQL的模型框架如图1-7所示。

图1-7 X-SQL模型框架

X-SQL模型主要由3部分组成:用于输入文本编码的编码器层(Encoder Layer)、基于结构化信息的上下文强化层(Context Reinforcing Layer)和输出层(Output Layer)。

编码器层采用了MT-DNN作为编码器,输入为自然语言问句与结构信息的拼接,其中结构信息的构造形式为“特殊Token(例如[SEP])分割的数据库中的表和列字段组成的文本字符串”,输入样例如图1-8所示。由于X-SQL的设计是针对WikiSQL这类单表特点的数据集,因此这样的拼接一般能对数据库中的表进行完全覆盖。

图1-8 X-SQL模型输入样例

在图1-8所示的输入样例中,[CLS]、[SEP]、TEXT和REAL为特殊词元(Token)。其中[CLS]和[SEP]分别表示“分类”Token和“分隔”Token;TEXT和REAL表示列名字段的数据类型。

上下文强化层的作用是对输入表字符串进行上下文相关的编码表征,具体的做法是将模型输入的[CLS]特征向量与经过矩阵运算“聚合”后的列名向量进行叠加,得到最终用于分类的特征向量。

输出层是X-SQL模型的最关键组件,它的做法是将SQL语句的生成转化为若干个分类器,通过优化各个子分类器来完成NL2SQL的任务。具体来说,X-SQL构建了若干个分类器,分别完成列名的选取、聚合操作的选择、条件符号的选择等任务,将用于分割列名的特殊Token([SEP])以及句子表征Token([CLS])作为子模型的输入,通过多任务的联合优化完成SQL语句的生成任务。

X-SQL模型是众多将NL2SQL任务改造成分类任务的工作代表,并且在单表数据集上取得了突破性的提升。当然,对X-SQL的改进工作一直在进行,例如可以将编码器层里的MT-DNN替换为当前主流大型预训练模型(BERT、Roberta、XLNet等),以增强底层的文本特征抽取能力,构造更适合的多任务学习框架等,甚至增加用于嵌套结构预测的子模型来完成复杂SQL查询生成任务。

(2)SeaD

SeaD模型也是WikiSQL数据集上表现较好的一个解决方案。模型来自蚂蚁金服算法团队,算法框架如图1-9所示。

图1-9 SeaD算法框架

SeaD模型是一种端到端的编码器-解码器(Encoder-Decoder)翻译模型。通过构造融合了自然语言问句和数据库信息的文本输入,以及优化一个Seq2Seq的目标函数,利用该目标函数完成自然语言问句到SQL查询语句的生成任务。

在模型输入端,和X-SQL模型类似,SeaD构造的输入形式也是“自然语言问句与列名的拼接”,二者的主要区别在于:SeaD将具体的列名通过构建的映射表进行了映射,因此输入中不再出现具体的列名字段,而是用表征列名的特殊Token来代替列名字段。

同样,在输出端,翻译模型的输出中也不包含真实的列名,而是需要通过转译的列名来映射Token。在完成翻译模型的输出后,需要再次通过映射表来生成最终的SQL查询语句。

根据作者的描述以及我们对模型成果的复现,可以总结出关于SeaD解决方案的以下几个要点。

Seq2Seq翻译架构简洁、高效,比较适合简单的单表NL2SQL任务。

列名映射表降低了翻译模型的拟合复杂度。

适当的数据增强(列名增删改、Text和SQL的实体顺序打乱)对于翻译模型的效果提升显著。

(3)IRNet

IRNet是一种基于“中间表达”的面向“复杂有嵌套SQL查询”的NL2SQL任务解决方案。“复杂有嵌套”的NL2SQL数据集代表有Spider数据集、CSpider数据集、DuSQL数据集等。它们的特点是SQL查询语句通常为包含多个“子查询语句”以及条件语句的复杂结构。由于单表(X-SQL、SeaD等)的架构设计上的种种限制,无法直接应用这类数据集。因此,需要一种新的架构来适应这类数据集的复杂数据形式。

IRNet与X-SQL均出自MSRA(微软亚洲研究院)的团队。IRNet模型架构如图1-10所示。

IRNet可以解决“复杂有嵌套”SQL查询的生成难题,其关键是SemQL——中间表达语言。SemQL是连接自然语言和SQL查询语句的一个重要角色,它巧妙地构建了一座自然语言到SQL结构化语言的沟通桥梁。SemQL的语法结构设计在样例中可以直观体现,如图1-11所示。

对于样例中的自然语言输入,IRNet并不是直接生成相应的SQL查询语句(见图1-11a),而是根据特定的语法规则,构建一种抽象语法树(见图1-11b)。在编解码过程中,以列名为根节点,根据语法树进行特定规则的“分裂”(树的构建),从而将NL2SQL任务转化为规则序列的构建过程。具体的构建过程将在第6章详细讲解。

IRNet的贡献可以表述为:通过构建“中间表达SemQL”结构,先预测SQL骨架,再预测SQL实体,实现针对“复杂有嵌套”NL2SQL任务的由粗到细的过程。

(4)RATSQL

RATSQL也是针对“复杂有嵌套”NL2SQL任务的,仍然来自微软算法团队。它的主要贡献有三点。

1)更合理的模式链接(Schema Linking)。

2)基于GNN(图神经网络)的Schema Graph(模式图)信息嵌入。

3)基于A和B设计的Relation-Aware-Transformer模型。

模式链接是一种将自然语言问句中的词元与Schema中的表名和列名进行“匹配对齐”的操作。Schema Graph信息嵌入指的是将数据库中具有主外键关联的不同表,以表名和列名作为节点构建图的连接形式,并通过GNN进行表示,之后嵌入到模型的输入表征中。

RATSQL利用图神经网络强大的表征能力构建Relation-Aware-Transformer模型,深度融合了不同表之间的连接关系,同时在解码过程中,采用了树形解码(Tree-Structure-Decoding)来生成SQL对应的抽象语法树(Abstract-Syntax-Tree,AST),在传统LSTM(长短期记忆网络)的序列建模能力基础上,引入了与当前节点相关的节点历史解码信息进行增强,在“复杂有嵌套”NL2SQL任务上取得了较为优异的成绩。

图1-10 IRNet模型架构图

NL2SQL技术路线的发展演进,可以以深度学习技术的兴起作为节点或者分界线进行总结和划分。深度学习技术的引入,使得NL2SQL技术路线能够更有效地利用数据库的Schema信息以及大规模预训练模型的知识表征能力,从而让NL2SQL技术的落地实现成为可能。深度学习兴起之前,系统大多基于规则实现,与数据库的Schema无关联,采用模板+简单统计分析模型;深度学习兴起之后,出现端到端的深度学习系统,采用大规模预训练模型。

近年来,随着大数据技术的兴起以及算力的飞速提升,基于深度学习(Deep-Learning-based)的方法被广泛应用于自然语言处理领域的各类基本任务中,并取得了大量不错的成果。对深度学习来说,似乎任务的效果仅与当前领域数据的数据量相关。也就是说,在标注数据(或者数据增强后的数据)足够的情况下,深度学习可以完成自然语言处理领域内的任何任务。

图1-11 SemQL语法结构样例展示

NL2SQL领域也不例外,当前由深度学习加持的各类算法模型已经“攻克”著名的单表NL2SQL数据库WikiSQL,不断刷榜的SOTA方法让我们乐观地感觉到,NL2SQL难题的瓶颈似乎已经被突破。

然而,随着Spider数据集以及更多复杂的NL2SQL数据集的发布,我们的最新模型(例如IRNet、SyntaxSQLNet、GNN等)虽然也能达到一定的效果,但是离“攻克”复杂SQL查询距离尚远。NL2SQL任务仍然是研究者不断投入的热门领域,越来越多的专家学者把NL2SQL作为解决“人机交互”的必由之路,试图给出更加完善的解决方案。