text2sql方法:RESDSQL和DAIL-SQL

之前介绍了text2sql的综述,但是对一些方法的描述不够详细,所以将一些感兴趣的方法思路也整理一下。

RESDSQL

RESDSQL出自2023年2月的论文《RESDSQL: Decoupling Schema Linking and Skeleton Parsing for Text-to-SQL》(github)。它使用seq2seq PLM(pre-trained language model)模型来将自然语言问题翻译成SQL。为了提高准确率,将Schema Linking和Skeleton Parsing解耦,具体做法是先进行Schema Linking使得输入模型encoder的schema只包括与问题最相关的表和列;在生成SQL时,模型decoder先生成SQL骨架再生成实际的SQL查询。

RESDSQL是Ranking-enhanced Encoding plus a Skeleton-aware Decoding framework for Text-to-SQL 的简称,论文图2示意了该方法的思路。

在这里插入图片描述

在介绍RESDSQL的实现细节之前,先说明一些符号和概念。将一个关系数据库记为 D \mathcal{D} D,数据库的schema S \mathcal{S} S包括:

  • 数据表集合 T = { t 1 , t 2 , ⋯ , t N } \mathcal{T} = \{ t_1, t_2, \cdots, t_N\} T={t1,t2,,tN}
  • 数据列集合 C = { c 1 1 , ⋯ , c n 1 1 , c 1 2 , ⋯ , c n 2 2 , ⋯ , c 1 N , ⋯ , c n N N } \mathcal{C} = \{ c^1_1, \cdots, c^1_{n_1}, c^2_1, \cdots, c^2_{n_2}, \cdots, c^N_1, \cdots, c^N_{n_N}\} C={c11,,cn11,c12,,cn22,,c1N,,cnNN}。每一个数据列都与一个数据表关联, c n i i c^i_{n_i} cnii是第i个表格的第 n i n_i ni列。
  • 外键关系集合 R = { ( c k i , c h j ) ∣ c k i , c h j ∈ C } \mathcal{R}=\{(c^i_k, c^j_h)|c^i_k, c^j_h \in \mathcal{C} \} R={(cki,chj)cki,chjC}, 其中的每一对 ( c k i , c h j ) (c^i_k, c^j_h) (cki,chj)表示列 c k i c^i_k cki c h j c^j_h chj之间存在外键关系。
  • M = ∑ i = 1 N n i M=\sum^N_{i=1} n_i M=i=1Nni表示数据库 D \mathcal{D} D中的所有的列的个数。
  • 在表示一个schema的时候,可以用原始名字(在数据库中表示的名字)或语义名字(原始名字实际代表的语义含义),比如在论文的图1中,”uid“是原始名字,而”airline id“是语义名字,用语义名字相对比原始名字能更清晰地理解列数据的含义。注意有时候语义名字和原始名字是一样的,比如图示中的country。

在这里插入图片描述

Ranking-Enhanced Encoder

为了使RESDSQL模型的encoder输入只包括与问题最相关的schema元素,RESDSQL使用了一个cross-encoder模型来对数据表和数据列进行分类,然后基于分类概率来排序并过滤掉不相关的schema元素。这样做一方面可以过滤掉不相关的schema元素,另一方面可以输入seq2seq encoder的schema元素是排过序,模型可以捕捉到潜在的位置信息。

cross-encoder模型的输入: 将schema元素按照其默认顺序组成一个schema元素序列,并将它和问题拼接起来组成cross-encoder模型的输入 X X X X = q ∣ t 1 : c 1 1 , ⋯ , c n 1 1 ∣ ⋯ ∣ t N : c 1 N , ⋯ , c n N N X=q|t_1:c^1_1,\cdots, c^1_{n_1}|\cdots|t_N:c_1^N, \cdots, c^N_{n_N} X=qt1:c11,,cn11tN:c1N,,cnNN ,|是分隔符,用来分隔问题和数据表。为了更好地表示数据元素的语义信息,这里使用的是它们的语义名称。

编码模块(Encoding Module):使用RoBERTa作为cross-encoder模型。因为每一个schema元素可能被模型的分词器分成1个或多个token,比如数据列"airline id"会被分成两个token:“airline” 和"id"。而我们会希望在分类时将每一个schema元素作为整体,论文的解决思路使用了一个包含两层的BiLSTM和一个非线性全连接层作为pooling方法。经过pooling之后,每一个数据表的embedding可表示为 T i ∈ R 1 × d ( 1 ∈ { 1 , … , N } ) \mathbf{T}_i \in \mathbb{R}^{1\times d} (1 \in \{ 1, \ldots, N\}) TiR1×d(1{1,,N}), 每一个数据列的embedding可表示为 C k i ∈ R 1 × d ( 1 ∈ { 1 , … , N } , k ∈ { 1 , … , n i } ) \mathbf{C}_k^i \in \mathbb{R}^{1\times d} (1 \in \{ 1, \ldots, N\}, k\in \{1, \ldots, n_i\}) CkiR1×d(1{1,,N},k{1,,ni}), d是隐藏层的大小。

列增强层(Column-Enhanced Layer):有些问题里只会提到相关列名不会提到表名,比如论文图1中的例子提到了列名"city",但是没有提到表名"airports"。这种表名在问题中缺失的问题可能会影响表分类性能,所以论文作者提出了一个列增强层来将列信息注入到它对应的表embedding中,这样即使问题中只提到列名也能将对应的表给识别出来。列增强层通过multi-head scaled dot-product attention layer和一个特征融合层来实现,设对于第 i i i个表,其所有列信息表示为 C : i ∈ R n i × d \mathbf{C}^i_: \in \mathbb{R}^{n_i \times d} C:iRni×d, 将其通过下式注入到表embeding T i \mathbf{T}_i Ti
T i C = M u l t i H e a d A t t n ( T i , C : i , C : i , h ) , ( 1 ) T ^ i = N o r m ( T i + T i C ) \begin{aligned} \mathbf{T}_i^C &= MultiHeadAttn(\mathbf{T}_i, \mathbf{C}^i_:, \mathbf{C}^i_:, h), \qquad (1) \\ \hat{\mathbf{T}}_i &=Norm(\mathbf{T}_i + \mathbf{T}^C_i) \end{aligned} TiCT^i=MultiHeadAttn(Ti,C:i,C:i,h),(1)=Norm(Ti+TiC)
在上式中 T i \mathbf{T}_i Ti作为self-attetion里的query, C : i \mathbf{C}^i_: C:i同时作为key和value, h是head的个数, N o r m ( ⋅ ) Norm(\cdot) Norm() row-wise L 2 L_2 L2归一化函数。通过将原来的表embedding T i \mathbf{T}_i Ti 和列注意力机制表embedding T i C \mathbf{T}_i^C TiC一起获得列增强表embedding T ^ i ∈ R 1 × d \hat{\mathbf{T}}_i \in \mathbb{R}^{1 \times d} T^iR1×d

Cross-Encoder的损失函数:因为一个SQL查询通常只会包括数据库中的少量数据表和数据列,训练集的标签分布是非常不均匀的。所以论文使用focal loss作为分类损失。cross-encoder的损失函数是多任务学习方式,包括数据表分类损失和数据列分类损失:
L 1 = 1 N ∑ i = 1 N F L ( y i , y i ^ ) + 1 M ∑ i = 1 N ∑ k = 1 n i F L ( y k i , y k i ^ ) \mathcal{L}_1 = \frac{1}{N}\sum^{N}_{i=1}FL(y_i, \hat{y_i}) + \frac{1}{M}\sum^{N}_{i=1}\sum^{n_i}_{k=1}FL(y^i_k, \hat{y^i_k}) L1=N1i=1NFL(yi,yi^)+M1i=1Nk=1niFL(yki,yki^)
上式中的FL是focal loss 函数, y i y_i yi是第i个表格的真实标签。 y i = 1 y_i=1 yi=1表示这个表被SQL查询引用了, y i = 0 y_i=0 yi=0表示这个表没有被SQL查询引用。 y k i y^i_k yki是第i个表格的第k列的真实标签。 y k i = 1 y^i_k=1 yki=1表示这一列被SQL查询引用了, y k i = 0 y^i_k=0 yki=0表示这一列没有被SQL查询引用。 y ^ i \hat{y}_i y^i y ^ k i \hat{y}^i_k y^ki是预测概率,由基于数据表embedding T ^ i \hat{\mathbf{T}}_i T^i和数据列embedding C k i \mathbf{C}^i_k Cki的两个不同MLP模块估计得到:
y ^ i = σ ( ( T ^ i U 1 t + b 1 t ) U 2 t + b 2 t ) y ^ k i = σ ( ( C k i U 1 c + b 1 c ) U 2 c + b 2 c ) \begin{aligned} \hat{y}_i & =\sigma\left(\left(\hat{\boldsymbol{T}}_i \boldsymbol{U}_1^t+\boldsymbol{b}_1^t\right) \boldsymbol{U}_2^t+\boldsymbol{b}_2^t\right) \\ \hat{y}_k^i & =\sigma\left(\left(\boldsymbol{C}_k^i \boldsymbol{U}_1^c+\boldsymbol{b}_1^c\right) \boldsymbol{U}_2^c+\boldsymbol{b}_2^c\right) \end{aligned} y^iy^ki=σ((T^iU1t+b1t)U2t+b2t)=σ((CkiU1c+b1c)U2c+b2c)
上式中的 U 1 t , U 1 c ∈ R d × w \boldsymbol{U}_1^t, \boldsymbol{U}_1^c \in \mathbb{R}^{d \times w} U1t,U1cRd×w b 1 t , b 1 c ∈ R w \boldsymbol{b}_1^t, \boldsymbol{b}_1^c \in \mathbb{R}^{ w} b1t,b1cRw U 2 t , U 2 c ∈ R w × 2 \boldsymbol{U}_2^t, \boldsymbol{U}_2^c \in \mathbb{R}^{w \times 2} U2t,U2cRw×2 b 2 t , b 2 c ∈ R 2 \boldsymbol{b}_2^t, \boldsymbol{b}_2^c \in \mathbb{R}^{2} b2t,b2cR2是可训练参数, σ ( ⋅ ) \sigma(\cdot) σ()表示Softmax函数。

seq2seq模型Encoder的输入准备:在seq2seq模型推理时,用前面训练好的cross-encoder为每一个schema元素计算概率并排序,只保留数据库中的 top  k 1 \text{top}\ k_1 top k1个数据表,并为每个表给保留 top  k 2 \text{top}\ k_2 top k2个数据列。 k 1 k_1 k1 k 2 k_2 k2是两个超参数,太小可能将必须的表或列给排除掉了,太大可能会包含一些不必要的schema元素(论文在后续的实验中对数据集进行统计后取了 k 1 = 4 k_1=4 k1=4 k 2 = 5 k_2=5 k2=5)。如论文图2所示,encoder的输入是由问题、排序后的schema元素,可选的外键关系拼接得到。在schema元素中使用的是原始名称,这样decoder可以直接成输入序列中拷贝所需的schema元素。(另外在论文实验时,还使用了与BRIDGE的方法从数据库中提取可能有用的内容来丰富数据列信息)

Skeleton-Aware Decoder

seq2seq的decoder将SQL生成分为两步:1. 基于问题的语义生成SQL骨架;2.从输入序列中选择所需"数据"(数据表、数据列、数据取值)来填充骨架中的槽位。

目标函数:为了在不引入额外模块的前提下实现上述分解思想,论文提出了一个新的生成目标,在生成第t个token时不仅依赖于encoder的输出,同时依赖decode在t个时间步之前的输出。也就是不是直接解码得到目标SQL,鼓励解码器先解码出SQL语句的骨架后再解码SQL语句。论文作者认为先解析骨架再解析SQL语句,在每一个解码步骤,SQL生成更容易,因为解码器可以直接从输入序列中拷贝"数据"或者从之前解析的骨架中拷贝SQL关键字:
L 2 = 1 G ∑ i = 1 G p ( l i s , l i ∣ S i ) \mathcal{L}_2 = \frac{1}{G} \sum^{G}_{i=1} p(l^s_i, l_i |S_i) L2=G1i=1Gp(lis,liSi)
上式的G是Text2SQL实例数目, S i S_i Si是第i个实例的输入序列(包括问题、排序后的schema元素,可选的外键关系)。 l i l_i li是第i个目标SQL语句, l i s l^s_i lis是从 l i l_i li抽取到的骨架。

SQL归一化:Spider数据集是由有不同标注习惯的标注员创建的,所以标注的最终SQL有不同的风格。为了减少模型学习的难度,将原始SQL语句在训练前进行如下操作的归一化,论文的表1有一个归一化例子。

  • 将所有的关键字和schema元素转小写
  • 在圆括号附近添加空格,将双引号替换成单引号
  • 如果ORDER BY语句后面没有指定排序方式,在后面添加ASC关键词
  • 将所有的AS语句去掉,并将所有表的别名用他们的原始名字替换。

在这里插入图片描述

SQL骨架提取:基于归一化的SQL语句,提取只包括SQL关键词和槽位的骨架,即对于一个归一化SQL语句,只保留它的SQL关键字并将其余部分用槽位标识代替。 另外不保留JOIN ON关键词因为它很难从自然语言问题中找到对应的部分。

Execution-Guided SQL Selector:因为在解码时没有约束SQL语法,使用了与以前研究相同的Execution-Guided SQL Selector,即在解码过程中进行beam search并选择结果中的第一个可以执行的SQL作为最终的结果。(beam search 在论文实验中为8)

DAIL-SQL

DAIL SQL出自2023年8月的论文《Text-to-SQL Empowered by Large Language Models: A Benchmark Evaluation》,是一种通过prompt GPT-4来实现Text2SQL的方法。论文先对已有的prompt LLM来实现Text2SQL的提示工程(prompt engineering)进行了调研和比较,然后提出名为DAIL SQL的方法来prompt LLM生成SQL。

论文将text2sql的提示工程分成question representation(prompt里问题和数据库表的表示方式)、example selection(如何选择有效text2sql例子)、example organization(例子在prompt中的组织方式)。

DAIL-SQL的思路的伪代码如论文算法1,下面介绍DAIL-SQL的prompt是如何得到的。

在这里插入图片描述

  • question representation:将数据库表用SQL语法语法形式来表示(论文中称其为Code Representation Prompt( CR P \text{CR}_P CRP)),如论文的Listing 4所示意。注意这个表示方式里有将数据表的外键特意标记出来,让LLM在预测"JOIN"操作时更容易。

    在这里插入图片描述

  • example selection: 在选择text2sql例子时,同时考虑自然语言问题和SQL查询的相似度。

    1. 先将目标问题 q q q和候选数据集 Q \mathcal{Q} Q的每一个问题 q i q_i qi中的领域相关的词(表名、列名、数据取值)都用一个mask token给替换掉(用与RAT-SQL一样的n-gram匹配方法来进行schema linking找到与数据库有关的词。将数据表和列名使用"“来替换,将数据取值用”"替换)。再计算mask后的 q q q q i q_i qi的embedding相似度,并按照它们的相似度大小来对数据集 Q \mathcal{Q} Q倒序排序。
    2. 用一个基础模型基于问题 q q q和数据库 D \mathcal{D} D预测出一个pre-predicted SQL查询 s ′ s^{'} s(论文使用的基础模型是Graphix),然后使用RESDSQL里的方法对SQL查询提取骨架,比较提取骨架后的 s ′ s^{'} s和候选数据集 Q \mathcal{Q} Q里的每一个SQL查询 s i s_i si的Jaccard相似度。
    3. 将第二步得到的相似度大于阈值 τ \tau τ的候选集保留。(论文实验里的阈值是0.9,提交到Spider时的阈值是0.85)
    4. 选择top k个例子作为text2sql的例子。(因为之前已经根据问题相似度排序过了,再卡相似度阈值来过滤sql查询例子,并选择top-k,就是同时考虑了自然语言问题和SQL查询的相似度)
  • example organization: text2sql例子的组织方式如论文的Listing 8所示。
    在这里插入图片描述

  • DAIL-SQL还尝试了self-consistency方法,可以使得执行准确率提高0.4%,但时间效率和token效率都低很多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147179.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

[笔记] 走行电机控制器 防摇摆功能的技术细节

防摇摆用于走行电机控制,一般用于小车。这里参考了数重的彩页: 1.原理 这个无效和有效的控制是靠启动时的幔起,和停车时的缓停实现的。他似乎对加速过程的力矩曲线做了某种控制,能够让启停时,必然的角度变化在运动中逐…

【时时三省】(C语言基础)指针笔试题3

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 笔试题3 首先创建了一个数组 数组里面放了1 2 3 4 &a取出的是数组的地址 数组地址加1 如下图 直接从1跳到了四后面 然后强制类型转换成了int* 转换成int*之…

ModbusTCP通讯错误的排查

Modbus是一种由MODICON公司开发的工业现场总线协议标准,是一项应用层报文传输协议。该协议用于传输数字和模拟变量[1]。有关该协议的报文具体格式,以及一些基本概念,见[1]。 本文以一个例子,阐述当ModbusTCP通讯出现错误的时候&a…

01_RabbitMQ安装及工作模式

一、消息队列MQ 中间件 1.1 什么是消息队列 消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。 消息队列(Message Queue)是一…

鸿蒙开发(NEXT/API 12)【跨设备互通开发】远场通信服务

跨设备互通提供跨设备的相机、扫描、图库访问能力,平板或2in1设备可以调用手机的相机、扫描、图库等功能。 场景介绍 您通过此能力实现跨设备交互,可以使用其他设备的相机、扫描和图库功能。 约束与限制 需同时满足以下条件,才能使用该功…

COLORmap

在这段MATLAB代码中,surf(peaks)、map的定义以及colormap(map)的调用共同完成了以下任务: 1. **绘制曲面图**: - surf(peaks):这个函数调用了MATLAB内置的peaks函数来生成数据,并使用surf函数将这些数据绘制成一个…

CSS 选择器的分类与使用要点二

目录 非 VIP 用户可前往公众号进行免费阅读 标签选择器 id 选择器 类选择器 介绍 公共类 CSS 中优先用 class 选择器,慎用 id 选择器 后代选择器 交集选择器 以标签名作为开头 以类名作为开头 连续交集 并集选择器(分组选择器) 通配符* 儿子选择器 >(IE7…

CSS 的继承性、层叠性与权重问题解析

目录 非 VIP 用户可前往公众号进行免费阅读 继承性 层叠性 CSS的权重问题 如果权重一样,以后出现的为准 以权重大的为准 没有选中,权重为0,就近原则 权重只和css顺序有关 非 VIP 用户可前往公众号进行免费阅读 CSS 的继承性、层叠性与权重问题解析本文主要介绍了 C…

AIGC8: 高通骁龙AIPC开发者大会记录B

图中是一个小男孩在市场卖他的作品。 AI应用开发出来之后,无论是个人开发者还是企业开发者。 如何推广分发是面临的大问题。 做出来的东西一定要符合商业规律。否则就是实验室里面的玩物,或者自嗨的东西。 背景 上次是回顾和思考前面两个硬件营销总的…

解决Python Debug没有反应的问题

应该有伙伴和我一样,用的2024版本的VS code,但是用到的python解释器是3.6.x,或者是更旧版本的Python. 想要进行Debug就会在扩展里面安装 一般安装就会安装最新版本,但是debug时又没有反应,其主要原因是Python的版本与…

Gin框架入门(2)--异常捕获与日志实现

异常捕获 Go语言的异常捕获采用的是延迟处理的方法实现的,实际上就是利用defer,panic和recover三个关键字和函数来实现的。 关键字 defer关键字(函数) 这个关键字在控制语句中就有所涉及,本质上是采用一个栈的存储结构,在整个…

时钟的配置

在使用51单片机时,系统使用的时钟源是一个外部晶体振荡器,频率为12M。由于51单片机每个指令周期都是12分频的,所以实际工作频率仅为1M。2440作为一种性能远高于51的Soc,主频肯定要远远高于51,因此2440有着比51单片机复…

yolov8模型在Xray图像中关键点检测识别中的应用【代码+数据集+python环境+GUI系统】

yolov8模型在X yolov8模型在Xray图像中关键点检测识别中的应用【代码数据集python环境GUI系统】 1.背景意义 X射线是一种波长极短、穿透能力极强的电磁波。当X射线穿透物体时,不同密度和厚度的物质会吸收不同程度的X射线,从而在接收端产生不同强度的信号…

pycharm加载虚拟环境及运行代码

pycharm加载虚拟环境及运行代码 pycharm下载地址: https://www.jetbrains.com/pycharm/download/ 1.加载虚拟环境 选择pycharm图标,点击启动。 选择OPEN, 选择工程文件夹: 选择File->setting 选择python 解释器: Project--…

扫码挪车是怎么实现的呢?一篇文章带你了解一下!扫码挪车小程序基础版上线了!!!

挪车小程序系统源码的功能特点 快速定位与挪车请求:车主通过小程序可以快速定位车辆位置,并发送挪车请求。系统会自动将请求发送给附近的车主,提醒其尽快挪车。实时通信与交互:小程序支持实时通信功能,车主之间可以通…

【C++笔记】C++编译器拷贝优化和内存管理

【C笔记】C编译器拷贝优化和内存管理 🔥个人主页:大白的编程日记 🔥专栏:C笔记 文章目录 【C笔记】C编译器拷贝优化和内存管理前言一.对象拷贝时的编译器优化二.C/C内存管理2.1练习2.2 C内存管理方式2.3 operator new与operator…

tornado

Tornado通过使用非阻塞网络1/0,可以扩展到数以万计的开放链接,非常适合 长时间轮询,WebSockets和其他需要与每个用户建立长期连接的应用程序。 特点 注重性能优越,速度快解决高并发异步非阻塞websockets 长连接内嵌了HTTP服务器…

十一、 JDK17 新特性梳理

文章目录 为什么是JDK17语法层面新特性1、文本块2 、Switch 表达式增强3、instanceof的模式匹配4、var 局部变量推导 模块化及类封装1、记录类 record2 、隐藏类 Hidden Classes3 、密封类 Sealed Classes4、模块化 Module System1 、什么是模块化2、声明一个module3 、require…

“智能密钥管家”IKE

IKE的出现 上一篇通过IPSec实现了BJ到CS的业务互通,但是是通过手工方式把加密和验证密钥手动配置,为了保障安全性,就需要经常去修改这些密钥,小型场景还好,来来回回就这2个点, 修改起来不算麻烦&#xff…

[Redis] 渐进式遍历+使用jedis操作Redis+使用Spring操作Redis

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…