nltk pos 标注器的内部实现
Internal implementation of nltk pos tagger
我是 NLP 的新手,正在尝试使用 nltk pos tagger,但对用法有疑问,
它通常接受一个词或一个完整的句子,并给出输入的pos标签,为什么它是双向工作的?
我有这个疑问是因为,我尝试删除停用词并使用 spacy pos 标记技术,我的同事说我不应该那样做,因为结果会随着它检查单词的位置而改变,
nltk pos tagger 也一样吗?如果是那么为什么它接受单个单词,因为考虑了定位?
此处为 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
一个单词的句子仍然是一个句子,所以从软件工程的角度来看,无论句子的长度如何,我都希望标注器模块的工作方式相同。从语言学的角度来看,情况并非如此。
positioning
这个词似乎让您感到困惑。很多词性标注器都是基于序列模型的,比如HMMs or CRFs*
。这些使用上下文特征,例如句子中的 previous/next 个词是什么。我想这就是你同事的意思。如果你只把前一个词当作上下文,那么句子多长都无所谓。任何句子中的第一个词都没有前面的词,因此标注器必须学会处理它。然而,添加上下文可以改变标注器的决定——让我们看一个使用 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 使用神经模型——关于上下文的争论仍然存在。
nltk.pos_tag()
函数采用 标记列表 作为输入。此列表可以包含任意数量的标记,当然包括 1。API documentation.
中有更多信息
因此在您引用的第一个示例中,nltk.pos_tag([w])
、w
应该是一个单词字符串,并且 [w]
将其放入列表中,根据函数的要求。
在第二种情况下,nltk.pos_tag(sent)
,列表理解中的sent
变量是一个已经被标记化为标记列表的句子(参见您引用的代码中的第41行- sentences = tokenize_sentences(document)
),这也是pos_tag()
.
要求的格式
我不确定为什么你的同事建议不要使用 spaCy。这取决于你想做什么。与 NLTK 相反,spaCy 在每个标记上存储了一组丰富的特征,包括标记在文档中的索引(位置)和原始文本中的字符偏移量。据我所知,NLTK 默认情况下不存储标记索引和字符偏移量,因此您必须自己尝试检索它(可能类似于 )。
我是 NLP 的新手,正在尝试使用 nltk pos tagger,但对用法有疑问,
它通常接受一个词或一个完整的句子,并给出输入的pos标签,为什么它是双向工作的?
我有这个疑问是因为,我尝试删除停用词并使用 spacy pos 标记技术,我的同事说我不应该那样做,因为结果会随着它检查单词的位置而改变,
nltk pos tagger 也一样吗?如果是那么为什么它接受单个单词,因为考虑了定位?
此处为 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
一个单词的句子仍然是一个句子,所以从软件工程的角度来看,无论句子的长度如何,我都希望标注器模块的工作方式相同。从语言学的角度来看,情况并非如此。
positioning
这个词似乎让您感到困惑。很多词性标注器都是基于序列模型的,比如HMMs or CRFs*
。这些使用上下文特征,例如句子中的 previous/next 个词是什么。我想这就是你同事的意思。如果你只把前一个词当作上下文,那么句子多长都无所谓。任何句子中的第一个词都没有前面的词,因此标注器必须学会处理它。然而,添加上下文可以改变标注器的决定——让我们看一个使用 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 使用神经模型——关于上下文的争论仍然存在。
nltk.pos_tag()
函数采用 标记列表 作为输入。此列表可以包含任意数量的标记,当然包括 1。API documentation.
因此在您引用的第一个示例中,nltk.pos_tag([w])
、w
应该是一个单词字符串,并且 [w]
将其放入列表中,根据函数的要求。
在第二种情况下,nltk.pos_tag(sent)
,列表理解中的sent
变量是一个已经被标记化为标记列表的句子(参见您引用的代码中的第41行- sentences = tokenize_sentences(document)
),这也是pos_tag()
.
我不确定为什么你的同事建议不要使用 spaCy。这取决于你想做什么。与 NLTK 相反,spaCy 在每个标记上存储了一组丰富的特征,包括标记在文档中的索引(位置)和原始文本中的字符偏移量。据我所知,NLTK 默认情况下不存储标记索引和字符偏移量,因此您必须自己尝试检索它(可能类似于