为什么 NLTK 的 PoS 标记器是为单词中的每个字母标记而不是为每个单词标记?
Why is NLTK's PoS tagger tagging for each letter in a word instead of tagging for each word?
假设我有这句话: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?我该如何解决这个问题?
nltk.pos_tag
作为参数处理列表或类似列表的东西,并标记 每个元素。因此,在您的第二个示例中,它将每个字符串(即每个单词)拆分为字母,就像在第一个示例中将句子拆分为字母一样。当您传入从拆分句子得到的整个列表时,它会起作用:
>>> nltk.pos_tag(sentence.split(" "))
[('I', 'PRP'), ('am', 'VBP'), ('a', 'DT'), ('good', 'JJ'), ('boy', 'NN')]
Per documentation,你通常传入NLTK的标记化返回的内容(这是words/tokens的列表)。
在这两种情况下,您以不同的方式拆分数据。但是 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')]
假设我有这句话: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?我该如何解决这个问题?
nltk.pos_tag
作为参数处理列表或类似列表的东西,并标记 每个元素。因此,在您的第二个示例中,它将每个字符串(即每个单词)拆分为字母,就像在第一个示例中将句子拆分为字母一样。当您传入从拆分句子得到的整个列表时,它会起作用:
>>> nltk.pos_tag(sentence.split(" "))
[('I', 'PRP'), ('am', 'VBP'), ('a', 'DT'), ('good', 'JJ'), ('boy', 'NN')]
Per documentation,你通常传入NLTK的标记化返回的内容(这是words/tokens的列表)。
在这两种情况下,您以不同的方式拆分数据。但是 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')]