中文文本處理簡要介紹
本文作者李繩,博客地址 http://acepor.github.io/ 。作者自述:
一位文科生曾勵志成為語言學家
出國后陰差陽錯成了博士候選人
三年后交完論文對學術徹底失望
回國后誤打誤撞成了數據科學家
作為一個處理自然語言數據的團隊,我們在日常工作中要用到不同的工具來預處理中文文本,比如 Jieba 和 Stanford NLP software 。出于準確性和效率的考慮,我們選擇了Stanford NLP software, 所以本文將介紹基于 Stanford NLP software 的中文文本預處理流程。
中文文本處理簡要介紹
與拉丁語系的文本不同,中文并不使用空格作為詞語間的分隔符。比如當我們說“We love coding.”,這句英文使用了兩個空格來分割三個英文詞匯;如果用中文做同樣的表述, 就是“我們愛寫代碼。”,其中不包含任何空格。因而,處理中文數據時,我們需要進行分詞,而這恰恰時中文自然語言處理的一大難點。
下文將介紹中文文本預處理的幾個主要步驟:
- 中文分詞
- 標注詞性
- 生成詞向量
- 生成中文依存語法樹
Stanford NLP software 簡要介紹
Stanford NLP software 是一個較大的工具合集:包括 Stanford POS tagger 等組件,也有一個包含所有組件的合集 Stanford CoreNLP 。各個組件是由不同的開發者開發的,所以每一個工具都有自己的語法。當我們研究這些組件的文檔時,遇到了不少問題。下文記錄這些問題和相對應的對策,以免重蹈覆轍。
Stanford NLP 小組提供了一個簡明的FAQ—— Stanford Parser FAQ 和一份詳細的Java文檔 —— Stanford JavaNLP API Documentation 。在這兩份文檔中,有幾點格外重要:
盡管PSFG分詞器小且快,Factored分詞器更適用于中文,所以我們推薦使用后者。
中文分詞器默認使用GB18030編碼(Penn Chinese Treebank的默認編碼)。
使用 -encoding 選項可以指定編碼,比如 UTF-8,Big-5 或者 GB18030。
中文預處理的主要步驟
1. 中文分詞
誠如上面所言,分詞是中文自然語言處理的一大難題。 Stanford Word Segmenter 是專門用來處理這一問題的工具。FAQ請參見 Stanford Segmenter FAQ 。具體用法如下:
bash -x segment.sh ctb INPUT_FILE UTF-8 0
其中 ctb 是詞庫選項,即 Chinese tree bank,也可選用 pku ,即 Peking University。 UTF-8 是輸入文本的編碼,這個工具也支持 GB18030 編碼。最后的0指定 n-best list 的大小,0表示只要最優結果。
2. 中文詞性標注
詞性標注是中文處理的另一大難題。我們曾經使用過 Jieba 來解決這個問題,但效果不盡理想。Jieba 是基于詞典規則來標注詞性的,所以任意一個詞在 Jieba 里有且只有一個詞性。如果一個詞有一個以上的詞性,那么它的標簽就變成了一個集合。比如“閱讀”既可以表示動詞,也可以理解為名詞,Jieba 就會把它標注成 n(名詞),而不是根據具體語境來給出合適的 v(動詞)或 n(名詞)的標簽。這樣一來,標注的效果就大打折扣。幸好 Stanford POS Tagger 提供了一個根據語境標注詞性的方法。具體用法如下:
java -mx3000m -cp "./*" edu.stanford.nlp.tagger.maxent.MaxentTagger -model models/chinese-distsim.tagger -textFile INPUT_FILE
-mx3000m 指定內存大小,可以根據自己的機器配置選擇。 edu.stanford.nlp.tagger.maxent.MaxentTagger 用于選擇標注器,這里選用的是一個基于最大熵(Max Entropy)的標注器。 models/chinese-distsim.tagger 用于選擇分詞模型。
3. 生成詞向量
深度學習是目前機器學習領域中最熱門的一個分支。而生成一個優質的詞向量是利用深度學習處理 NLP 問題的一個先決條件。除了 Google 的 Word2vec ,Stanford NLP 小組提供了另外一個選項—— GLOVE 。
使用Glove也比較簡單,下載并解壓之后,只要對里面的 demo.sh 腳本進行相應修改,然后執行這個腳本即可。
CORPUS=text8 # 設置輸入文件路徑 VOCAB_FILE=vocab.txt # 設置輸入詞匯路徑 COOCCURRENCE_FILE=cooccurrence.bin COOCCURRENCE_SHUF_FILE=cooccurrence.shuf.bin BUILDDIR=build SAVE_FILE=vectors # 設置輸入文件路徑 VERBOSE=2 MEMORY=4.0 # 設置內存大小 VOCAB_MIN_COUNT=5 # 設置詞匯的最小頻率 VECTOR_SIZE=50 # 設置矩陣維度 MAX_ITER=15 # 設置迭代次數 WINDOW_SIZE=15 # 設置詞向量的窗口大小 BINARY=2 NUM_THREADS=8 X_MAX=10
4. 生成中文依存語法樹
文本處理有時需要比詞性更豐富的信息,比如句法信息,Stanford NLP 小組提供了兩篇論文: The Stanford Parser: A statistical parser 和 Neural Network Dependency Parser ,并在這兩篇論文的基礎上開發了兩個工具,可惜效果都不太理想。前者的處理格式是正確的中文依存語法格式,但是速度極慢(差不多一秒一句);而后者雖然處理速度較快,但生成的格式和論文 Discriminative reordering with Chinese grammatical relations features – acepor 中的完全不一樣。我們嘗試了郵件聯系論文作者和工具作者,并且在 Stackoverflow 上提問,但這個問題似乎無解。
盡管如此,我們還是把兩個方案都記錄在此:
java -cp "*:." -Xmx4g edu.stanford.nlp.pipeline.StanfordCoreNLP -file INPUT_FILE -props StanfordCoreNLP-chinese.properties -outputFormat text -parse.originalDependencies
java -cp "./*" edu.stanford.nlp.parser.nndep.DependencyParser -props nndep.props -textFile INPUT_FILE -outFile OUTPUT_FILE
結論
預處理中文文本并非易事,Stanford NLP 小組對此作出了極大的貢獻。我們的工作因而受益良多,所以我們非常感謝他們的努力。當然我們也期待 Stanford NLP software 能更上一層樓。
本文原載于 https://acepor.github.io/2015/12/17/General-Pipelines/ 。