Nltk Pos Tagger的内部实现

时间:2018-08-08 12:38:53

标签: nlp nltk spacy

我是NLP的新手,并尝试使用nltk pos标记器,并对用法有疑问,

它通常接受一个单词或一个完整的句子,并给出输入的pos标签,为什么它同时以两种方式起作用?

我对此表示怀疑,因为我尝试删除停用词并使用了spacy pos标签技术,而我的同事说我不应该那样做,因为结果也会改变,因为它还会检查单词的位置,

nltk pos标记器也一样吗?如果是,那为什么考虑到定位后为什么接受单个单词呢?

在以下两个nltk用例中找到了示例用法:https://github.com/acrosson/nlp/blob/master/subject_extraction/subject_extraction.py#L61

https://github.com/acrosson/nlp/blob/master/subject_extraction/subject_extraction.py#L44

2 个答案:

答案 0 :(得分:1)

一个单词的句子仍然是一个句子,因此从软件工程的角度来看,无论句子的长度如何,我都希望标记器模块能够相同地工作。从语言的角度来看,并非如此。

positioning一词似乎使您感到困惑。许多PoS标记器基于序列模型,例如HMMsCRFs *。这些使用上下文功能,例如句子中的前一个/下一个词是什么?我认为这就是您的同事的意思。如果仅将前一个单词作为上下文,那么句子有多长都无所谓。任何句子中的第一个单词都没有前一个单词,因此标记者必须学会处理该单词。但是,添加上下文可以改变标记器的决定-让我们看一个使用nltk

的示例
In [4]: import nltk

In [5]: nltk.pos_tag(['fly'])
Out[5]: [('fly', 'NN')]

In [6]: nltk.pos_tag(['I', 'fly'])
Out[6]: [('I', 'PRP'), ('fly', 'VBP')]

In [7]: nltk.pos_tag(['Large', 'fly'])
Out[7]: [('Large', 'JJ'), ('fly', 'NN')]

如您所见,更改第一个单词会影响标记者第二个单词的输出。因此,在将文本输入PoS标记器之前,您应该不要删除停用词。

*尽管并非总是如此。 NLTK 3.3的PoS标记器是平均感知器,spacy 2.0使用神经模型-尽管关于上下文的争论仍然成立。

答案 1 :(得分:0)

nltk.pos_tag()函数将令牌列表作为输入。该列表可以包含任意数量的令牌,当然包括1。API documentation中有更多信息。

因此,在第一个示例中,您引用nltk.pos_tag([w])w应该是单个单词字符串,而[w]根据功能需要将其放入列表中。

在第二种情况下,nltk.pos_tag(sent),列表理解中的sent变量是已经被标记为标记列表的句子(请参见您引用的代码的第41行-{{ 1}}),也是sentences = tokenize_sentences(document)要求的格式。

我不确定您的同事为什么建议不要使用spaCy。这取决于您想做什么。与NLTK相反,spaCy在每个令牌上存储了丰富的功能集,包括文档中令牌的索引(位置)和原始文本中的字符偏移量。据我所知,NLTK在默认情况下不存储令牌索引和字符偏移量,因此您必须自己尝试检索它(也许像this之类)。