目录

  1. SQLNet: Generating Structured Queries From Natural Language Without Reinforcement Learning
  2. X-SQL: reinforce schema representation with context / X-SQL: reinforce context info schema representation
  3. RAT-SQL: Relation-Aware Schema Encoding and Linking for Text-to-SQL Parsers

【SQLNet: Generating Structured Queries From Natural Language Without Reinforcement Learning】

  • 目标:

自然语言query → SQL query

  • 方法:

Employ a sketch-based approach to generage a SQL query from a sketch

  • 数据:

    • WiKiSQL
    • 为何用此数据:
      1. 数据量大
      2. 通过众包方式标注,带有人类的思维模式,贴合实际
      3. 该任务生成的SQL仅依赖于自然语言query和表格结构,不依赖表格正文
      4. 数据已经切分好,train/dev/test不重复

思想:仅需要填充sketch中的slots,而不是来生成正文和语法

${§}3.1$   基于sketch的query合成

Sketch如下图所示:

image

其中:

  • 加粗的文本是关键词
  • $的文本是待填充的slots,$表示的是预测的类别

Sketch的依赖关系如下图所示:

image

可将此模型视为图模型,将查询问题视为图上的推理。比如说$OP_1$仅有两条边到$Column1$和自然语言query,说明$OP_1$的取值仅依赖它们。


${§}3.2$   利用column attention预测

在本节中,将利用一个WHERE预测列名的作为例子,来解释模型的sequence-to-setcolumn attention


$sequence-to-set$

由于出现在WHERE子句中的列名是所有列名的子集,所以我们不需要“产生”一系列列名,我们仅仅进行预测哪个列名会出现即可,因此我们称这个思想为:sequence-to-set

因此我们的目标即是:

$P_{wherecol}(col|Q)=σ(u_c^T·E_{col} + u_q^T·E_Q)$ ·····(1)

其中

  • $σ$为sigmoid函数
  • $E_{col}$和$E_Q$为列名和自然语言query的embedding,由一个bi-LSTM的隐层得到(分别在列和query的top上运行,参数权重不共享)
  • $u_c^T$和$u_q^T$是两个训练列向量
  • 上面这些所有的乱七八糟维度都是d


    $Column-attention$

对于上式(1)由于仅使用自然语言query的隐藏层信息,在预测列名时可能不会关注一些有用的信息。因此,设计了一个Column attention来计算$E_{Q|Col}$而非$E_Q$。

我们假设有$d*L$维度的矩阵$H_Q$,L是自然语言Query的长度,$H_Q$的第$i$维表示query第$i$个token从LSTM输出的隐藏层。然后对query的每个token给出attention权重$w$,因此$w$是一个维度为L的列向量,通过以下方式计算

$w=softmax(v)$
$v_i={(E_{col})}^T·W·{H_Q^i}$

其中$H_Q^i$表示$H_Q$的第$i$维。

得到$w$后,可以得到:

$E_{Q|col}={H_Q}·w$

通过公式(1),将替换,就可以得到传说中的column attention model

$P_{wherecol}(col|Q)=σ(u_c^T·E_{col} +u_q^T·E_{Q|col})$

作者发现在sigmoid前面加一层效果更好,于是就有了终极model:

$P_{wherecol}(col|Q)=σ((u_a^{col})^T·tanh(U_c^{col}·E_col+U_q^col·E_{Q|col})$

其中,$U_c^{col}$和$U_q^{col}$均是d*d的训练参数,$U_c^{col}$为d维的训练向量

${§}3.3$ SQLNet以及训练细节

SELECT和WHERE是分开处理的,首先是WHERE,然后是SELECT。

${§}3.3.1$ WHERE

  • column slots

    设置一个$τ ∈ (0, 1)$,选择所有$P{wherecol}(col|Q)>=τ$的列。由于种种原因,我们选择$P{wherecol}(col|Q)$为top-K的列名作为候选,将问题转化为一个分类问题,即

    $P_{@col}(K|Q)=softmax(U_1^{@col}·tanh(U_2^{@col}·E_{Q|Q}))_i$

    (由于渲染问题所有的“#”用“@”代替)

    其中$U_1^{@col}$和$U_2^{@col}$是$(N+1)xd$ 和 $dxd$。

    SQLNet会选择K个列,选择使的$P_{@col(k|Q)}$最大的列名

  • OP slot

    把这个当成一个三分类,因此就是计算:

    $P_{op}(i|Q,col)=softmax(U_1^{op}·tanh(U_c^{op}·E_{col}+U_q^{op}·E_{Q|col}))$
  • VALUE slot

    使用了一个seq-to-seq结构,encoder使用了bi-LSTM,decoder用了一个指针网络

${§}3.3.2$ SELECT

TODO

${§}3.3.3$ 其他训练细节

  • 分词使用了StanfordCoreNLP
  • 使用了GloVe Embedding
  • 设计了一个特殊的loss【有个公式】
  • LSTM的权重都不共享
  • 在训练过程中,用Adam每100epoch更新一下

X-SQL: reinforce schema representation with context / X-SQL: reinforce context info schema representation

Introduction

x-sql:基于神经网络模型的增强预训练模型,有以下三点贡献&观点:

  1. nl2sql有两类问题:

    1. 非结构化query
    2. 结构化schema

      我们利用一个现有的模型(MT-DNN)来捕捉这种变化,并将无结构的query合并成全局性的文本表示,然后用于为下游任务增强“结构化schema”的表示。

      这是第一次用bert来尝试处理问题依赖结构,并且对结构化信息构建了一个新的表示方法。

  2. 对于有结构的schema数据,一部分SQL语法是“有界的”,例如:

    1. MIN仅用于数字列
    2. > 不会出现在字符串列
    • 第${§}2.1$节描述了类别embedding,并修改了预训练语言表示
    • 第${§}2.2$节展示了如何通过学习一个分离的类别embedding来增强子任务
  3. 之前的方法有这么一个问题:

    由于每个分类器是独立优化,并且他们的输出不能直接比较,之前方法使用多个二元分类器不能完成对列见关系的预测。因此,x-sql使用了一个列表示全局排序方法,使用KL散度作为目标来将所有列映射到一个可比空间。

模型结构

  1. sequence encoder
  2. context enhanced schema encoder
  3. output layer

1. sequence encoder

使用了一个类Bert的模型,有以下改变:

  1. 在每个表结构中添加一个空列[EMPTY],这个空列会在$§{2.4}$节被清除
  2. 用type embedding替换segment embedding,这里会从四个类学习embedding:
    1. question
    2. categorial列
    3. numerical 列
    4. special empty 列
  3. 使用MT-DNN作为初始化encoder(与Bert结构类似,但是是由多个GLUE任务训练得到的,在下游NLP任务中展现了不错的表示性能)

将Bert的[CLS]重命名为[CTX](目的:注重当前捕获到的上下文信息,而非为了下游任务作表示)

为了实现以上的变化,对比SQLova中的NL2SQL layer,我们的方法主要是用了一个足够简单但是有效的layer

2. context enhanced schema encoder

表示Encoder的输出,每个均是d维

  • 每个question token被编为$h_{qi}$
  • 表示第$i$列的第$j$个token

故 这个Encoder的目的是:对每一列$i$学习一个新的表示$h_{C_i}$,通过使用$h_{[CTX]}$来捕捉全局上下文信息来增强原始编码器的输出。

因此,$h_{C_i}$可以表示为:

$h_{C_i}=\sum_{t=1}^{n_i}\alpha_{it}·h_{C_{it}}$······(1)

其中:

  • $n_i$表示列$i$中token数
  • 表示第$i$列的第$t$个token捕捉全局上下文信息的好坏,


3. output layer

output layer结合了SQL程序以及:

  1. sequence encoder 输出,
  2. context enhanced schema encoder 输出,

这个output layer类似于Xu et al.(2017)Hwang et al.(2019),该任务被划分为6个子任务,每一部分均是最终SQL pragram的一部分。


首先介绍一个使用基于sub-network调整schema representation 的任务,特别是:

$rC_i=LayerNorm(U'·h_{[CTX]} + V'·h_{C_i})$ ······(2)

与公式(1)不同的是,对于每个子任务这个计算式分别进行的,以便于schema representation更好的对齐每个子任务应重点关注的自然语言query的特定部分。

(注:这个在另一篇论文中提到,虽然已经通过token权重加强了上下文信息,但是对query也有不错的~)

任务S-COL

预测SELECT列,那么给SELECT选择的列$C_i$即为:

$P^{S-COL}(C_i)=Softmax(W^{S-COL}·rC_i)$

其中S-COL仅依赖于$rC_i$

任务S-AGG

对列预测Aggregator,为了增强aggregator依赖被选择列的类别(例如MIN不会用于string类型的列),我们明确地利用了type embedding,则选择的AGG可以表示为:

$p^{S-AGG}(A_j|C_i)=Softmax(W^{S-AGG}{[j, :]\times LayerNorm(U''·h_{[CTX]} + V''·h_{C_i} + E^T_{C_i})}$····(3)

其中,$W^{S-AGG}\in{R^{6\times d}}$。

与其他子任务不同的是,这里我们没有使用而是使用了,因为我们使用了一个类似于公式(2)的方法来合并列的类别,type embedding是由sequence encoder单独学来的。

以下四个任务是围绕WHERE同时得到的
任务W-NUM

W-NUM使用$W^{W-NUM}·h_{[CTX]}$来计算WHERE的条数,被建模为四个可能标签的分类任务,每个标签代表最终SQL语句中的1~4个where子句。不过这没法预测where子句为空的情况,这种情况会通过KL散度交给W-COL来完成。

任务W-COL
$p^{W-COL}(C_i)=Softmax(W^{W-COL}·rC_i)$

(注:$p^{W-COL}$是一个分布,基于W-NUM,得到where选择的top score列)

任务W-OP

W-OP对于给定的where列选择合适的操作符,即:

$p^{W-OP}(O_j|C_i)=Softmax(W^{W-OP}·[j, :]·rC_i)$

这个操作符也依赖于列的类别(text/real),能够类似于公式(3)的S-AGG进行建模。

任务W-VAL

W-VAL是从query中预测where语句的子串,因此转化为预测子串在query的起始和终止位置,即:

$p^{W-VAL}_{start}(q_j|C_i)=Softmax g(U^{start}·h_{q_j} + V^{start}·rC_i)$ $p^{W-VAL}_{end}(q_j|C_i)=Softmax g(U^{end}·h_{q_j} + V^{end}·rC_i)$

其中$g(x):=W·x+b$。

Training&Inference

1. Training

在训练过程中,使用了:

  • 交叉熵,包括S-COL, S-AGG, W-NUM, w-VAL
  • KL散度,包括W-COL

2. Inference

若高分列是特殊的[EMPTY],我们将忽视”W-NUM”的输出,并且返回空WHERE;否则,选择由W-NUM和W-COL指定的非[EMPTY]的top-n

实验

数据

WiKiSQL,train/dev/test

评价

  • logical form accuracy
  • execution accuracy

结果

  1. lf、ex准确率
  2. 每个子任务的准确率

image

From `X-SQL: reinforce schema representation with context`

image

From `X-SQL: REINFORCE CONTEXT INTO SCHEMA REPRESENTATION`

RAT-SQL: Relation-Aware Schema Encoding and Linking for Text-to-SQL Parsers

摘要

现有两个挑战

  1. 如何为语义解析器提供编码数据库关系?
  2. 如何将数据库列名与给定的query对齐

本文工作

基于关系感知的自注意力机制,在一个text-to-sql encoder内解决schema encodingschema linking特征表示三个问题

Introduction

schema表示(schema generalization难点

  1. 任何text-to-sql模型均要将schema构建为适合解码成可能包含列名和表名的SQL语句的向量表示
  2. 1中得到的表示应该编码了schema的所有信息,包括列类别、主键、外键
  3. 模型需要识别(可能与训练过程不同的)NL问题所设计的列名和表格,故成:schema linking,即将question与列、表进行对齐

具体描述本文工作

(RATSQL)利用关系感知的自注意力机制来构建schema和question的全局推理,用于在给定的question和数据库schema中对关系结构进行编码。

  1. relation-aware self-attentionpaper

Peter Shaw, Jakob Uszkoreit, and Ashish Vaswani. 2018. Self-Attention with Relative Position Repre- sentations. In Proceedings of the 2018 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies, Volume 2 (Short Papers), pages 464– 468.

  1. AST-based structural paper

Jiaqi Guo, Zecheng Zhan, Yan Gao, Yan Xiao, Jian-Guang Lou, Ting Liu, and Dongmei Zhang. 2019. Towards complex text-to-SQL in cross- domain database with intermediate representation. In Proceedings of the 57th Annual Meeting of the Association for Computational Linguistics, pages 4524–4535.

Relation-Aware Self-Attention

一个正常的self-attention encoder/transformer:

给定输入:

image

有:

image

其中,$1 \le h \le H$,这里attention权重就是input的关系信息

一个self-attention layer:

image

这里,就编码了$x_i$和$x_j$之间已知的关系

假设为关系特征集合,那么。RATSQL对每个(i, j)边用表示所有的预定义特征。

这里要么是一个从关系学到的embedding(如果该关系适用于相应的边),要么是一个零向量。

RAT-SQL

1. 输入输出定义

基本定义:
  • 输入:
    1. natural language question $Q$
    2. schema
  • 输出:
    1. SQL P (abstract syntax tree T
  • 其中
    • Question:是一个words序列
    • column:,每个$c_i$还包含type,
    • table:

每个列名均包括多个words,如;表格名也包括多个words,如

将database schema表示为:

image

其中:

  • image
  • $\varepsilon$为边(具体见下图)

image

因为以上不包括question信息,所以设计了新的图:

$\mathcal{G}_Q=<\mathcal{V}_Q, \mathcal{E}_Q>$

其中:

  • $\mathcal{V}_Q=\mathcal{V}\cup\mathcal{Q}=\mathcal{C}\cup\mathcal{T}\cup\mathcal{Q}$
  • (后面会讲question和schema之间的特殊关系)
encoder-decoder

2. Relation-Aware Input Encoding

  1. Glove
  2. BiLSTM
  3. BERT

因此对于image,构建输入为:

image

3. Schema Linking

的schema linking relations辅助模型去做question和schema的对齐,对齐也主要包括两种:match namesmatch values

Name-Based Linking

是指列名/表名完全或部分地出现在question中,self-attention在这里还是有一些的缺陷,所以作者:

  1. 对question取1~5的n-gram,判别每个n-gram是exact match还是partial match
  2. 对于(或反过来),我们约定属于:
    image
Value-Based Linking

是指Question与schema中的内容(value)相关联,因此也会间接影响到SQL,所以作者:

  1. 对$q_i$和列名$c_j$增加了一个Column-Value,即$q_i$匹配了列$c_j$的任意一个值
Memeory-Schema Alignment Matrix

TODO

4. Decoder

decoder参考了

Pengcheng Yin and Graham Neubig. 2017. A Syntactic Neural Model for General-Purpose Code Generation. In Proceedings of the 55th Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers), pages 440–450.

的树结构。

(该方法)根据深度优先遍历,通过一个LSTM来输出一个decoder action序列,像生成句法树一样生成SQL。这个action的产生遵从以下两种方式:

  1. 根据语法规则扩展最后生成的节点,称为ApplyRule
  2. 从schema中选择一个column或者table,成为SelectColumn或者SelectTable

准确来说,

image

其中 是question和schema最后的encoding变量, 是之前所有的actions。因此对于不同的action,有不同操作,如下:

  • 对于ApplyRule,
  • 对于SelectColumn,image

Experiments

本小结详细讲了实验相关细节,描述了用到的方案如StanfordCoreNLP,PyTorch,BERT,batch size=24训练了9w个step,利用了超参数搜索的一些方式。由于spider没有test数据公开,所以论文也在dev上进行了验证和实验。并给出了Spider和WiKiSQL两个数据集的实验结果。

在错误分析部分,分析主要有以下三类错误:

  1. 18%:由于SQL表述形式不同但是实际意义相同
  2. 39%:在Select部分有丢失或者错误
  3. 29%:在Where部分错误

附录

TODO

按语

本篇论文是20年微软发表在ACL上的论文,基本达到了当时的sota水平,同时开源了项目代码,有极大的研究价值。纵观整个项目,项目代码较为优雅,在执行上做了很多优化,利用装饰器封装了一个全局的字典用于存储所有变量,方便整个项目在任意位置访问资源,这种写法可以深入学习。模型结构方面,还是经典的encoder-decoder,在encoder部分做了很多的尝试,在decoder部分还是采用了IRNet那种AST的方式。

作者主要是参考了relation-aware self-attention,即将schema和question之间的关系在做attention的时候加进去,从而让模型学得Question与Schema之间的关联信息。所以论文的很多工作是围绕着如何描述它们之间的信息展开的,例如定义了一些column和table之间的type(table 1),在question和column/table之间做match(name-based, value-based),以及(还没看)。在decoder阶段是利用了LSTM深度优先生成树结构,从而构成SQL语句。


实验随手记

data processes

rat_sql_master/ratsql/commands/preprocess.py,创建Processor()对象,包含:

image

读取数据为SpiderDataset的逻辑:rat_sql_master/ratsql/datasets/spider.py

  1. 读取table的逻辑

ratsqlmaster/ratsql/datasets/spiderlib/evaluation.py
的buildforeign_key_map函数,用来构建外键之间的关系,比如:先将table和列弄成“
表格名.列名
”的形式,然后构建映射关系

image

以下是处理每条数据的逻辑

image

这里self.model_preproc.validate_item调用的是rat_sql_master/ratsql/models/enc_dec.py的EncDecModel的Preproc的validate_item,即:

image

这里self.enc_preproc是rat_sql_master/ratsql/models/spider/spider_enc.py的SpiderEncoderBertPreproc类;self.dec_preproc是NL2CodeDecoderPreproc类,首先进入SpiderEncoderBertPreproc类的validate_item,这里item是一个SpiderItem:

image

(接上)

  1. enc_result, enc_info = self.enc_preproc.validate_item(item, section)过程

SpiderEncoderBertPreproc类的validate_item的执行逻辑为:

image

其中,self._preprocess_schema(item.schema)做的事情是:

处理一下schema,然后返回一个处理结果

image

处理的结果是个类,大概是下面的样子:

image

至此,enc_result, enc_info = self.enc_preproc.validate_item(item, section)部分完成

  1. dec_result, dec_info = self.dec_preproc.validate_item(item, section)过程

这一部分会进行sql的解析,

image

这里self.grammar是来自于rat_sql_master/ratsql/grammars/spider.py:

image

在解析过程会调用rat_sql_master/ratsql/grammars/spider.py的SpiderLanguage的parse_sql函数,然后依次对sql的每个部分进行解析

  1. parse_select
  2. parse_from

image

  1. 2.1 parse_table_unit

输入:table_unit为:[‘table_unit’, 0]

  1. parse_cond
  • 在处理where语句有用到

在完成解析后,对sql dict构建AST树结构

处理完毕后,调用add_item

image

基本上主要是对train的数据进行操作

操作后,进行保存:

  1. spider_enc.py保存vocab,enc目录下的train、dev
    在其中保存enc_vocab.json, enc_word_freq.json
  2. decoder.py 保存vocab,dec目录下的train、dev
    在decoder.py中保存:observed_productions.json, grammar_rules.json,dec_vocab.json

train

输入的batch结构:

image

然后在compute_loss的时候调用的是_compute_loss_enc_batched

里面对encoder input进行编码,即:

image

这个过程大概是这样的:分词,做index的映射

image

完成encoder部分后,开始进行decoder的loss计算部分:

image

目前调用的是compute_mle_loss,将desc_enc转为TrainTreeTraversal,然后根据rule执行遍历,最后将loss进行concat,得到最终的loss

infer

TODO