Skip to content

Latest commit

 

History

History
93 lines (53 loc) · 4.44 KB

README.md

File metadata and controls

93 lines (53 loc) · 4.44 KB

首届中文NL2SQL挑战赛

竞赛链接

⚠️ 由于可能存在的版权问题,请自行联系竞赛平台或主办方索要竞赛数据,谢谢!

💡 代码运行环境至文末

成绩

本项目所采用的方案在复赛中的线上排名为第5,决赛最终成绩排名第3。

主分支下的代码以 jupyter notebook 的形式呈现,以学习交流为目的,对原始的代码经过一定的整理,并不会完全复现线上的结果,但效果不会差太多。

code 目录下的 model1.ipynbmodel2.ipynb为建模流程,nl2sql/utils 目录则包含了该任务所需的一些基础函数和数据结构。

致谢

  • 感谢追一科技的孙宁远对本次比赛做了细致的赛前辅导
  • 感谢追一科技研究员、科学空间博主苏剑林,分享了大量关于NLP方面的优质博文。本方案受到了基于Bert的NL2SQL模型:一个简明的Baseline这篇文章的启发。项目中使用的 RAdam 优化器的实现直接来自于苏剑林开源的 keras_radam 项目
  • 感谢 CyberZHG 大神的开源项目 keras-bert,本次比赛中我们使用了 keras-bert 构建我们的模型。
  • 感谢哈工大讯飞联合实验室的 Chinese-BERT-wwm 项目,本次比赛中我们使用了他们BERT-wwm, Chinese 预训练模型参数

背景

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

模型的输入为一个 Question + Table,输出一个 SQL 结构,该 SQL 结构对应一条 SQL 语句。

其中

  • sel 为一个 list,代表 SELECT 语句所选取的列
  • agg 为一个 list,与 sel 一一对应,表示对该列做哪个聚合操作,比如 sum, max, min 等
  • conds 为一个 list,代表 WHERE 语句中的的一系列条件,每个条件是一个由 (条件列,条件运算符,条件值) 构成的三元组
  • cond_conn_op 为一个 int,代表 conds 中各条件之间的并列关系,可以是 and 或者 or

方案介绍

我们将原始的 Label 做一个简单的变换

  • aggsel 合并,agg 中对表格中每一列都做预测,新的类别 NO_OP 表明该列不被选中
  • conds 分为 conds_opsconds_vals 两个部分,这么做的原因是想分两步进行预测。由一个模型先预测 conds 需要选取哪些列以及操作符,再由另一个模型预测所选取的列的比较值

Model 1

Model 1 将 Question 与 Header 顺序连接,在每个 Column 之前添加一个特殊标记,TEXTREAL,这两个特殊的 Token 可以从 BERT 预留的未训练过的 Token 中任选两个来代替。

Model 1 的架构如下:

Model 2

Model 2 则负责 cond_val 的预测。我们的思路是根据 Model 1 选择的 cond_col,枚举 cond_opcond_val,生成一系列的候选组合,将这些组合当成多个二分类问题来做

Model 2 的架构如下:

最后将 Model 2 对一些列候选组合的预测合并起来

模型训练中的一些探索尝试

关于模型训练中的优化,以及一些成功、不成功的 idea,详细可以见我们决赛答辩ppt

代码运行环境

深度学习框架: tensorflow, keras

具体版本见 requirements.txt

更方便的做法是在 Docker 中运行。比赛中用了如下 Docker 镜像

REPOSITORY TAG IMAGE ID
tensorflow/tensorflow nightly-gpu-py3-jupyter 6e60684e9aa4

由于需要用到 python3.6,使用了 tensorflow nightly build 的镜像,我将比赛时用的镜像传到 docker hub 上了,可以通过如下命令获取。

docker pull beader/tensorflow:nightly-gpu-py3-jupyter