- 自然語言工具包教程
- 自然語言工具包 - 首頁
- 自然語言工具包 - 簡介
- 自然語言工具包 - 入門
- 自然語言工具包 - 分詞
- 訓練分詞器 & 過濾停用詞
- 在 WordNet 中查詢單詞
- 詞幹提取 & 詞形還原
- 自然語言工具包 - 詞語替換
- 同義詞 & 反義詞替換
- 語料庫讀取器和自定義語料庫
- 詞性標註 (POS) 基礎
- 自然語言工具包 - 一元標註器
- 自然語言工具包 - 組合標註器
- 自然語言工具包 - 更多 NLTK 標註器
- 自然語言工具包 - 語法分析
- 組塊 & 資訊提取
- 自然語言工具包 - 轉換組塊
- 自然語言工具包 - 轉換樹
- 自然語言工具包 - 文字分類
- 自然語言工具包資源
- 自然語言工具包 - 快速指南
- 自然語言工具包 - 有用資源
- 自然語言工具包 - 討論
自然語言工具包 - 組合標註器
組合標註器
組合標註器或將標註器彼此連結是 NLTK 的重要功能之一。組合標註器背後的主要概念是,如果一個標註器不知道如何標註一個單詞,它將被傳遞給連結的標註器。為了實現這一目的,SequentialBackoffTagger 為我們提供了回退標註功能。
回退標註
如前所述,回退標註是SequentialBackoffTagger 的重要功能之一,它允許我們以以下方式組合標註器:如果一個標註器不知道如何標註一個單詞,則該單詞將傳遞給下一個標註器,依此類推,直到沒有剩餘的回退標註器可供檢查。
它是如何工作的?
實際上,SequentialBackoffTagger 的每個子類都可以接受一個“backoff”關鍵字引數。此關鍵字引數的值是SequentialBackoffTagger 的另一個例項。現在,每當初始化此SequentialBackoffTagger 類時,都會建立一個回退標註器內部列表(自身作為第一個元素)。此外,如果給定了一個回退標註器,則此回退標註器的內部列表將被追加。
在下面的示例中,我們採用DefaulTagger 作為上述 Python 程式碼中訓練UnigramTagger 的回退標註器。
示例
在此示例中,我們使用DefaulTagger 作為回退標註器。每當UnigramTagger 無法標註一個單詞時,回退標註器(在本例中為DefaulTagger)將用“NN”對其進行標註。
from nltk.tag import UnigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Uni_tagger = UnigramTagger(train_sentences, backoff = back_tagger)
test_sentences = treebank.tagged_sents()[1500:]
Uni_tagger.evaluate(test_sentences)
輸出
0.9061975746536931
從以上輸出可以看出,透過添加回退標註器,準確率提高了約 2%。
使用 pickle 儲存標註器
正如我們所看到的,訓練一個標註器非常麻煩,而且需要時間。為了節省時間,我們可以將訓練好的標註器進行 pickle 處理,以便以後使用。在下面的示例中,我們將對我們已經訓練好的名為“Uni_tagger”的標註器進行此操作。
示例
import pickle
f = open('Uni_tagger.pickle','wb')
pickle.dump(Uni_tagger, f)
f.close()
f = open('Uni_tagger.pickle','rb')
Uni_tagger = pickle.load(f)
NgramTagger 類
從前面單元中討論的層次結構圖中,UnigramTagger 繼承自NgarmTagger 類,但NgarmTagger 類還有另外兩個子類:
BigramTagger 子類
實際上,n 元組是 n 個專案的子序列,因此,顧名思義,BigramTagger 子類會檢視兩個專案。第一個專案是前一個已標註的單詞,第二個專案是當前已標註的單詞。
TrigramTagger 子類
與BigramTagger 同理,TrigramTagger 子類會檢視三個專案,即前兩個已標註的單詞和一個當前已標註的單詞。
實際上,如果我們像使用 UnigramTagger 子類一樣單獨應用BigramTagger 和TrigramTagger 子類,它們的效能都非常差。讓我們在下面的示例中看看。
使用 BigramTagger 子類
from nltk.tag import BigramTagger from nltk.corpus import treebank train_sentences = treebank.tagged_sents()[:2500] Bi_tagger = BigramTagger(train_sentences) test_sentences = treebank.tagged_sents()[1500:] Bi_tagger.evaluate(test_sentences)
輸出
0.44669191071913594
使用 TrigramTagger 子類
from nltk.tag import TrigramTagger from nltk.corpus import treebank train_sentences = treebank.tagged_sents()[:2500] Tri_tagger = TrigramTagger(train_sentences) test_sentences = treebank.tagged_sents()[1500:] Tri_tagger.evaluate(test_sentences)
輸出
0.41949863394526193
您可以將之前使用的 UnigramTagger 的效能(準確率約為 89%)與 BigramTagger(準確率約為 44%)和 TrigramTagger(準確率約為 41%)進行比較。原因是 Bigram 和 Trigram 標註器無法從句子中的第一個單詞(或單詞)學習上下文。另一方面,UnigramTagger 類不關心之前的上下文,並猜測每個單詞最常見的標籤,因此能夠獲得較高的基準準確率。
組合 n 元標註器
從以上示例可以看出,當我們將 Bigram 和 Trigram 標註器與回退標註相結合時,它們可以做出貢獻。在下面的示例中,我們將 Unigram、Bigram 和 Trigram 標註器與回退標註相結合。該概念與之前將 UnigramTagger 與回退標註器組合的程式碼相同。唯一的區別是我們使用 tagger_util.py 中提供的名為 backoff_tagger() 的函式進行回退操作,如下所示。
def backoff_tagger(train_sentences, tagger_classes, backoff=None):
for cls in tagger_classes:
backoff = cls(train_sentences, backoff=backoff)
return backoff
示例
from tagger_util import backoff_tagger
from nltk.tag import UnigramTagger
from nltk.tag import BigramTagger
from nltk.tag import TrigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Combine_tagger = backoff_tagger(train_sentences,
[UnigramTagger, BigramTagger, TrigramTagger], backoff = back_tagger)
test_sentences = treebank.tagged_sents()[1500:]
Combine_tagger.evaluate(test_sentences)
輸出
0.9234530029238365
從以上輸出可以看出,準確率提高了約 3%。