2017-10-12 87 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