1. 首页
  2. >
  3. 数据库技术
  4. >
  5. SQL SERVER

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

作者 | 幻风编辑 | 唐里

论文标题:X-SQL:reinforce schema representation with context

论文地址:https://arxiv.org/pdf/1908.08113


1、背景介绍

如果有人问现在是一个什么样的时代?那么很多人都会回复现在是一个大数据的时代,如此海量的数据,我们将其大多数都存储在数据库中。在日常生活中我们经常和数据库进行交互,比如网络购物、订票、订餐等等,绝大多数操作都是在后台封装好的SQL 模板,这样我们的操作常常会受限于预先设好的SQL模板,不具备灵活性,为了解决这个问题,我们可以使用NL2SQL的技术方案,用户只需要通过自然语言表达意图,NL2SQL会将其转换为结构化查询语句SQL,这样会大大缩短用户与数据库之间的距离。

在自然语言处理领域,上述自然语言-SQL任务被称为语义解析,即把自然语言自动转化为一种机器可以理解并执行的SQL表达形式。


2、问题难点

结构化查询语言SQL是由人类设计的,它句法要求严格,一条SQL语句往往由多个部分组成,彼此之间相互关联,一旦某个部分出现问题,那么整体都会执行失败,所以如何将自然语言自动转为SQL表达并且正确执行是非常困难的。

本文我们将介绍微软在该领域的最新进展,它将自然语言到 SQL 语句的生成分解为六个子任务,彼此之间相互约束,保证模型输出空间最大限度地满足SQL语言要求。该任务由 Pengcheng He, Yi Mao, Kaushik Chakrabarti, Weizhu Chen 四位研究员完成,并且在数据集WikiSQL上达到了目前最佳表现,超越人类水平。


3、数据集WikiSQL介绍

WikiSQL 是 Salesforce 在 2017 年提出的大型标注 NL2SQL 数据集,也是目前规模最大的 NL2SQL 数据集。它包含了 24,241 张表、80,645 条自然语言问句及相应的 SQL 语句。该数据集不涉及高级用法,Question 所对应的正确表格已经给定,不需要联合多张表格,图一是其中的一条数据样例,包括一个 table、一条 SQL 语句、SQL语句所对应的自然语言语句及该条SQL语句的执行结果。

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

图一


4、主要思路

针对自然语言到sql的解析问题,本论文提出了一种新的网络体系结构x-sql。x-sql提出利用bert风格的预训练模型(MT-DNN)的上下文输出来增强结构模式表示,并结合类型信息来学习用于下游任务的新模式表示。因为SQL语法的一部分受限于结构化数据模式的类型,例如,聚合器min只与数字列一起出现,而不能与字符串的类型列一起出现,所以我们必须要对其进行约束,论文中显性的将列类型添加到模型中。

本论文中模型包含三层结构,分别是SequenceEncoder、ContextEnhancedSchemaEncoder、OutputLayer(输出层),其中输出层完成SQL语句的生成,我们将其分为6个子任务(select-column, select-aggregation, where-number, where-column, where-operator, and where-value),这六个任务彼此之间相互结合,彼此制约。下面我们将按照论文对这三层结构,6个子任务进行解析。


5、三层结构

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

第一层结构是Sequence Encoder(序列编码器),在该结构中,我们为每个表增加一个empty列,然后段编码替换为类型编码,学习四个类型:question,categorial column,numerical column和empty column,该模型输出h_[CTX], h_q1, ···, h_qn, h_[SEP], h_C11, ···, h_[SEP], h_C21, ··· h_[SEP], ···, h_[EMPTY], h_[SEP],其中问题中每一个词编码为h_qi,然后h_cij表示列 i 编码第 j 个标记,因为每个列名可能包含多个标记。

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

第二层结构是Context Enhanced Schema Encoder,该结构用于增强在equence Encoder(序列编码器)得到的H_[CTX],虽然在序列编码器的输出中已经捕获了某种程度的上下文,但这种影响是有限的,因为自我关注往往只关注某些区域。另一方面,[ctx]中捕获的全局上下文信息具有足够的多样性,因此用于补充序列编码器中的模式表示。通过这种方式可以捕获到哪一个查询词与哪一列最相关,从而得到增强的语义表示HCi它的计算过程如下图所示:

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

第三层结构是Output Layer,它的核心是完成sql语句的生成,它将SQL语句分为六个子任务,对于每个子任务首先使用下面的子网络结构得到使用融合hci和hctx的rCi,它的模型图如下所示:

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

需要注意的是每个子任务都具有一个这样的子网络,计算是针对每个子任务单独进行的,以便更好地将模式表示与每个子任务应该关注的自然语言问题的特定部分对齐。该子结构的计算机构如下所示:

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

当我们完成这个子结构之后,我们就可以完成之后的六个子任务了


6、六个子任务

第一个任务S-COL,这个任务表示SQL语句查询表的哪一列,我们使用前面得到的rci来完成这个子任务,使用softmax来找到最可能的列,计算公式如下所示:

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

第二个子任务S-AGG,这个任务表示对第一个子任务使用什么函数操作,比如min、max,这里就需要注意我们前面提到字符串函数不可以应用min、max的问题,为了解决这个问题,我么们需要显式的将任务一得到的列类型Ectype嵌入到模型中,与其他子任务不同,我们在这里使用hci而不是rci,它的计算公式如下所示:

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

其中 E_Ci^T 就是任务一的类型,从公式可以看出来,这里就相当于给任务二增加了类型约束,使得任务二预测的函数操作不可以和任务一得到的列类型相矛盾。

其余4个任务w-num、w-col、w-op和w-val一起决定了SQL语句的where部分,其中w-num决定了对表的几列进行约束,w-col表示对哪几列进行约束,w-op表示对这几列的操作符,比如>、<、=等等,w-val表示对这几列进行约束的值。

首先这w-col、w-op和w-val这三个任务是依赖w-num的,因为w-num决定了对几列进行约束,这样它们三个只需要取softmax最大的那几个就可以了。然后w-col和w-op也进行依赖,这个和任务二w-agg一样,字符串类型的列是不可以使用<或者>的,但是本论文实验过程中,这里并没有多少改善,所以我们这里可以不进行约束。

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

最后一个任务就是w-val,这个值是多少,只能来源于query的语句,所以这里我们预测value值在query语句中的起始位置,计算公式如下:

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

至此为止,本论文的三层模型和六小任务就介绍完成了,我们前面介绍过它的模型效果已经超越人类表现了,我们来一下它的实验结果。


7、实验结果

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

因为在这个论文之前,在该数据集上的最佳表现的算法模型是SQLNet以及SQLova,所以本论文只能它们两个进行了比较,我们可以看出在验证集和测试集中X-SQL模型都有一个全面的提高。在没有EG的情况下,x-sql在逻辑形式精度上绝对提高了2.6%(83.3对80.7),在测试集上的执行精度提高了2.5%。如果使用了EG,xsql在逻辑形式准确性上仍然高出2.4%。

自然语言到 SQL 语句,微软只用六个子任务,结果超越人类水平

因为本任务使用六个子任务完成,所以对于SQLova与X-SQL在每个子任务的效果,我们可以看到每个子任务的准确性,并展示了一致的改进。特别是,任务w-col显示在没有eg的情况下绝对有1.1%的增益,在有eg的情况下绝对有1.7%的增益。另一个显著的改进是W-VAL任务,在没有EG的情况下绝对增加了1.2%,而在有EG的情况下绝对增加了2.0%。


8、总结

由于SQL语句的严格语法规范性,本任务将问题进行拆分,并且相互之间进行约束,从而得到了一个好的模型学习,在WikiSQL数据集上取得了一个好的进展,我们可以思考是否默写任务可以使用这种方式,比如NL2java,NL2python等等,或者我们可以增加更多的子任务,从而加强约束空间,得到更加严格的SQL语句。

虽然本任务取得好的效果,但是却有一些问题,比如为什么使用六个子任务,这是因为这个数据集只涉及到单表查询,想对来说语法比较简单,所以我们使用六个子任务就可以完成,但是如果有的数据集设计到多表联合查询,那么六个子任务是远远不够的,那么此时增加更多的子任务是否可以解决多表查询的任务,还是会成为负担,这些都是我们需要担忧的,但是无论怎么本任务所需的的结果证明这个模型效果和思想是不错的,我们可以借鉴或者进行升级,以此来帮助我们更好的解决自己的任务。