「句讀」的自動生成

「句讀」的自動生成

句讀之不知,惑之不解,或師焉,或不焉,小學而大疑,吾未見其明也。

——韓愈 《師說》

古人讀書,「句讀」是幫助其斷句、理解句子含義甚至消除歧義的重要技能。雖然現代人閱讀的古文往往是經過人工添加了標點符號的,但仍有大量的文獻是沒有任何斷句的,直接閱讀這樣的資料對於相關專業的學者恐怕也要耗費一番精力;而另一方面,完全依靠人工方法去標註這些文獻的工作量是不可想像的。

今天在這裡分享一些用深度學習的方法自動做「句讀」的結果——結論是一個簡單的模型都可以在很大程度上正確地為完全無標點的古文添加標點,甚至在風格相差較大的內容上也取得了不錯的效果。

0. 數據選取

主要選取《續資治通鑒長編》作為數據集。該文獻共520卷,按時間順序記錄了北宋時期的歷史。訓練集選取前514卷(99%),餘下6卷為測試集;此外,還選取《歷代名臣奏議》中的部分內容進一步驗證結果。之所選取《歷代名臣奏議》,是因為在網上找了好久也沒找到這本書帶標點的部分( @經略幽燕我童貫 嫖相幫忙確認下 :)),也算是寫這篇文章的起因吧。

考慮的標點符號全部從《續資治通鑒長編》中提取,包括逗號(,)、句號(,)、冒號(:)、分號(;),問號(?)以及雙引號(「和」)和雙括弧(()),再加上無標點共10種類別。

1. 基於卷積神經網路(CNN)的方法

雖然最開始還是想用循環神經網路做第一個模型,但考慮到「句讀」不僅和斷句處之前的內容相關(上文),也和之後的文字(下文)有緊密地聯繫。鑒於這種局部特性,決定先試驗一下卷積神經網路(CNN)的效果。

由於我對CNN也是一知半解,第一個冒出的想法是使用一個1D的CNN;然後才意識到文字序列不像語音序列,每個字不能表示成一個具有數值意義的標量。簡單查閱了一些論文,才發現似乎主流的做法還是通過one hot或word embedding的方法將1D的文字序列轉換成2D的「圖像」——直覺上感覺這樣的做法還是比較奇怪的,因為畢竟在擴展的這一維度上並沒有CNN期望的空間局部性質。無論如何,還是簡單將網路結果設計如下:

CNN模型的網路結構

大體上,一個待句讀的句子通過獲取每個字的embedding表示成一張「偽」圖像,經過兩層卷積+池化層後,再經過一個全連接層,為每個字得到一個10位的logit值,表示其後接標點的log概率。這裡之所以使用embedding而不直接使用one hot的表示,一是由於one hot維度太高導致訓練效率極低,二是考慮embedding結構更緊密,我們希望使用更小的核函數就可以保證捕捉到足夠的局部信息。損失函數使用交叉熵。

然而,理想很豐滿,現實很骨感:訓練結果甚至在訓練集本身上都表現極差(幾乎為每個字後面強行加上了冒號,不知道冒號有什麼特別的地方)。雖然不確定是哪裡出現問題,多半可能是網路結構的設計不合理。後來發現了一個基於CNN做加標點的工作([5]),但還沒有仔細閱讀。

2. 基於循環神經網路(RNN)的方法

不得已,退回到最初的想法,使用一個簡單的LSTM單元構建的RNN,輸入為word embedding,並將其輸出再經過一個全連接層得到類似上面CNN中的10位logit值。網路結構很簡單,這裡就不贅述了。

下面給出了在測試集上的損失函數和準確度隨迭代次數的變化(本文中所有模型均使用Tensorflow實現;訓練過程使用Adam演算法)。其中Accuracy on Punc是在所有標點位上的準確率(可能更確切一點應該叫召回率;考慮到絕大部分字後面不接標點,這一指標應是我們最關心的),Accuracy on non-Punc是在所有非標點位上的準確率,而Accuracy則是所有位置上的準確率。

RNN的訓練過程

可以看到,Accuracy on Punc的準確率在30%左右——考慮到共有10種標點,隨機猜測的準確率為10%(又由於一般逗號居多,只猜逗號可能更高一些),說明我們的結果已經要優於」瞎猜「了,但仍然不夠理想。另外Accuracy和Accuracy on non-Punc分別超過80%和接近90%,但對於」句讀「的任務來說並沒有太大意義。

3. 基於雙向循環神經網路(Bidirectional RNN)的方法

上面這種簡單的RNN的效果並不理想的一個重要原因,也是我們一開始想要使用CNN的理由是:是否加標點同時和下文有關。同時結合上、下文信息的RNN,自然想到雙向循環神經網路,於是設計網路結構如下:

Bidirectional RNN模型的網路結構

輸入同樣還是embedding,不過將其送入兩個方向一前一後的LSTM單元中;兩個LSTM單元的輸出做element-wise product後,再分別結過一層全連接網路,得到各個字後面標點的logits。用測試集上的指標表示的訓練過程如下:

Bidirectional RNN的訓練過程

首先注意到的是,Accuracy on Punc的準確率已經提高到近60%,較前面簡單的RNN模型提高了近一倍。另外,在模型收斂後似乎出現了數值精度的問題,導致了精度在圖中近800個batch處發生了斷崖式跌落,原因不詳。

4. 具體結果示例

光給數據不如上幾個具體的結果來得更直觀。下面給出最終模型在演算法訓練過程中未見的6卷測試集中的三段話加註標點結果:

人工加註標點和模型加註標點的結果比較

可以看出,Bidirectional RNN生成的結果與人工標註的結果幾乎毫無差別,對於閱讀而言基本上達到了幫助讀者斷句釋義的功能。

更進一步地,我們取《歷代名臣奏議》中兩段宋代大臣上奏的內容,得到如下結果(注意由於我們的字典完全取自《長編》,因而對只在《歷代名臣奏議》中出現的字採取了直接過濾的處理方法,所以可能部分文字有缺失):

建中靖國元年給事中上官均論治天下在好學廣問上奏曰:臣聞人主之治,天下一日萬機,不可勝察也。而明君操術,蓋有至要可以不勞而治。蓋好學,則知天人之道,通古今之變,好問,則察臣之情,達天下之政,通古今而達事情物理,豈有不燭注措,豈有不善哉?說命曰:念終始典於學。揚雄曰:學之為王者事,其已久矣。此言人主之,不可不好學也。仲尼稱:舜曰:舜好問而好察邇言孟軻稱舜曰:大舜善與人同樂,取諸人以為善。仲虺之告。湯曰:好問則裕自用,則小此言人主之不可不廣問也。然而人主之學異乎?人臣之學,何則?人臣之學,或以文詞為工,或以博記為能,以文詞為工,則有不適用之患,以博記為能,則有不燭理之蔽,非所謂善學也。人主之學,在乎簡而知要達,而適用知要在乎明道明道,在乎味五經之言,適用在乎觀前世治亂盛衰之跡,而近稽祖宗聖明相繼,治天下之意,因已然之跡,而考其理亂,因理亂而鑒,其所以得失,可以知要而適用矣。此人主之好學所以為先務也。天下之政,有利有害,百官之有邪有正非廣問而參稽之,則利害未易,見邪正未易,明,利害未盡見,則事,或過舉邪正未盡明,則奸佞之徒,或乘間而害正,此人主之好問所以為政之要也。臣竊觀陛下仁而有中正而不偏清凈而寡,欲溫恭而盡下,可謂有上聖之資矣。臣願陛下退朝燕閑,觀經閱史,以明理義之大,致達治亂之大體,因進對之臣心下問,以考政,事之得失。觀臣之志,趣如此,則天下之義理,臣下之邪正判如白之辨矣。陶之告舜曰:在知人在安民禹曰:知人則哲能官人安民則惠黎民之燭義理而辨,邪正,則能官人能安民矣。堯、舜之治,天下不過如此矣。

……

光宗紹三年,御史台主簿彭龜年上疏曰:臣聞講讀之官,責任最重,故程頥謂天下重任,惟宰相與經筵,天下治亂,系宰相君成,就在經筵,以臣觀之,君不修,雖治,難保要知經筵之重,尤在宰相之先,是以祖宗重此官具有成憲未得之則求之,惟恐其不廣。既得之則親之,惟恐其或揆之近時,頗非其舊。臣敢為陛下條列陳之。臣觀祖宗精擇經筵,不限資任,或以布衣而就職,或解政柄而復為,蓋以勸講之臣,當用明經之士,經須素業,人各有長。儻平時未嘗留意於斯,則雖賢何以克堪其任?今不問所學,以序遷此,非其舊者一也。臣觀祖宗引對臣僚莫如經筵,親在太祖朝,非時召王昭素講說經書,在太宗朝,命呂文仲為侍讀,多以日晚,召見及真宗嗣位,首置侍讀。侍講學士,命邢昺楊徽之夏侯嶠為之,常,令昺宿秘閣訪問或至中夕,自此,遂為故事,夜直率置常員,不特與之究義理之亦欲籍之杜逸豫之隙。蓋聞古今之治亂,則警懼易動,聞閭閻之艱苦,則憂念自生。退即宴閑必無過當,聖謨,深人未易知。竊見近日宣召,經筵,多用晝接,臣不知游息,深宮之際,何以為保養,夜氣之方,此非其舊者二也。臣仰惟陛下留心問學,不愧古先,嘗於郊禋之時,豫展講讀之日,厥修時敏何待人言,而臣之區區,猶及此者。臣嘗見范祖禹所編帝學上下數千年,未有若祖宗好學之篤者,陛下欲法祖宗舍,此宜無大者也。臣愚慾望陛下柬拔名儒,置之講席,但問經學之深,淺不校官資之崇卑,官大,則加之學士之名,官小則任以說書之職日與之講論義理夜與之商古。今自此聖性日益,明聖日益盛大,既有義理之可樂,自然物慾之難移,保國寧家,莫先於是。惟陛下留神。

可以看到,對於風格有一定差別(《長編》中除了奏陳的內容,還有大量敘事、論述的文字)的內容,我們的模型也基本上按照語義添加了標點!這進一步說明我們的模型還是具有較好的泛化能力的。

5. 尾聲

加標點的工作似乎並不常見,或許是因為對於當下生成的文字內容,絕大多數都是直接或間接由人工錄入的;而一個可能生成未加標點文字的領域是語音識別,但考慮到通過語音中的停頓有助於識別效果,加標點在某種意義上可以看作語音識別的副產品,因而似乎也不是該領域中的研究熱點。後知後覺地去google了一下,發現還是有幾篇相關文章([1, 2, 3])和基於keras和theano的開源實現([4, 5])的,但都是近兩年的內容,引用度也不甚高。但個人認為在我國歷史文獻處理工作中,相關工作還是有一定借鑒意義的。

參考文獻

[1] A Neural Network Architecture for Multilingual Punctuation Generation

[2] Deep Learning for Punctuation Restoration in Medical Reports

[3] LSTM for Punctuation Restoration in Speech Transcripts

[4] ottokart/punctuator2

[5] vackosar/keras-punctuator


推薦閱讀:

TAG:深度學習DeepLearning | 自然語言處理 | 宋史 |