基於IBM Model 1的詞對齊與短語抽取Python實現
- 2020 年 3 月 26 日
- 筆記
說明
其中實驗所使用的運行環境如下:
操作系統:Linux
Python版本:3.6
可選:csvkit(pip3 install csvkit



基於詞的翻譯模
簡介
基於詞的翻譯模型起源於上世紀IBM關於統計機器翻譯的原創性工作,教材主要介紹的是IBM Model 1模型。該模型能夠從大量句對齊的語料中自動實現詞對齊。
顯然這個任務中,我們即不知道英文詞和外文詞的對齊方式,也不知道他們兩兩之間的對齊概率。雖然對齊方式和對齊概率我們都不知道,但是如果我知道其中一個,問題就解決了:知道對齊方式,直接得到答案;知道對齊概率,則通過統計可以得到不同對齊方式的概率,取最大概率的對齊方式即可(極大似然估計)。
我們稱「對齊」在這個任務中是隱變量,而解決包含隱變量的訓練算法是期望最大算法(EM算法)。EM算法的工作流程如下:
初始化模型,通常從均勻分佈開始。
將模型應用於數據(求期望步驟)。
從數據中學習模型(最大化步驟)。
重複迭代步驟2和3直至收斂。
詳細的推導詳見教材第4章。



基於詞的翻譯模型
代碼解釋
本小節我們基於Python使用EM算法實現一個IBM Model 1模型,算法的偽代碼位於教材圖4.3。
由於使用EM算法,實驗需要迭代多輪,直至輪數達到預設值或者誤差小於設定閾值。每一輪的訓練函數如下所示:

代碼中比較重要的地方標註了教材對應的公式,方便對照查閱。
總訓練函數train在每一輪訓練中調用以上train_iter函數,代碼如下(結果輸出部分省略):

程序使用argparse來輸入參數,需要輸入的參數有:
–f-corpus:外語語料路徑,每行一句(中文語料需分好詞)。
–e-corpus:英語語料路徑,每行一句,須與外語語料句對齊。
–save-dir:結果保存路徑。
–epsilon:設定誤差閾值。(默認值=1e3)
–iter-num:設定訓練輪數。(默認值=10)
–save-iteration/–no-save-iteration:是否保存每一輪迭代後的詞翻譯概率(語料較大勿用,內存容易溢出,僅作為演示用)
–save-alignment/–no-save-alignment:是否保存詞對齊的結果。
小語料運行演示
我們可以先使用教材上的例句來進行實驗,這時輸入語料為:

在終端按如下參數輸入命令即可開始訓練,輸出的日誌會記載每一輪的時間和誤差:

輸出的結果中的iterations.csv
文件記錄每一個詞對齊的翻譯概率,可以看到和教材圖4.4一致:

輸出結果中的alignment.txt
文件記錄了每一個英文詞對應概率最大的外文詞:

以上試運行表明程序設計正確,接下來我們將程序運行於較大的語料上。
大語料運行演示
我們使用的FBIS語料為中英對齊語料,數量為10k,內容如下:

在終端使用如下參數訓練:

查看輸出的alignment.txt
可見:

當然為了下一章的短語抽取實驗,我們還需要記錄每個英文詞所有的對齊候選詞以及翻譯概率,這個文件以json格式輸出存儲,內容較雜亂,這裡不再展示。



基於短語的翻譯模型
簡介
基於詞的翻譯模型並不符合語言學,可以使用短語來作為基本的翻譯單元。顯然,基於短語的翻譯系統性能取決於從基於詞的翻譯模型中得到的短語翻譯表。得到詞對齊後,每輸入一個句對,可以將其表示為教材圖5.3所示矩陣,使用黑色方塊表示詞的對齊。我們的任務是從這個含有黑色方塊的矩陣中,用灰色矩形框出滿足一致性(「一致性」從視覺上很容易理解,詳見圖5.4;其形式化定義見公式(5.3))的一個或者多個黑色方塊。
算法思想比較簡單,即使用兩層for循環遍歷矩陣,遇到符合的區域就提取其中的短語。但是需要處理一些邊角情形,如對空的情況等。
短語抽取實驗
代碼解釋
本小節我們使用Python實現一個短語抽取的模型,該模型能根據之前實驗得到的詞對齊,從大量句對齊的語料中通過實現短語自動抽取(抽取的短語不一定具有語言學意義)。算法的偽代碼位於教材圖5.5。

該函數內雙重for循環不斷調整着預計抽取短語對的開始、結束下標。每找到一組可行的下標(e_start,e_end,f_start, f_end),就進入第11行使用extract函數進行抽取。例如輸入的對齊A=[(1,1), (2,2)](即教材上的黑格子坐標),則可以進行三次抽取,每次抽取的下標範圍為(1,1,1,1)、(1,2,1,2)、(2,2,2,2)(即教材上的灰矩形坐標,由兩個頂點確定)。
抽取的函數代碼如下:

注意教材上偽代碼第4行(對應此代碼第6行)缺少條件,這裡添加了後半個條件,否則輸出將是整個句對。
抽取給定的下標範圍的短語後,還要檢測其前後有無對空的可能性。is_aligned函數用於檢測這種情況:

程序使用argparse來輸入參數,需要輸入的參數有:
–f-corpus:外語語料路徑,每行一句(中文語料需分好詞)。
–e-corpus:英語語料路徑,每行一句,須與外語語料句對齊。
–save-dir:結果保存路徑。
–alignment:對齊文件路徑,json格式,可由上一個實驗自動生成。內容為一個嵌套字典,如下所示:

小語料運行演示
我們使用以上程序演示一下教材圖5.6的實例:

在終端執行後可以得到和教材完全一致的結果:

大語料運行演示
仍舊使用的FBIS語料為中英對齊語料,在終端以如下參數執行程序:

抽取的短語如下:

結果基本正確,但由於部分詞沒有相應的對齊,以及沒有對抽取行為做限制,仍有較多瑕疵。後續可以通過訓練更好的詞對齊(如正反訓練一遍做並集)、對抽取短語的長度做限制等,可以提升抽取結果的質量。



結語:神經機器翻譯與其他
機器翻譯從形式上來說,是序列到序列的任務,但是和序列標註任務(如詞性標註)不同的是,大多屬情況下,源端序列和目標端序列長度不一致。因此序列標註任務中使用的HMM、CRF等模型不再適用,需要有其他的翻譯模型。
在機器翻譯的課堂上,除了傳統的統計機器翻譯(SMT)外,我們也涉獵了若干前沿的神經機器翻譯(NMT)模型。神經機器翻譯基於深度的神經網絡模型,比如CNN和RNN。RNN擅長處理時序模型,可以從輸入端隨着時序喂入一個分詞的句子(以詞向量形式),RNN能夠在內部維持一個隱狀態參數矩陣,用於將上一個時刻的輸出,通過該參數矩陣傳入下一個時刻,以此解決長程依賴。
為了解決RNN在長距離上梯度傳遞的消失和爆炸,可以引入LSTM。LSTM在內部使用三個具有可學習參數的門控來決定哪些信息該輸入、遺忘、輸出,從而解決梯度消失和爆炸的問題。
神經機器翻譯模型一般採用seq2seq模型2,seq2seq模型採用encoder-decoder的結構,這裡的encoder和decoder可以是CNN也可以是RNN。encoder將輸入的句子轉化(編碼)為一個中間狀態向量,decoder則通過此中間狀態向量和前面已經翻譯好的詞彙解碼出下一個翻譯詞彙。seq2seq模型還可以搭配attention機制,可以得到更優秀的、更具有語言學意義的翻譯模型。
儘管NMT全面勝出SMT,但NMT參數過多,運行時間過長的缺點也不容小覷,課堂上也討論了眾多的方案。可以使用簡單但同樣強大的結構來提速,如FAIR提出的純CNN翻譯模型3;也有通過改進梯度傳導過程中類似「剪枝」的手段來避免無用部分的梯度傳導等根本性的改進4。NMT有比較大的潛力,後續有精力將嘗試研究和實現。


