layout: posttitle: NL2SQL
subtitle: 自然语言转换成SQL查询
date: 2019-12-30
author: NSX
header-img: img/post-bg-2015.jpg
catalog: true
tags:
- 技术
- 教程

NL2SQL

NL2SQL任务

NL2SQL(Natural Language to SQL), 顾名思义,是一项将自然语言转为可执行 SQL 语句的技术。它可以充当数据库的智能接口,让不熟悉数据库的用户能够快速地找到自己想要的数据,对改善用户与数据库之间的交互方式有很大意义。

NL2SQL 的价值

当前,大量信息存储在结构化和半结构化知识库中,如数据库。对于这类数据的分析和获取需要通过SQL等编程语言与数据库进行交互操作,SQL的使用难度限制了非技术用户,给数据分析和使用带来了较高的门槛。人们迫切需要技术或工具完成自然语言与数据库的交互,因此诞生了Text-to-SQL任务。NL2SQL图示如下:

2019-12-30-NL2SQL - 图1

我们通过图1中的实例来介绍一下Text-to-SQL任务。该任务包含两部分:Text-to-SQL解析器和SQL执行器

解析器的输入是给定的数据库和针对该数据库的问题,输出是问题对应的SQL查询语句,如图中红色箭头标示。SQL执行器在数据库上完成该查询语句的执行,及给出问题的最终答案,如图中绿色箭头标示。

SQL执行器有很多成熟的系统,如MySQL,SQLite等,该部分不是本文重点。本文主要介绍解析器,学术界中Text-to-SQL任务默认为Text-to-SQL解析模型。

2019-12-30-NL2SQL - 图2

根据SQL的构成,解析器需要完成两个任务,即“问题与数据库的映射”和“SQL生成”。

在问题与数据库的映射中,需要找出问题依赖的表格以及具体的列,如图1实例中,问题“绿化率前5的城市有哪些,分别隶属于哪些省?”依赖的数据库内容包括:表格“中国城市”,具体的列“名称”、“所属省”、“绿化率”(SQL查询语句蓝色标注成分)。

在SQL生成中,结合第一步识别结果以及问题包含信息,生成满足语法的SQL查询语句,如实例中的“Select 名称,所属省 From 中国城市 Where 绿化率 > 30%”。

Text-to-SQL研究进展

我们接下来将从相关数据集模型两方面介绍该技术的研究进展。

1、数据集介绍

图2给出了Text-to-SQL数据集发展趋势,代表数据集参见表1。

2019-12-30-NL2SQL - 图3

目前,NL2SQL 方向已经有 WikiSQL、Spider、WikiTableQuestions、ATIS 等诸多公开数据集,如图所示:

2019-12-30-NL2SQL - 图4

不同数据集都有各自的特点,这里简单介绍一下这四个数据集:

  • WikiSQL:该数据集是Salesforce在2017年提出的大型标注NL2SQL数据集,也是目前规模最大的NL2SQL数据集。它包含了 24,241张表,80,645条自然语言问句及相应的SQL语句。目前学术界的预测准确率可达91.8%。
  • Spider:Spider数据集是耶鲁大学于2018年新提出的一个较大规模的NL2SQL数据集。该数据集包含了10,181条自然语言问句,分布在200个独立数据库中的5,693条SQL,内容覆盖了138个不同的领域。虽然在数据数量上不如WikiSQL,但Spider引入了更多的SQL用法,例如Group By、Order By、Having等高阶操作,甚至需要Join不同表,更贴近真实场景,所以难度也更大。目前准确率最高只有54.7%
  • WikiTableQuestions 是斯坦福大学于 2015 年提出的一个针对维基百科中那些半结构化表格问答的数据集,包含了 22,033 条真实问句以及 2,108 张表格。
  • The Air Travel Information System (ATIS) 是一个年代较为久远的经典数据集,由德克萨斯仪器公司在 1990 年提出。该数据集获取自关系型数据库 Official Airline Guide (OAG, 1990),包含 27 张表以及不到 2,000 次的问询,每次问询平均 7 轮,93% 的情况下需要联合 3 张以上的表才能得到答案,问询的内容涵盖了航班、费用、城市、地面服务等信息。
  • 中文数据集目前只有追一科技在天池发布的比赛数据集,包括4万条有标签数据作为训练集,1万条无标签数据作为测试集。目前比赛第一名的成绩,准确率达到了92%。

2、模型介绍

SQL查询语句是一个符合语法、有逻辑结构的序列,其构成来自三部分:数据库、问题、SQL关键词

在当前深度学习研究背景下,Text-to-SQL任务可被看作是一个类似于神经机器翻译的序列到序列的生成任务,主要采用Seq2Seq模型框架。基线Seq2Seq模型加入注意力、拷贝等机制后,在单领域数据集上可以达到80%以上的准确率,但在多领域数据集上效果很差,准确率均低于25%。

编码解码两个方面进行原因分析:

  • 在编码阶段,问题与数据库之间需要形成很好的对齐或映射关系,即问题中涉及了哪些表格中的哪些元素(包含列名和表格元素值);同时,问题与SQL语法也需要进行映射,即问题中词语触发了哪些关键词操作(如Group、Order、Select、Where等)、聚合操作(如Min、Max、Count等)等;最后,问题表达的逻辑结构需要表示并反馈到生成的SQL查询语句上,逻辑结构包括嵌套、多子句等。

  • 在解码阶段,SQL语言是一种有逻辑结构的语言,需要保证其语法合理性和可执行性。普通的Seq2Seq框架并不具备建模这些信息的能力。

当前基于Seq2Seq框架,主要有以下几种改进:

1)基于Pointer Network的改进

首先,SQL组成来自三部分:数据库中元素(如表名、列名、表格元素值)、问题中词汇SQL关键字。其次,当前公开的多领域数据集为了验证模型数据库无关,在划分训练集和测试集时要求数据库无交叉,这种划分方式导致测试集数据库中很大比例的元素属于未登录词。传统的Seq2Seq模型是解决不好这类问题的。

Pointer Network很好地解决了这一问题,其输出所用到的词表是随输入而变化的。具体做法是利用注意力机制,直接从输入序列中选取单词作为输出。在Text-to-SQL任务中,将问题中词汇、SQL关键词、对应数据库的所有元素作为输入序列,利用Pointer Network从输入序列中拷贝单词作为最终生成SQL的组成元素。

由于Pointer Network可以较好的满足具体数据库无关这一要求,在多领域数据集上的模型大多使用该网络,如Seq2SQL[1]、STAMP[8]、Coarse2Fine[9] 、IRNet[16]等模型。

2)基于Sequence-to-set的改进

在简单问题对应的数据集合上,其SQL查询语句形式简单(仅包含Select和Where关键词),为了解决Seq2Seq模型中顺序错误带来的影响(如“条件1 And 条件2”,预测为“条件2 And 条件1”,属于顺序错误,但对应的SQL是正确的),SQLNet[10]提出了Sequence-to-set模型,基于所有的列预测其属于哪个关键词(即属于Select还是Where,在SQLNet模型中仅预测是否属于Where),针对SQL 中每一个关键词选择概率最高的前K个列。

该模式适用于SQL形式简单的数据集,在WikiSQL和NL2SQL这两个数据集合上使用较多,且衍生出很多相关模型,如TypeSQL[11]、SQLova[12]、X-SQL[13]等。

2019-12-30-NL2SQL - 图5

3、评价方法

Text-to-SQL任务的评价方法主要包含两种:精确匹配率(Exact Match, Accqm)、执行正确率(Execution Accuracy, Accex)。

精确匹配率指,预测得到的SQL语句与标准SQL语句精确匹配成功的问题占比。为了处理由成分顺序带来的匹配错误,当前精确匹配评估将预测的SQL语句和标准SQL语句按着SQL关键词分成多个子句,每个子句中的成分表示为集合,当两个子句对应的集合相同则两个子句相同,当两个SQL所有子句相同则两个SQL精确匹配成功;

2019-12-30-NL2SQL - 图6

执行正确指,执行预测的SQL语句,数据库返回正确答案的问题占比。

2019-12-30-NL2SQL - 图7

目前仅WikiSQL数据集支持Accex,其他数据集仅支持Accqm。大部分数据集发布了对应的评估脚本,方便大家在同一个评估标准下进行算法研究。

4、NL2SQL实现简述

NL2SQL的基本思路是打造一条从自然语言到SQL的转换链路,多采用的是语义解析和规则的方式构建NL2SQL系统,其架构大体如下:

2019-12-30-NL2SQL - 图8

  1. 用户UI:用户交互界面,包括问句自动提示、可视化选择等功能。
  2. Storage:Storage是数据存储中心,包括了Knowledge Graph、Intent words以及database schema信息。同时也会将用户的搜索log存储起来。
  3. Parser:主要负责对user query进行parsing,包括了annotator(字符串匹配+NER+意图识别等一系列操作)、grammar(语法检测)、semantic predict(语义预测)、ranking(评分排序)。这部分会调用借助图谱来提高实体和关系识别精度。
  4. Answering Engine:用于将语义解析的结果转换成SQL,包括表识别、查询语句生成器等,最终将结果(数据、可视化结果、SQL等)返回给user。

XSQL

2019-12-30-NL2SQL - 图9

  • X-SQL是微软提出的NL2SQL模型,参考了SQLNet、SQLova等模型的思路.
  • X-SQL 的模型架构分为三层 (如下所示):

    • Encoder: 首先使用 bert 风格的预训练模型(MT-DNN) 对 Question 和 SQL 表格进行编码和特征提取, 得到上下文输出来增强结构模式表示,并结合类型信息;
    • Context Reinforcing Layer: 该结构用于增强在 equence Encoder (序列编码器)得到的 H_[CTX], 从而得到增强的语义表示 HCi ;
    • Output Layer: 输出层完成 SQL 语句的生成,我们将其分为 6 个子任务(select-column, select-aggregation, where-number, where-column, where-operator, and where-value),这六个任务彼此之间相互结合,彼此制约。

2019-12-30-NL2SQL - 图10

X-SQL模型—Encoder

X-SQL使用了一个BERT-Like模型MT-DNN作为Token Sequence Encoder,同时进行以下修改:

  • 引入了一个特殊空列[EMPTY]的概念,并将其追加到每个Table Schema后面;
  • BERT中的Segment Embedding被替换为Type Embedding,包括:Question 、Categorial Column、Numerical Column、Special Empty Column 这四种类型;
  • 此外,单纯地将标志位[CLS]重命名为[CTX]

2019-12-30-NL2SQL - 图11

X-SQL模型—Context Reinforcing Layer

  • 对上一层Encoder的输出 H_[CTX] 进一步“强化”,从而为表的每一列学习新的表示h_Ci
  • 这种强化体现在两方面:

    • 由于Column Tokens的输出长短不一,所以需要对Column Embeddings进行“调整”;
    • 此外为了加强Context的影响,在Alignment Model中会使用到Context Embedding的信息;

2019-12-30-NL2SQL - 图12

通过这种方式可以捕获到哪一个查询词与哪一列最相关,从而得到增强的语义表示 HCi 。它的计算过程如下所示:

2019-12-30-NL2SQL - 图13%0A#card=math&code=s%7Bit%7D%3Df%28Uh%7B%5BCTX%5D%7D%2F%5Csqrt%7Bd%7D%2CVh%7BC%7Bit%7D%7D%2F%5Csqrt%7Bd%7D%29%0A)

2019-12-30-NL2SQL - 图14%0A#card=math&code=a%7Bit%7D%3Dsoftmax%28s%7Bit%7D%29%0A)

2019-12-30-NL2SQL - 图15

其中,2019-12-30-NL2SQL - 图16只是普通的点乘 (dot-product) 操作。最后,针对每一列 (schema representation h_Ci),独立的使用下面的子网络结构得到使用融合 h_Ci 和 hctx 的 rCi,公式如下所示:

2019-12-30-NL2SQL - 图17%0A#card=math&code=r%7BC%7Bi%7D%7D%3DLayerNorm%28U%5E%60h%7B%5BCTX%5D%7D%2BV%5E%60h%7BC_%7Bi%7D%7D%29%0A)

X-SQL模型—Output Layer

Output层由六个子分类器构成:

  • S-COL:查询表的哪一列
  • S-AGG: 使用什么聚合函数
  • W-NUM: 查找where子句的数量(四个可能标签的分类,每个标签表示1~4 )
  • W-COL:选择表的哪几列
  • W-OP: 对这几列的操作符
  • W-VAL: 这几列的值

其中五个子模型的输出会被填到QueryStructure中。w-col、w-op 和 w-val 这三个任务是依赖 w-num 的,因为 w-num 决定了对几列进行约束,这样它们三个只需要取 softmax 最大的那几个。

2019-12-30-NL2SQL - 图18

每个子模型的说明:

2019-12-30-NL2SQL - 图19

在训练过程中,我们优化目标是所有单个子任务损失的总和。

追一NL2SQL天池任务

任务描述

首届中文NL2SQL挑战赛,使用金融以及通用领域的表格数据作为数据源,提供在此基础上标注的自然语言与SQL语句的匹配对,希望选手可以利用数据训练出可以准确转换自然语言到SQL的模型。

模型的输入为一个 Question + Table,输出一个 SQL 结构,该 SQL 结构对应一条 SQL 语句。示例如下图黄色部分,需要预测的有4部分:

  • 挑选的列(sel)
  • 列上的聚合函数(agg)
  • 筛选的条件(conds)
  • 条件间的关系(cond_conn_op)

2019-12-30-NL2SQL - 图20

任务数据

  • 4万条有标签数据作为训练集

  • 1万条无标签数据作为测试集

评价指标

  • 全匹配率 (Logic Form Accuracy): 预测完全正确的SQL语句。其中,列的顺序并不影响准确率的计算。
  • 执行匹配率 (Execution Accuracy): 预测的SQL的执行结果与真实SQL的执行结果一致。

官方的评估指标是 (全匹配率 + 执行匹配率) / 2,也就是说你有可能写出跟标注答案不同的SQL语句,但执行结果是一致的,这也算正确一半。

难点分析

  • 不限制使用表格内容信息
  • 存在conds value不能从question提取的样本
  • select agg存在多项
  • 没有conds缺失的样本

第一名解决方案M-SQL

  1. 将原始的 Label 做一个简单的变换

2019-12-30-NL2SQL - 图21

  1. 对输入进行改造

将 Question 与 Header 顺序连接, 其中每一个表头也视为一个句子,用[CLS]***[SEP]括住。

  1. M-SQL 模型架构

第一个[CLS]对应的向量,我们可以认为是整个问题的句向量,我们用它来预测XXX的连接符。后面的每个[CLS]对应的向量,我们认为是每个表头的编码向量,我们把它拿出来,用来预测该表头表示的列是否应该被select . 现在就剩下比较复杂的conds了,就是where col_1 == value_1这样子的,col_1、value_1以及运算符==都要找出来。

两个较特殊的改进:

  • W-col-val模型

    • 相较于X-SQL的W-VAL预测Value的首尾偏移量,W-col-val改用了序列标注的方式提取Where Value;
  • W-val-match模型

    • 提取各列的 Distinct Value Set,基于Matching的方式匹配最可能的【列-值】;

      • 基于文本的匹配:rouge-L、编辑距离等;
      • 基于语义的匹配:LR、MLP、相似度计算等

2019-12-30-NL2SQL - 图22

M-SQL在X-SQL的基础上进行了调整和扩展(对比)

  • Encoder:

    • 预训练模型更换(MT-DNN → Bert-wwm-ext);
    • Token/TokenType调整;
  • Column Representation:基本和X-SQL一致;
  • Sub-models:

    • 增加S-num辅助任务
    • 合并W-NUM和Reducer预测;
    • 将原本的W-VAL换成了W-col-val和W-val-match;
    • (待定) 把sel与agg结合,当作多分类问题

2019-12-30-NL2SQL - 图23

现阶段的问题

  • WikiSQL 数据集的数据形式和功能薄弱
  • 条件的表达只支持最基础的 >、<、=
  • 条件之间的关系只有 and
  • 不支持聚组、排序、嵌套等其它众多常用的 SQL 语法
  • 不需要联合多表查询答案,真实答案所在表格已知
  • 这样的数据集并不符合真实的应用场景
  • Query Structure中的元素不存在递归关系
  • 天池TableQA(5w,中文),样本量少,且结构简单

如何更好地结合数据库信息来理解并表达用户语句的语义、如何编码及表达数据库的信息、如何生成复杂却有必要的 SQL 语句,此类挑战还有很多需要解决,它们都是非常值得探索的方向。

补充

现在Bert可用的中文预训练权重有两个

两个的最终效果差不多,但是哈工大版的收敛更快。

复现过程

Part1: 预处理

首先对question进行了格式统一,具体如下:

  1. 百分数转换,例如百分之10转化为10%,百分之十转换为10%, 百分之一点五转化为1.5%
  2. 大写数字转阿拉伯数字,例如十二转换为12; 二十万转化为200000; 一点二转化为1.2
  3. 年份转换,如将12年转换为2012年
  4. 利用规则与编辑距离对query进行修正
  5. query信息标记:[CLS] -> [XLS]

然后,SQL分析

  • 常用的SQL模式分析

Part2:模型介绍

  • 预训练模型:Bert-wwm-ext,哈工大
  • W-num,W-op融合

Part3: 后处理

Part4: 模型效果评估

Part5: 网络/应用

通过云服务构建服务器后,构建可与各种DBMS链接的网页

参考

基于Bert的NL2SQL模型:一个简明的Baseline

RAdam 优化器的实现 keras_radam

CyberZHG 大神的开源项目 keras-bert

哈工大讯飞联合实验室的 Chinese-BERT-wwm 项目

追一:NL2SQL的发展

NL2SQL概述:一文了解NL2SQL

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

追一科技首届中文NL2SQL挑战赛决赛第3名方案+代码

X-SQL,X-SQL: REINFORCE CONTEXT INTO SCHEMA REPRESENTATION

M-SQL,M-SQL:Muti-Schema Representation Learning for Single-Table Text2SQL Generation(修改中…)