在 NLTK 中评估词性标注器

Evaluating POS tagger in NLTK

我想使用文本文件作为输入来评估 NLTK 中的不同词性标签。

例如,我将使用 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 标签。

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 中不同的词性标注器来识别最适合给定文件的词性标注器。

如有任何帮助,我们将不胜感激。

您需要自己或从其他来源阅读手动标记的数据。然后按照您评估 unigram 标注器的方式进行操作。您不需要标记手动标记的数据。假设你的新标记数据保存在一个名为yash_new_test的变量中,那么你需要做的就是执行这个命令:

 `print(unigram_tagger.evaluate(yash_new_test))`

希望对您有所帮助!

这道题本质上是关于模型评价指标的题。在这种情况下,我们的模型是一个词性标注器,特别是 UnigramTagger

量化

您想知道您的标注器在做什么“how well”。这是一个 qualitative 问题,因此我们有一些通用的 quantitative 指标来帮助定义“how well”的含义。基本上,我们有标准指标来为我们提供这些信息。它们通常是 accuracyprecisionrecallf1-score

正在评估

首先,我们需要一些标有POS tags的数据,然后我们就可以测试了。这通常被称为 train/test 拆分,因为我们使用一些数据来训练词性标注器,一些数据用于测试或 evaluating 它的性能。

由于词性标注传统上是一个 supervised learning 问题,我们需要一些带有词性标签的句子来训练和测试。

在实践中,人们会标记一堆句子,然后将它们拆分成 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”的一个 OK 指标,但还有其他指标可以为我们提供更多详细信息,例如 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?

简单地说,就是其他答案中提到的,除非你有自己的词性标记数据关于我们要测试的句子,否则我们永远无法确定!