zoukankan      html  css  js  c++  java
  • MSQL:超强的多任务表示学习方法

    摘要:本篇文章将硬核讲解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.huaweicloud.com/markets/aihub/article/detail/?content_id=d5f27a62-fc93-43cb-813b-6bb5c5eec068

     

    点击关注,第一时间了解华为云新鲜技术~

  • 相关阅读:
    网络攻击技术:SQL Injection(sql注入)
    人生若只如初见,何事秋风悲画扇
    TCPClient、TCPListener的用法
    C#中时间的Ticks属性
    string.Empty、" "、null 三者之间的区别
    telnet的使用解析
    public DataTable ExecuteQuery(string sql) 这段话具体意思
    C#中三层架构UI、BLL、DAL、Model详解(送给自学的初学者)
    数据库三层架构
    获取SQL Server数据库的表结构的做法
  • 原文地址:https://www.cnblogs.com/huaweiyun/p/15324606.html
Copyright © 2011-2022 走看看