天天看點

NLTK中文詞性自動标注

1.      說明

學習自然語言處理,一定會參考NLTK,主要是學習它的思路, 從設計地角度看看能做什麼. 其本質就是把語言看成字元串,字元串組,字元串集,尋找其間規律.

NLTK是多語言支援的, 但目前網上的例程幾乎沒有用NLTK進行中文的,其實可以做。比如标注功能, 它自身提供了帶标注的中文語庫(繁體語料庫sinica_treebank). 下面來看看怎樣通過資料訓練來實作中文詞性自動标注.

可以利用它來标注中本,也可以尋找和驗證一些隐性的規律.

2.      相關知識

1)       詞性标注

詞彙按它們的詞性(parts-of-speech,POS)分類以及相應的标注它們的過程, 詞性包括:名詞、動詞、形容詞, 副詞等.

2)       中文字元的顯示

Python内部編碼是unicode, 是以輸出中文常常像這樣"\u4eba\u5de5", 用print函數輸出時, 将自動轉換成本地字元集, 也可以使用encode(‘utf-8’)函數轉換.

3)       資料集,訓練集,評估

有監督的機器學習一般都是把資料分成兩個部分, 一部分用于訓練, 一部分用于測試, 還可以通過不同分組交叉驗證. Nltk提供了evaluate()函數評估标注效果.

4)       預設标注(Default Tagger)

事先對語料庫做了統計(利用nltk.FreqDist()), 出現最多的是名詞.

在這裡,預設标注為名詞

5)       正規表達式标注(Regexp Tagger)

用比對模式配置設定标記給辨別符.在英文進行中,常用此方式識别各種形态(時态,字尾等),中文識别中也可以使用它來識别标點,數字等.

6)       一進制标注(Unigram Tagger)

一進制标注基于一個簡單的統計算法: 對每個辨別符配置設定這個獨特的辨別符最有可能的标記.

在這裡就是配置設定給具體單詞,它最常出現的詞性.

7)       多元标注(N-gram Tagger)

多元标注使用訓練集來确定對每個上下文哪個詞性标記最有可能。上下文指目前詞和它前面 n-1 個辨別符的詞性标記.

在這裡,就是找一些規律, 比如: XX常出現在名詞之前, YY常出現在動詞之後. 通過某個詞以及它之前那個詞的詞性來判斷它的詞性. 這就是二進制标注. 同理,可以生成三元甚至多元标注.詞的距離越遠影響越小, 也更占用資源, 一般二進制到三元就夠了.

8)       組合标注

更精确的算法在很多時候落後于具有更廣覆寫範圍的算法(比如滿足三元标的詞可能非常少), 是以有時我們組合多個标注器,

在這裡,組合 bigram 标注器、unigram 标注器和一個預設标注器

3.      代碼

# encoding=utf-8

import nltk
from nltk.corpus import sinica_treebank	# 帶标注的中文語料庫

# 用print輸出本地字元格式
def dump_result(result):
    for item in result:
        print item[0],",",item[1],
    print
    
# 等标注的詞,以空格分詞(分詞問題不在此讨論)
raw = '讓 人工 智能 能夠 更 有效地 甄別 虛假 和 低俗 內容 並 控制 其 傳播 是 當前 業界 和 學界 要 重點 研究 的 問題'.decode('utf-8')
tokens = nltk.word_tokenize(raw)

sinica_treebank_tagged_sents = sinica_treebank.tagged_sents()	# 以句為機關标
size = int(len(sinica_treebank_tagged_sents) * 0.9)
train_sents = sinica_treebank_tagged_sents[:size]	# 90% 資料作為訓練集
test_sents = sinica_treebank_tagged_sents[size:]	# 10% 資料作為測試集

t0 = nltk.DefaultTagger('Nab')	# 詞性的預設值為名詞
t1 = nltk.UnigramTagger(train_sents, backoff=t0)	# 一進制标注
t2 = nltk.BigramTagger(train_sents, backoff=t1)	# 多元(二進制)标注

dump_result(t2.tag(tokens))
print t2.evaluate(test_sents)	# 根據帶标注的文本,評估标注器的正确率
           

4.      主要思想

詞性标注的主要思想是提煉最容易出現的可能性 (在不同層次: 所有詞, 具體詞, 詞間關系),它是一套統計方法,也是分類器的一個應用.

NLTK的詞性标注隻是抛磚引玉,使用同樣方法,還也可以實作标注詞義(一詞多義的消歧), 字音(多音字)等等.

通過它來看看自然語言的處理方法, 有了自己的工具, 也能更靈活地使用這個功能, 目前還很簡陋,下面來看看怎麼改進它.

5.      改進

1)       缺少訓練資料

訓練資料不足, 或者一些标注本身的問題, 需要改進和增加訓練資料.錯誤分類可以通過大量資料的校正,同時也需考慮語境,選擇不同訓練集.

上例中的sinica_treebank語料庫自帶1萬個句子, 10萬左右的詞,文本也比較單一,執行以上程式後可以看到, 準确率在75%左右.

想要訓練出更理想的标注器, 需要更多帶标注的資料(有監督學習). 資料從哪兒來呢? 其實也簡單, 可以用現有靠譜的分詞工具(比如: 線上的”語言雲”, 離線的”結巴”)的标注結果去訓練你自己的标注器.

2)       有一些詞本身就是特例, 就如同”海豚不是魚類”

統計歸類本身無法處理, 除了統計的方案, 還可以添加一一對應的詞與标注的映射表來解決此類問題.

3)       新詞/不常用詞

未被訓練過的詞,可以用一些特殊标記加入字典,在資料積累到一定數量時總結其規律.

N元标注再抽象一個層次是發現詞性間的規律,比如"名詞前是形容詞的可能性比較大",借此來處理不能識别的"新詞".

也可以通過WordNet等字典檢視具體詞的詞性.有一些詞雖然很少出現, 但詞義和詞性比較單一. 對多義詞,可以選擇其最常用的詞性.

4)       特殊規則

有些專業領域會有一些特殊的習慣用法, 也可以通過它制定一些規則. 通過正規表達式标注器實作.

5)       語義, 形态…

更深層次的語義分析

6.      參考

a)        Categorizing and Tagging Words

http://www.nltk.org/book_1ed/ch05.html

b)       結巴詞性标注

http://www.mamicode.com/info-detail-562618.html