2017-10-12 95 views
0

我想使用文本文件作爲輸入來評估NLTK中的不同POS標記。評估NLTK中的POS標記器

例如,我將採用Unigram標記器。我發現如何使用棕色語料庫評估Unigram標籤。

from nltk.corpus import brown 
import nltk 

brown_tagged_sents = brown.tagged_sents(categories='news') 
brown_sents = brown.sents(categories='news') 
# We train a UnigramTagger by specifying tagged sentence data as a parameter 
# when we initialize the tagger. 
unigram_tagger = nltk.UnigramTagger(brown_tagged_sents) 
print(unigram_tagger.tag(brown_sents[2007])) 
print(unigram_tagger.evaluate(brown_tagged_sents)) 

它產生如下的輸出。

[('Various', 'JJ'), ('of', 'IN'), ('the', 'AT'), ('apartments', 'NNS'), ('are', 'BER'), ('of', 'IN'), ('the', 'AT'), ('terrace', 'NN'), ('type', 'NN'), (',', ','), ('being', 'BEG'), ('on', 'IN'), ('the', 'AT'), ('ground', 'NN'), ('floor', 'NN'), ('so', 'QL'), ('that', 'CS'), ('entrance', 'NN'), ('is', 'BEZ'), ('direct', 'JJ'), ('.', '.')] 
0.9349006503968017 

以類似的方式,我想讀從一個文本文件中的文本和評估不同的POS標註器的精確度。

我想出瞭如何讀取文本文件以及如何爲標記應用pos標記。

import nltk 
from nltk.corpus import brown 
from nltk.corpus import state_union 

brown_tagged_sents = brown.tagged_sents(categories='news') 

sample_text = state_union.raw(
    r"C:\pythonprojects\tagger_nlt\new-testing.txt") 
tokens = nltk.word_tokenize(sample_text) 

default_tagger = nltk.UnigramTagger(brown_tagged_sents) 

default_tagger.tag(tokens) 

print(default_tagger.tag(tokens)) 
[('Honestly', None), ('last', 'AP'), ('seven', 'CD'), ('lectures', None), ('are', 'BER'), ('good', 'JJ'), ('.', '.'), ('Lectures', None), ('are', 'BER'), ('understandable', 'JJ') 

我想要的東西已經是一個得分一樣default_tagger.evaluate(),這樣我就可以在NLTK使用相同的輸入文件,以確定最適合POS惡搞給定文件比較不同的POS標註器。

任何幫助將不勝感激。

+1

你需要你的測試句子的ground-truth標籤。您可以使用一組現有的標記句子(如第一個例子中使用的布朗語料庫),或者找一些熟悉英語的語言學家,他們願意手動標記您的句子。 – lenz

+0

@Yash你正在做的事情與你現在正在做的不同。你傳遞命令'default_tagger.tag(tokens)',它標記你的原始令牌。您應該提供手動標記的數據以便能夠評估標記器。 – Mohammed

回答

2

這個問題本質上是一個關於模型評估指標的問題。在這種情況下,我們的模型是一個POS惡搞,特別是UnigramTagger

量化

你想知道「how well」的惡搞在做什麼。這是一個qualitative的問題,所以我們有一些通用的quantitative指標來幫助定義「how well」的含義。基本上,我們有標準的指標給我們這些信息。它們通常是accuracy,precision,recallf1-score

評估

首先,我們需要一個被標記了POS tags一些數據,那麼我們就可以進行測試。這通常被稱爲train/test拆分,因爲我們用於培訓POS tagger的一些數據,有些用於測試或者是性能。

由於POS標籤傳統上是supervised learning的問題,我們需要一些帶POS標籤的句子來訓練和測試。

實際上,人們會標記一堆句子,然後將它們分成testtrain集合。 NLTK book解釋了這一點,讓我們試試看。

from nltk import UnigramTagger 
from nltk.corpus import brown 
# we'll use the brown corpus with universal tagset for readability 
tagged_sentences = brown.tagged_sents(categories="news", tagset="universal") 

# let's keep 20% of the data for testing, and 80 for training 
i = int(len(tagged_sentences)*0.2) 
train_sentences = tagged_sentences[i:] 
test_sentences = tagged_sentences[:i] 

# let's train the tagger with out train sentences 
unigram_tagger = UnigramTagger(train_sentences) 
# now let's evaluate with out test sentences 
# default evaluation metric for nltk taggers is accuracy 
accuracy = unigram_tagger.evaluate(test_sentences) 

print("Accuracy:", accuracy) 
Accuracy: 0.8630364649525858 

現在,accuracy對於瞭解「how many you got right」一個好指標,但也有其他指標,讓我們更詳細,如precisionrecallf1-score。我們可以使用sklearnclassification_report給我們一個很好的結果總覽。

tagged_test_sentences = unigram_tagger.tag_sents([[token for token,tag in sent] for sent in test_sentences]) 
gold = [str(tag) for sentence in test_sentences for token,tag in sentence] 
pred = [str(tag) for sentence in tagged_test_sentences for token,tag in sentence] 
from sklearn import metrics 
print(metrics.classification_report(gold, pred)) 

      precision recall f1-score support 

      .  1.00  1.00  1.00  2107 
     ADJ  0.89  0.79  0.84  1341 
     ADP  0.97  0.92  0.94  2621 
     ADV  0.93  0.79  0.86  573 
     CONJ  1.00  1.00  1.00  453 
     DET  1.00  0.99  1.00  2456 
     NOUN  0.96  0.76  0.85  6265 
     NUM  0.99  0.85  0.92  379 
     None  0.00  0.00  0.00   0 
     PRON  1.00  0.96  0.98  502 
     PRT  0.69  0.96  0.80  481 
     VERB  0.96  0.83  0.89  3274 
      X  0.10  0.17  0.12   6 

avg/total  0.96  0.86  0.91  20458 

現在我們有一些想法和價值觀,我們可以看一下,以量化我們的標註器,但我相信你的想法,「That's all well and good, but how well does it perform on random sentences?

簡單地說,它就是在其他的答案中提到,除非你在我們想測試的句子上有你自己的POS標記數據,否則我們絕對不會知道!

0

您需要自己或從其他來源手動讀取標記的數據。然後按照您評估unigram tagger的方式進行操作。您無需標記手動標記的數據。假設你的新標籤數據被保存在一個名爲yash_new_test變量,那麼所有你需要做的是執行此命令:

`print(unigram_tagger.evaluate(yash_new_test))` 

我希望這有助於!

+0

我跑你的建議,它給了我這個錯誤。 tagged_sents = self.tag_sents(untag(已發送)以黃金形式發送)ValueError:解壓縮的值太多(預計爲2) – Yash

+0

您試圖以錯誤的方式解壓縮字典。這完全與我的方法無關。 – Mohammed