【问题标题】:Why is NLTK's PoS tagger tagging for each letter in a word instead of tagging for each word?为什么 NLTK 的 PoS 标注器对单词中的每个字母进行标记,而不是对每个单词进行标记?
【发布时间】:2018-07-09 06:37:37
【问题描述】:

假设我有这句话:I am a boy。我想找出句子中每个单词的词性。这是我的代码:

import nltk
sentence = 'I am a good boy'
for word in sentence:
    print(word)
    print(nltk.pos_tag(word))

但这会产生以下输出:

I
[('I', 'PRP')]

[(' ', 'NN')]
a
[('a', 'DT')]
m
[('m', 'NN')]

[(' ', 'NN')]
a
[('a', 'DT')]

[(' ', 'NN')]
g
[('g', 'NN')]
o
[('o', 'NN')]
o
[('o', 'NN')]
d
[('d', 'NN')]

[(' ', 'NN')]
b
[('b', 'NN')]
o
[('o', 'NN')]
y
[('y', 'NN')]

所以,我尝试这样做:

sentence = 'I am a good boy'
for word in sentence.split(' '):
    print(word)
    print(nltk.pos_tag(word))

这会产生以下输出:

I
[('I', 'PRP')]
am
[('a', 'DT'), ('m', 'NN')]
a
[('a', 'DT')]
good
[('g', 'NN'), ('o', 'MD'), ('o', 'VB'), ('d', 'NN')]
boy
[('b', 'NN'), ('o', 'NN'), ('y', 'NN')]

为什么要为每个字母而不是每个单词找到 PoS?我该如何解决这个问题?

【问题讨论】:

    标签: python string nlp nltk part-of-speech


    【解决方案1】:

    nltk.pos_tag 作用于列表或类似列表的事物作为参数,并标记其中的 每个元素。因此,在您的第二个示例中,它将每个字符串(即每个单词)拆分为字母,就像在第一个示例中将句子拆分为字母一样。当您传入拆分句子获得的整个列表时,它会起作用:

    >>> nltk.pos_tag(sentence.split(" "))
    [('I', 'PRP'), ('am', 'VBP'), ('a', 'DT'), ('good', 'JJ'), ('boy', 'NN')]
    

    Per documentation,您通常传递 NLTK 的标记化返回的内容(即单词/标记列表)。

    【讨论】:

      【解决方案2】:

      在这两种情况下,您都以不同的方式拆分数据。但是 pos_tag 需要一个可迭代的作为输入。
      在您的第一种情况下,您正在逐个字母地拆分句子。
      例如

      sentence = "cat"
      for word in sentence:
          print(word)
      # 'c' , 'a', 't'
      

      然后你要求 pos_tagger 找到每个字母的词性。

      print(nltk.pos_tag(word))
      

      很明显,因为每次你将字母作为输入给 pos_tag(),你都会在这里得到每个字母的词性标签。


      在您的第二个示例中,您按单词拆分句子。 例如:

      sentence = 'I am a good boy'
      splitted_words = sentence.split() # you can use split() instead of split(' ') 
      for word in splitted_words: 
          print(word)
      # 'I', 'am', 'a', 'good', 'boy'
      

      现在重要的一点是要注意每个单词都是可迭代的。 'am' 是可迭代的,我们可以通过 'am' 进行迭代,得到 'a' 和 'm'。 所以很明显 pos_tagger 给出了单词中字母的结果。

      如何解决这个问题:

      pos_tag() 需要一个可迭代的参数(列表、元组等)。我建议您使用带有 NLTK 的 tokenizer(),而不是手动按空格分隔句子。 所以你的代码应该是这样的:

      sentence = "I am a good boy"
      tokenised_words = word_tokenize(sentence) # ['I', 'am', 'a', 'good', 'boy']
      print(nltk.pos_tag(tokenised_words))
      

      输出

      [('I', 'PRP'), ('am', 'VBP'), ('a', 'DT'), ('good', 'JJ'), ('boy', 'NN')]
      

      【讨论】:

      • 感谢您发布此信息! print 语句的最后一行应该是: print(nltk.pos_tag(tokenised_words)) 而不是 print(nltk.pos_tag(text))。
      猜你喜欢
      • 2015-06-06
      • 1970-01-01
      • 1970-01-01
      • 2015-05-22
      • 1970-01-01
      • 2019-03-12
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多