摘要:本篇文章将硬核解说M-SQL:一种将自然语言转换为SQL语句的多任务示意学习办法的相干论文。

本文分享自华为云社区《【云驻共创】M-SQL,一种超强的多任务示意学习办法,你值得领有》,作者: 启明。

数据集整体介绍

定义介绍

国际惯例,先来一段定(bai)义(du)介(bai)绍(ke):Text to SQL,顾名思义,就是在给定数据库(或表)的前提下,依据用户的发问,产生SQL语句。其数学形容如下:

令X示意用户的自然语言发问,D示意与发问相干的数据库(或表),Y示意其对应的SQL语句。

SQL语句生成工作能够表述为:对于每一组独立的(X,D,Y),将(X,D)映射到对应的Y。

用一个大家相熟的场景为例。假如咱们有一张学生信息表,咱们能够用自然语言发问:大于18岁的学生都有谁,模型须要返回一个与之相干的SQL语句,那么就是:

SELECT 姓名 FROM 学生信息 WHERE 年龄 > 18

场景分类

Text to SQL有很多种分类,其中一种是按问题分类

一种是上下文无关的(发问之间不存在关联):Spider

一种是上下文相干的(两个发问之间存在肯定关联):SparC

“上下文无关”是指发问之间没有任何的关联,而“上下文相干”是前后两个发问之间,存在一些指代关系或者说存在肯定的关联。

同样,咱们举一个简略的例子来阐明:

发问1:有预约的医生ID是什么?

SELECT physician FROM appointment

发问2:他们的名字是什么?

SELECT T2.name FROM appointment AS T1 JOIN physician AS T2 ON T1.Physician = T2.EmpoyeeID

以上就是一个上下文相干的例子,第一句的确定医生ID,第二句依据医生ID确定医生名字。

另一种是按畛域分类:单畛域 or 多畛域

如果所有的发问都是有对于航空方面的,这就是一个单畛域的数据集。而跨畛域数据集,则是在训练集当中可能有很多种畛域,在测试集当中也有很多种畛域,然而训练集中的畛域和测试集中的畛域不重合,这就要求咱们的模型具备肯定的泛化能力。

第三种是依照数据库进行分类

单表数据库:WikiSQL,其发问只针对一个表,或者是它所针对数据库当中只有一个表

多表数据库:Spider,其发问针对的数据库当中有许多个表,它所产生的 SQL语句可能波及到多个表之间的连贯。

第四种种分类是依照标注类型进行分类

最终后果:WikiTableQuestion

SQL语句:WikiSQL、Spider

有一些数据集没有给出相干的SQL语句,而是间接给出了一个后果。以后面的例子为例,“大于18岁的学生都有谁”,输入有可能是给出SQL语句,也有可能是最终后果:把这些人名都给列出来,而没有给出SQL语句,这其中波及到的“弱监督学习”,本次不做具体解说。

TableQA 数据集

本次要解说的论文所采纳的是一个TableQA数据集,它也是一个单表数据。也就是每一个发问都只针对一个表进行发问。TableQA和WikiSQL有有很多相似之处,然而也有肯定的差别,如下图所示:

论文概述

介绍完数据集之后,咱们来对论文中所提出的模型进行一个简略的介绍。

首先来思考这样一个问题:通过自然语言生成SQL语能够有什么办法?其实一个最简略的思路:输出端是自然语言句子,输入端是与之对应的SQL语句(依照SQL语句依照一个token一个token进行生成)。

比如说咱们后面那个例子,Encoder是“大于18岁的学生都有谁“,输入端是SELECT name FROM XX表 Y条件。

这个办法很简略,然而也随同着一些问题:SQL语句是结构化的查询语言,它是具备肯定的构造的,这和个别的语言生成工作是有肯定差异的。

对于个别的语言生成工作来说,如果变更其中的一两个词,可能它的语义不会产生太大变动。然而对于 SQL语句来说,如果某个词不一样了,那么其就可能就没有方法继续执行。所以咱们须要利用好SQL语句外部的一些语法信息,也就是构造信息。依照它的构造来进行生成,这就是论文当中所提出来的,依照 SQL的框架来进行生成。

M-SQL

因为TableQA数据集只针对单表,相当于From字句能够省略。大体能够分成两个局部,一部分是 Select子句,一部分是 Where子句。

其中Select的子句当中有两个局部:一个是所选取的表的名称,另一个是聚合操作。比如说咱们要求某一列的最大值、最小值或者是对某一列进行求和,就须要聚合操作来进行。

对于Where子句这一部分,咱们具体介绍一下:

$WOP:where 条件连接符(and /or / Null)

$COLUMN:数据库中的列名

$AGG:对选取列的操作(Null, AVG, MAX, MIN, COUNT, SUM)

$OP:where子句中的列值

依据对TableQA数据集进行统计,限定select中最多呈现2列、where中最多有3个条件:

SELECT ($AGG $COLUMN)*

WHERE $WOP ($COLUMN $OP $VALUE)*

M-SQL模型

此模型大抵可从下往上能够分成三块。

Encoder:对输出进行一个编码;采纳了一个简略的bert模型,版本是wwwm-ext。wwm意味着其应用的是一个全词笼罩的形式,而ext则裁减了它的训练集并使它的训练部署有所增加。

其输出局部包含:问题、列名。同样以后面“大于18岁的学生都有谁”为例,能够看到上图所示,T1至TL,前面跟着的是所发问的表当中所呈现的每一列它的列名,比如说这个表当中可能有姓名、学号或者年龄。另外,与bert输出不同的是它用 [XLS]去替换了[CLS]。

列示意:对于列的示意进行加强;因为每一列当中它可能会由多个token形成,比如说,一列的名字叫“姓名”,其可能是两个字,这两个字别离有两个embeding,那么如何把这两个embeding给它合并成一个embeding作为列的示意呢?咱们能够用后面的 XLS的示意来对列的示意进行加强,具体的做法如下:

先通过后面 XLS的示意,对这一列当中所有的token示意进行计算attention,attention计算出来之后再加上后面 XLS示意的 embeding,这两个之和就形成了这一列的加强的示意。

通过上述步骤之后,咱们就失去了问题当中,每一个token的示意,以及表格当中每一列的示意。

子模型:8个子模型及对这8个子模型进行1个多任务的学习。

后面提到,咱们能够将SQL语句宰割成不同的局部,而后每一部分别离进行生成,于是能够得出8个子工作,别离是:

• Select列数
• Where列数和连接符
• Select列
• Select列操作
• Where列
• Where每列的运算
• 值抽取
• 值匹配

接下来,咱们对这8个子工作别离介绍一下它们的做法。

工作一:S-num:Select中呈现的列数。[1、2](2分类)

首先是Select当中呈现的列数。对于TableQA数据集,Select当中呈现列数只可能是一列或者是两列,因而咱们能够当做是一个二分类的问题:利用 XLS的 embeding做线性变换,而后过sigmoid的失去它的概率。

工作二:w-num-op:Where中的连接符和条件数。[null-1、and-1、or-1、and-2、or-2、and-3、or-3](7分类)

第二个工作是Where当中呈现的连接符和条件数。所谓“连接符”,指的是“And”还是“or”等;条件的个数,指的是Where当中所呈现的“>”、“<”、“=”等等条件的个数。咱们能够将他们分成了7个类别,“-”后面的就是连接符,“-”前面的这些就是条件的个数。当然也能够把这两个工作进行离开,然而如果把这两个工作进行离开的话,成果与两个工作一起做相比,会大打折扣。

那么总共是有7个类型,就能够看成是7分类的问题,因而还是 XLS示意过一个线性变换,而后再通过softmax,就能够失去这7个类别上的概率分布。

第三个和第四个子工作是Select字句和Where字句当中呈现的列。咱们后面曾经预测了Select当中的例数,以及Where当中的例数,那么在这一部分咱们别离预测每一例所呈现的概率即可。

工作三:S-col:Select 中呈现的列

Select中呈现的列:利用咱们之前每一列失去加强的示意,通过一个线性变换,再过一个softmax就能够失去这一列所呈现的概率。

工作四:W-col:Where 条件中呈现的列

对Where条件当中呈现的列:同样,利用不同的线性变动来进行失去这一列它所呈现的概率。

工作五:S-col-agg:Select 中呈现的列的操作符

  • [Null, AVG, MAX, MIN, COUNT, SUM](6分类)

第五个工作是Select当中呈现的这些操作符,这些操作符也被称为是聚合操作。比如说,咱们能够求这一列当中所有数据的最大值、最小值或者求均匀、求和等等。

在TableQA当中,5种操作符加上NULL一共是6种,咱们能够将其看到是一个6分类的问题。同样,咱们对每一列的加强的示意做一个线性变换,而后再通过softmax就能够失去每一类的概率分布。

工作六:W-col-op:Where 条件中呈现的列对应的条件运算符

  • [> / < / == / !=](4分类)

对于Where条件当中呈现的这些运算符也是一样。这些运算符,包含这一类大于一个数或者小于一个数,或者是等于某个值,或者不等于某个值,一共是4类,咱们能够看作是一个4分类的问题。做法和之前的Select当中的运算符统一,也是给列的加强示意过一个线性映射再通过softmax失去4类的每一类的概率分布,从中的选取最大的作为这一列的运算符。

最初两个子工作就是服务于条件值预测。同样以咱们后面的例子为例,“大于18岁的学生都有谁”。最初的后果应该是Where条件当中有一个age > 18,那么咱们18应该怎么取得呢?作者就问题给它拆成了两个子工作:

工作七:从问题中抽取可能是值的短语

  • 应用0/1对问题中的Token进行标记(1示意值,0示意非值),每一组间断的

1标记的token作为一个整体

第一步就是从问题当中抽取出有可能是值的短语。比如说“大于18岁的学生都有谁”这个问题,那么这个子工作就是把“18”从问题当中进行抽出来。咱们能够采纳的办法是应用0和1对问题当中所呈现的token进行标记,比如说“大于18岁都有谁”中的“18”,咱们就把它标记成1,而后其余所有的token就把它标注上0,并对于问题当中咱们一个token的表述过一个线性变换,应用sigmoid的来预测它到底是1还是0。

工作八:将抽取出的短语和Where中呈现的列进行匹配

在工作七的根底上,咱们须要将抽取进去的短语与where当中所呈现的列进行匹配。

在前一个步骤,咱们曾经把“18”给它打上1的标签了,因而也就生成了“18”这个token序列。它是一个可能会呈现在某一个条件当中的value,然而它会呈现到哪一列之后,是这一步所要确定的事。

将取出来的短语与Where当中呈现的列进行匹配,如果短语当中它是由多个token形成的,就把所有的token的text示意求一个均匀。如下图,此公式相当于是对短语与where当中呈现的列求一个类似度,而后再过一个sigmoid。后面这个u是一个可学习的参数,过一个sigmoid就能够失去短语与列是否匹配:如果匹配就把短语作为列的值,比如说18就跟age匹配了,而后咱们就能够写age > 18。

Execution-Guided Decoding

咱们曾经对上述8个子工作做了简略的介绍。通过这8个子工作,咱们就能够失去一条SQL语句,并且保障它是合乎了语法规定的。然而它所产生的SQL语句有可能还是不能被执行。

因为SQL语句的外部可能还存在一些限度条件:

• SELECT子句中如果呈现string类型的列,则对应的操作不能是’sum’, ‘min’, ‘max’
• WHERE子句中如果呈现string类型的列,则对应的操作不能是‘<’, ‘>’
• SELECT子句和WHERE子句中呈现的列互不雷同(剖析数据集得悉)

在这些限度下,咱们能够采纳Execution-Guided Decoding的办法:在decode的过程当中,去掉那些不能被执行的SQL语句,比如说SQL语句执行进去的后果是空,或者压根就不能被执行,从而被会报错,这些SQL语句咱们就能够间接被摈弃,而选取合乎上述条件的概率最大的SQL语句。

试验后果

接下来是试验后果。

首先简略介绍一下其所采纳的评估指标,别离是LX、X还有MX。

LX,就是它的逻辑模式的准确率。如果所生成的SQL语句和标准答案的SQL语句完全一致,那么下面这两个操作正确;如果有一点不一样,比如说“>”写错了,或者是这一列选错了,那么这个例子即谬误。

X,就是它的执行后果的准确率。如果两条SQL语句,可能它的逻辑模式不一样(这两个SQL可能存在一些差异),但它的执行后果是统一的,那么也算预测正确。

MX,是后面LX和X的一个均匀。它有两个模型,一个是单个模型,一个是集成模型(前面的Ens)。通过Ensemble对屡次训练的后果进行集成,最终失去一个更好的后果。从图中咱们能够看到它比之前几种模型的后果都要好。

因为之前的模型都是基于WikiSQL进行实现的。咱们所采纳的TableQA与WikiSQL有一些不同,并且比WikiSQL要更难一些,所以之前的这些模型在TableQA对数据集上的成果并不是很好。

子工作的性能

下图对8个不同的子模型的性能做了比照:

咱们能够看到在每一个子模型上,它的成果都是十分不错的,当初通过Ensemble之后就能够达到更好的成果。

融化试验

在试验的最初一部分咱们做了一系列的融化试验。

从试验后果咱们能够看出,应用BERT-wwm-ext的版本比 BERT-base成果要好,应用XLS作为前置比CLS作为前置的成果要好。图中更上面局部是所应用的一些值的抽取的办法,以及一些值匹配的办法,咱们在上面给大家作更具体的介绍。

复现中的细节解决

接下来,咱们将介绍在复现过程当中的一些细节解决。

首先是数据预处理的局部。对于这个数据集来说,它的数据是不太标准的,有可能会呈现以下状况(括号中示意歧义局部):

• 数字:哪些城市上一周成交一手房超十五万平? (十五,15)
• 年份:你晓得10年的土地成交面积吗? (10年,2010)
• 单位:哪些城市最近一周新盘库存超过5万套? (5万,50000)
• 日期:哪个公司于18年12月28号成立? ( 18年12月28号,2018/12/28 )
• 同义:你能帮我算算芒果这些剧的播放量之和是多少吗?(芒果,芒果TV)

后面几个问题,能够间接依照肯定的规定来进行转换;而前面这些能够通过到数据库当中去找相干的品类词做一个替换。

值的抽取

在“值抽取”这一部分的,咱们尝试了很多种办法,比如说bert+crf的办法,bert+bilstm+crf,以及bert+半指针的办法。最终所采纳的还是0/1标记的办法,因为它的成果是最好的。

• bert + crf,val_acc: 0.8785
• bert + bilstm + crf,val_acc: 0.8801
• bert + 半指针,val_acc: 0.8891
• bert + 0/1 标记,val_acc: 0.8922

0/1的形式是如何实现的呢?咱们以问题是“青秀南城百货有限公司在哪?”为例来具体解说一下。

query:青秀南城百货有限公司在哪?

bert_tokenizer:[‘[XLS]’, ‘青’, ‘秀’, ‘南’, ‘城’, ‘百’, ‘货’, ‘有’, ‘限’, ‘公’, ‘司’, ‘在’, ‘哪’, ‘?’, ‘[SEP]’]

value:青秀南城百货有限公司

tag:[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]

首先对此问题进行Tokenizer,而后失去token序列,如果值“青秀南城百货有限公司”呈现在SQL语句中,就把这些token给标记成1;对于其余的没有在SQL语句当中呈现的,就标记成0。

细节解决

Value检索

因为在value抽取的时候,抽取进去的value可能不太标准,或者是问题当中和数据库当中呈现的不太统一。比如说下图中的“人人”与“人人网”:

Query1:人人周涨跌幅是多少?

Value:人人

在这种状况下,咱们就须要将 value与 SQL这一列当中呈现的所有的值做一个检索,选出与之最靠近的一个词作为最终的 value。那么如果检索,咱们能够选的办法也很多,比如说rouge-L的匹配形式,以及几种机器学习的办法:逻辑回归、SVR以及贝叶斯。通过成果比照,咱们能够发现,逻辑回归是最好的形式,其准确度是97%。

Table-Column 信息加强:

最初一部分,应用表的内容来对列的示意进行加强。

如上图,比如说地区这一类,从中随机选取一个列值,比如说“广西”,咱们这一列就示意成“地区, 广西”这一个整体就作为这一列的一个示意,并把它送到input端,而后再进一步的取得列的示意。通过这种形式对于列进行加强,最终能够取得0.4的成果晋升。

复现中的问题及倡议

1、数据集不标准,倡议抽取选取局部标准的数据进行训练和预测;

2、不要从0开始复现,能够基于现有的模型,参考现有的代码。

M-SQL:一种将自然语言转换为SQL语句的多任务示意学习办法

查看本期论文解读视频、算法链接,请点击:

https://marketplace.huaweiclo...

点击关注,第一工夫理解华为云陈腐技术~