袁志祥,任冬冬,洪旭東,孫國華
(安徽工業(yè)大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,安徽馬鞍山 243000)
互聯(lián)網(wǎng)上的許多重要數(shù)據(jù)都存儲在結(jié)構(gòu)化數(shù)據(jù)庫中,其具有存儲簡單、數(shù)據(jù)質(zhì)量高等特點(diǎn)。但是對于缺少相關(guān)SQL 專業(yè)知識的用戶而言,很難快速準(zhǔn)確地寫出他們所需求的SQL 查詢語句。為解決該問題,研究人員提出NL2SQL(Natural Language to SQL)任務(wù),該任務(wù)要求模型根據(jù)自然語言問句和數(shù)據(jù)庫表生成相應(yīng)的SQL 查詢,而解決該任務(wù)的關(guān)鍵是充分地理解自然語言問句的語義,并將其映射到SQL 表達(dá)式相應(yīng)的部分(如在表中找到對應(yīng)的列名,在表內(nèi)容找到對應(yīng)的條件值,在SQL 關(guān)鍵字中找到對應(yīng)的聚合函數(shù)等)。
由于缺少人工標(biāo)注的SQL 數(shù)據(jù)集,使得該任務(wù)未被重視。2017 年,ZHOU 等人[1]發(fā)布人工標(biāo)注的大型SQL 數(shù)據(jù)集——WikiSQL,該數(shù)據(jù)集含有大量英文問句以及對應(yīng)的SQL 語句和數(shù)據(jù)庫表。2019年,追一科技公司在阿里云平臺舉辦的首屆中文NL2SQL 挑戰(zhàn)賽,提供了大型中文SQL 數(shù)據(jù)集。上述數(shù)據(jù)集為訓(xùn)練NL2SQL 神經(jīng)網(wǎng)絡(luò)及解決語義解析提供了訓(xùn)練條件。
早期將自然語言轉(zhuǎn)換為SQL 語句的研究是利用中間表達(dá)式的方法,結(jié)合自定義語法和規(guī)則將自然語言問句轉(zhuǎn)換成SQL 語句。文獻(xiàn)[2]使用斯坦福依存樹解析器[3]解析問句,根據(jù)啟發(fā)式規(guī)則生成SQL候選集,利用語法樹核函數(shù)的SVM[4]對候選SQL 進(jìn)行排序。文獻(xiàn)[5]使用無監(jiān)督學(xué)習(xí)的方法生成SQL,利用數(shù)據(jù)庫模式限制模型的輸出空間以彌補(bǔ)標(biāo)注數(shù)據(jù)的不足,同時(shí)引入擴(kuò)展?fàn)顟B(tài)空間的語義依存樹解決語義和語法不匹配的問題。文獻(xiàn)[6]通過與用戶交互來確定問句的詞語與表相應(yīng)內(nèi)容的關(guān)系,同時(shí)自定義規(guī)則調(diào)整查詢樹的結(jié)構(gòu),最終將其轉(zhuǎn)換成SQL。文獻(xiàn)[7]通過自定義一種形式化意義語言實(shí)現(xiàn)了中文GIS 自然語言接口。上述方法都是依賴高質(zhì)量的語法來解析問句,不能處理用戶語法多變的問句,因此具有局限性。
隨著深度學(xué)習(xí)的發(fā)展,人們開始將NL2SQL 的研究轉(zhuǎn)向訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型。早期的深度學(xué)習(xí)模型將NL2SQL 看成序列生成問題,利用sequence-tosequence 模型[8]生成SQL 查詢。文獻(xiàn)[9]運(yùn)用注意力機(jī)制,通過sequence-to-sequence 的解碼層自動生成SQL 序列。為提升SQL 查詢的準(zhǔn)確率,結(jié)合SQL 語法限制輸出空間的模型被提出。文獻(xiàn)[1]提出Seq2SQL 模型,該模型將SQL 生成分為聚合函數(shù)分類、select column 以及where 子句生成三部分,同時(shí)利用強(qiáng)化學(xué)習(xí)解決序列生成引發(fā)的“order matters”問題。文獻(xiàn)[10]利用SQL 語句的格式和語法提出sequence-to-set 模型,將SQL 語句任務(wù)分成多個(gè)子任務(wù),并結(jié)合column attention 提升SQL 生成的準(zhǔn)確率。文獻(xiàn)[11]結(jié)合知識圖譜識別問句中的實(shí)體。文獻(xiàn)[12]利用sequence-to-sequence 以及sequence-toset 模型各自的優(yōu)勢,提出sequence-to-action 模型。該模型使用預(yù)定義的action 來填充SQL 查詢草圖的插槽。文獻(xiàn)[13]通過SQL 執(zhí)行結(jié)果修復(fù)錯(cuò)誤的SQL查詢。
近年來,大規(guī)模預(yù)訓(xùn)練模型在許多自然語言處理的下游任務(wù)中取得優(yōu)秀的成績,許多基于預(yù)訓(xùn)練的Nl2SQL 模型被提出。研究人員使用Bert[14-15]預(yù)訓(xùn)練模型替代glove[16]作為模型的編碼器,基于Bert 編碼器提出3 種不同的輸出層,超過了人類手動標(biāo)注。文獻(xiàn)[17]基于MT-DNN 模型[18]提出X_SQL 模型,通過強(qiáng)化上下文信息得到數(shù)據(jù)庫模式新的表達(dá)式,更好地表征其結(jié)構(gòu)信息以用于下游任務(wù)。
現(xiàn)有許多深度學(xué)習(xí)模型都僅局限于數(shù)據(jù)庫結(jié)構(gòu)對模型的影響,忽略了表內(nèi)容對NL2SQL 任務(wù)的重要性。問句的詞語與表內(nèi)容不匹配,導(dǎo)致生成的SQL 查詢在數(shù)據(jù)庫執(zhí)行錯(cuò)誤。而結(jié)合表內(nèi)容不僅可以幫助模型更好地識別問句中對應(yīng)的SQL 語句實(shí)體,還可以緩解問句與表內(nèi)容不一致的問題。本文在SQLova[13]的框架下,提出一個(gè)同時(shí)結(jié)合表結(jié)構(gòu)和內(nèi)容的NL2SQL 模型。使用字符串匹配的方法篩選出與問句相關(guān)的表內(nèi)容,利用Bert 編碼器對問句、表列名以及相關(guān)表內(nèi)容進(jìn)行字編碼,value attention 和column attention 將表結(jié)構(gòu)和內(nèi)容的表示特征加到問句表達(dá)式中,幫助模型更好地理解用戶問句的語義,識別問句中的表列名和條件值,并根據(jù)多個(gè)子模型的分類方法填充SQL 草圖完成SQL 查詢。
本文使用追一公司在阿里云發(fā)布的中文數(shù)據(jù)集作為整篇文章的示例。該中文數(shù)據(jù)集的任務(wù)是在給定問句和數(shù)據(jù)庫表的情況下生成相應(yīng)的SQL 查詢。其數(shù)據(jù)格式如圖1 所示,每條數(shù)據(jù)對應(yīng)一個(gè)數(shù)據(jù)庫表和1 條問句以及SQL 查詢。
圖1 中文數(shù)據(jù)集數(shù)據(jù)格式Fig.1 Chinese dataset data format
對于問句的詞語與表內(nèi)容不完全匹配的問題,如圖1 中的“死侍2”與表內(nèi)容的“死侍2:我愛我家”不一致的情況,會導(dǎo)致SQL 查詢結(jié)果為空。模型結(jié)合表內(nèi)容通過字符串匹配的方法來替換模型從問句中生成的詞語,即將“死侍2:我愛我家”替換成“死侍2”,緩解表內(nèi)容與問句詞語不一致的問題。在WikiSQL 測試集上比SQLova 準(zhǔn)確率高出1.4%,實(shí)驗(yàn)結(jié)果表明,結(jié)合數(shù)據(jù)庫結(jié)構(gòu)和內(nèi)容特征可以幫助模型更好地理解問句語義,提升SQL 查詢的準(zhǔn)確率。
本文將序列生成任務(wù)轉(zhuǎn)化為多個(gè)分類任務(wù),通過填充SQL 草圖生成SQL 查詢。該中文數(shù)據(jù)集的SQL 查詢對應(yīng)的SQL 草圖如圖2 所示,草圖的每個(gè)槽對應(yīng)不同子任務(wù)。以$開頭的標(biāo)記表示槽標(biāo)記,$后面的名稱表示需要預(yù)測的類型。其中:$AGG 表示模型預(yù)測SQL 查詢的聚合函數(shù),取值集合包括{‘ ’,‘MAX’,‘MIN’,‘COUNT’,‘SUM’,‘AVG’};$SELECT_COL 和$WHERE_COL 表示模型需要預(yù)測的數(shù)據(jù)庫表列名;$WHERE_RELA 表示where 子句的關(guān)系,包括{‘ ’,‘a(chǎn)nd’,‘or’};$WHERE_OP 表示SQL 查詢的操作符,包括{‘=’,‘>’,‘<’};$WHERE_VAL 表示從問句中生成的SQL 查詢條件值;(…)*表示子句的數(shù)量是零個(gè)或多個(gè)。
圖2 SQL 草圖Fig.2 SQL sketch
在SQLova 框架下,將模型分成Encoder 層、Attention 層以及Ouput 層三部分,具體結(jié)構(gòu)如圖3 所示。在Encoder 層,SQLova 將問句和表列名作為Bert 預(yù)訓(xùn)練模型的輸入,在SQLova 模型的基礎(chǔ)上將相關(guān)表內(nèi)容作為Bert 的輸入;在Attention 層,SQLova 通過Column Attention 得到問句表達(dá)式,利用Value Attention 將表內(nèi)容的信息融入問句的表達(dá)式中;在Output 層,為了更好地預(yù)測Where Column和Where Value 子任務(wù),將基于表內(nèi)容的問句表達(dá)式作為額外輸入。
圖3 模型整體結(jié)構(gòu)Fig.3 Model overall structure
在解析問句語義時(shí),相對于結(jié)合數(shù)據(jù)庫結(jié)構(gòu),表內(nèi)容對于生成SQL 查詢有著重要作用。結(jié)合表內(nèi)容可以幫助模型更好地找到SQL 查詢的條件值,如圖1中的示例,模型根據(jù)表內(nèi)容“大黃蜂”更好地找到問句中的“大黃蜂”。同時(shí)結(jié)合表內(nèi)容還可以幫助模型預(yù)測問句中表列名,比如“北京”這個(gè)條件值使模型更傾向于預(yù)測“城市”列名。但將表內(nèi)容所有的信息作為Bert 編碼器的輸入,給模型帶來過多的干擾因素,同時(shí)會使得模型的輸入過長,所以本文篩選出與問句有關(guān)的表內(nèi)容作為模型的輸入。
為得到與問句相關(guān)的表內(nèi)容,模型將問句進(jìn)行分詞處理,枚舉長度為1~4 的所有n-garms,使用Jaccrad公式計(jì)算組合的詞語與表內(nèi)容的相似度。若問句中出現(xiàn)單引號或者雙引號以及書名號時(shí),直接使用該詞語與表內(nèi)容進(jìn)行相似度計(jì)算。計(jì)算公式如下:
如果相似度超過一定的閾值,則將表內(nèi)容加到模型的輸入中。本文利用得到的相關(guān)表內(nèi)容、問句和表列名共同構(gòu)成Bert 編碼器的輸入。
基于語境的動態(tài)詞表達(dá)式ELMO[19-20]和Bert[14]預(yù)訓(xùn)練模型,在處理許多自然語言處理任務(wù)方面表現(xiàn)突出。SQLova[13]的實(shí)驗(yàn)結(jié)果也表明利用Bert 模型得出的基于上下文和表的詞表達(dá)式,可以有效提高NL2SQL 任務(wù)的準(zhǔn)確率。模型使用Bert 模型對其進(jìn)行字編碼,同時(shí)將問句、數(shù)據(jù)庫列名以及相關(guān)表內(nèi)容作為Bert 的整體輸入。Bert 中的self-attention 機(jī)制使得模型更注重問句中列名和條件值,獲得更準(zhǔn)確的表達(dá)式。具體如圖3 所示,其中[CLS]和[SEP]是用于分類和上下文分離的特殊標(biāo)記。本文使用[SEP]來分隔問句、列名以及表內(nèi)容,與位置向量共同構(gòu)成bert 編碼器的輸入,得到對應(yīng)的問句、列名以及表內(nèi)容的特征表達(dá)式Hq、Hcol和Hval。
將Hq、Hcol、Hval通過3 個(gè)Bi-LSTM,選擇最后的隱藏狀態(tài)得到對應(yīng)的表達(dá)式Eq、Ecol、Eval。在預(yù)測Select Column 與Where Column 子任務(wù)時(shí),為表示不同列名在自然語言問句的重要程度,本文引用SQLNet 的Column Attention[9]表示問句的表達(dá)式,具體如下:
其中,Wcol是d×d的參數(shù)矩陣,softmax 函數(shù)對輸入矩陣的每行做歸一操作,wq|col表示列名對問句的注意力權(quán)重,Eq|col是結(jié)合表內(nèi)容的問句表達(dá)式。
為更好地理解問句中的條件值,本文提出Value Attention,使問句的表達(dá)式可以在預(yù)測SQL 查詢的條件值時(shí)更好地反映出表內(nèi)容在問句的重要信息。本文首先利用問句和表內(nèi)容的表達(dá)式計(jì)算問句對應(yīng)表內(nèi)容的權(quán)重,其中,Wval是參數(shù)矩陣。根據(jù)得到的每個(gè)問句的權(quán)重wq|val,然后與問句的特征表達(dá)式Eq進(jìn)行加權(quán)乘積求和得到基于表內(nèi)容問句的新表達(dá)式,具體公式如下:
模型利用Attention 層得到的輸出來預(yù)測SQL 草圖不同的槽,其中槽分別對應(yīng)8 個(gè)子任務(wù),分別是Select Number、Select Column、Select Agg、Where Relation、Where Number、Where Column、Where Operator、Where Value。Output 層的子任務(wù)以及之間詳細(xì)的依存關(guān)系如圖4 所示。由于Select Number 子任務(wù)與Where Number 以及Where Relation 模型結(jié)構(gòu)相同,在圖中只顯示出Select Number 子模型的結(jié)構(gòu)。
圖4 輸出層子模型之間的關(guān)系Fig.4 Relationship between output layer submodels
子任務(wù)分別介紹如下:
1)Select Number。該任務(wù)是確定Select 子句中表列名的數(shù)量,模型把該任務(wù)當(dāng)成一個(gè)4 分類任務(wù),具體公式如下:
其中,Eq|q表示基于self-attention 的問句表達(dá)式,Vsnum和Wsnum分別對應(yīng)4×d、d×d的參數(shù)矩陣。
2)Select Column。該任務(wù)根據(jù)概率的大小從表中k個(gè)列名作為SQL 語句的Select 查詢字段,其中,k是Select Number 預(yù)測的個(gè)數(shù),具體公式如下:
3)Select Agg。該任務(wù)是預(yù)測SQL 查詢的聚合函數(shù),利用Select 子句的列名和問句進(jìn)行分類任務(wù),具體公式如下:
4)Where Number:該任務(wù)是利用問句的表達(dá)式預(yù)測Where 子句的個(gè)數(shù),具體公式如下:
5)Where Relation。該子模型是預(yù)測Where 子句之間的關(guān)系。若Where 子句的數(shù)量為1 時(shí),默認(rèn)Where Relation 為空;當(dāng)Where 子句的數(shù)量大于1 時(shí),將問句表達(dá)式作為輸入對Where 子句的關(guān)系進(jìn)行二分類(and,or),具體公式如下:
6)Where Column。該任務(wù)是確定Where 子句的表列名,利用列名、基于表結(jié)構(gòu)和表內(nèi)容的問句表達(dá)式進(jìn)行分類任務(wù)。根據(jù)SQL 語法,Select Column 與Where Column 不能同時(shí)對應(yīng)數(shù)據(jù)庫表的同一個(gè)列名,因此把Select 子句生成的列名也作為該任務(wù)的輸入,公式具體如下:
7)Where op。該子任務(wù)是確定Where 子句的操作符,需要根據(jù)Where 子句的表列名與問句表達(dá)式來進(jìn)行分類,具體公式如下:
8)Where Value。該任務(wù)通過序列標(biāo)注從問句中找到每一個(gè)Where Column 對應(yīng)的條件值。除了基于列名問句表達(dá)式與Where Column 預(yù)測的Column表達(dá)式作為Where Value 任務(wù)的輸入外,基于Value attention 的問句表達(dá)式也可以幫助模型預(yù)測Where Column,具體公式如下:
若該任務(wù)生成的條件值與表內(nèi)容存在不匹配的問題,模型結(jié)合表內(nèi)容利用字符串匹配的方法替換生成的條件值。
在訓(xùn)練階段,由于模型被分成多個(gè)分類子任務(wù),因此目標(biāo)函數(shù)可以被看成多個(gè)子模型的交叉熵?fù)p失函數(shù)的和。針對表列名的預(yù)測,模型通過交叉熵?fù)p失函數(shù)計(jì)算標(biāo)注數(shù)據(jù)出現(xiàn)的表列名與預(yù)測列名概率的損失;針對Where Value 子任務(wù)的預(yù)測,通過預(yù)測問句中的條件值的開始位置和結(jié)束位置與真值的損失。交叉熵?fù)p失函數(shù)的具體公式如下:
其中,x表示訓(xùn)練數(shù)據(jù),y表示真值,N表示樣本的數(shù)量。本文通過最小化目標(biāo)函數(shù)的方式來更新模型參數(shù)。
本文分別在追一公司發(fā)布的中文數(shù)據(jù)集和WikiSQL 數(shù)據(jù)集進(jìn)行測試。WikiSQL 數(shù)據(jù)集是ZHONG 等人[1]發(fā)布的手工數(shù)據(jù)集,被廣泛應(yīng)用于NL2SQL 深度學(xué)習(xí)模型,該數(shù)據(jù)集擁有80 000 多條訓(xùn)練數(shù)據(jù)以及對應(yīng)的20 000 多張數(shù)據(jù)庫表。中文數(shù)據(jù)集共有50 000 多條數(shù)據(jù),與WikiSQL 不同的是,中文數(shù)據(jù)集的SQL 查詢中Select 子句的表列名可以是多個(gè),另外,Where 子句之間的關(guān)系不是默認(rèn)的“and”關(guān)系,其條件數(shù)量以多個(gè)為主。本文使用Logic Form Accuracy(Logic)和Execution Accuracy(Exe)兩個(gè)指標(biāo)評估模型性能,其中,Logic Form Accuracy 是指生成的SQL 查詢與數(shù)據(jù)集的SQL 真值比對的準(zhǔn)確率,Execution Accuracy 是指生成的SQL 語句與數(shù)據(jù)庫的SQL 語句在數(shù)據(jù)庫執(zhí)行完查詢結(jié)果后進(jìn)行比對的準(zhǔn)確率。
在實(shí)驗(yàn)中,本文使用768 維的Bert 作為模型的編碼器,其最大長度設(shè)置為222,在訓(xùn)練階段微調(diào)Bert 預(yù)訓(xùn)練模型的參數(shù);設(shè)置模型使用的Bi-LSTM隱藏層的維度是100,丟失率為0.3,不同子任務(wù)之間的Bi-LSTM 的參數(shù)不共享;設(shè)置迭代次數(shù)為100,批訓(xùn)練次數(shù)為8,每次迭代打亂訓(xùn)練數(shù)據(jù)的順序,學(xué)習(xí)率設(shè)置為0.003,使用Adam 方法優(yōu)化參數(shù)模型。
表1 給出本文模型和不使用表內(nèi)容的模型在中文數(shù)據(jù)驗(yàn)證集上的實(shí)驗(yàn)結(jié)果,其中,“-表內(nèi)容”表示不使用表內(nèi)容的模型。可以觀察到在S_col 任務(wù)上,原模型比不使用表內(nèi)容的模型準(zhǔn)確率高出0.021,在W_col 任務(wù)上,比不使用表內(nèi)容的模型高出0.007,結(jié)果表明,結(jié)合表內(nèi)容可以在一定程度上幫助模型預(yù)測與表內(nèi)容相關(guān)的表列名;原模型在W_val 上高出0.01,這是因?yàn)樵P涂梢酝ㄟ^表內(nèi)容更好地理解問句中的SQL 查詢條件值。例如問句“愛情的呼喚這部電影是哪家單位引進(jìn)的”,對應(yīng)正確的Where 子句是“Where 劇名=愛情呼叫轉(zhuǎn)移and 類別=電影”,結(jié)合表內(nèi)容可以幫助模型預(yù)測“電影”應(yīng)該作為SQL查詢的條件值,而不是表列名。不使用表內(nèi)容的模型比原模型在Execution 低0.19,在Logic Form 低1.8%,說明模型利用Attention 層的Value Attention 注意力機(jī)制,獲得更加準(zhǔn)確的問句表達(dá)式,可以更好地幫助下游任務(wù)分類。
表1 不同模型在中文數(shù)據(jù)集上的實(shí)驗(yàn)結(jié)果Table 1 Experimental results of different models on the Chinese dataset
表2 給出不同模型在WikiSQL 驗(yàn)證集和測試集上的實(shí)驗(yàn)結(jié)果。從表2 可以看出,本文模型的準(zhǔn)確率明顯高于表中前5 個(gè)模型。針對SQLova 的模型,本文獲取到SQLova 源碼得到的模型由于不知道SQLova 具體的參數(shù),實(shí)驗(yàn)結(jié)果比原文給出的準(zhǔn)確率低。本文模型在驗(yàn)證集上的Logic Form 比SQLova高出0.18,在測試集高出0.15;在驗(yàn)證集上的Execution Accuracy 比SQLova 模型高出0.14,在測試集高出0.14。該結(jié)果表明結(jié)合表內(nèi)容和表結(jié)構(gòu)可以有效地提高SQL 生成的準(zhǔn)確率。
表2 不同模型在WikiSQL 數(shù)據(jù)集上的實(shí)驗(yàn)結(jié)果Table 2 Experimental results of different models on the WikiSQL dataset%
本文在SQLova 框架下,提出一個(gè)基于表結(jié)構(gòu)及其表內(nèi)容的NL2SQL 模型,利用Column Attention和Value Attention 來更好地理解用戶問句的語義。將序列生成任務(wù)轉(zhuǎn)變成多個(gè)分類任務(wù),通過填充SQL 草圖生成SQL 查詢。實(shí)驗(yàn)結(jié)果表明,結(jié)合表結(jié)構(gòu)和內(nèi)容可以提升模型生成單表的SQL 語句的準(zhǔn)確率。但該模型暫不能處理結(jié)合生活常識解決的問題,同時(shí)在實(shí)際情況中,用戶提出的問題往往需要多張數(shù)據(jù)庫表來解決,而多表對應(yīng)的SQL 查詢會涉及表名、多張表的連接方式、嵌套查詢以及增加Group、Order 等SQL 關(guān)鍵字的情況。下一步研究方向是處理涉及多表查詢的Spider 數(shù)據(jù)集,利用人們的生活常識生成SQL 查詢,以更符合實(shí)際應(yīng)用場景。