spaCy的词形归并器没有出错,它的表现符合预期。词形归并取决于分配给标记的词性(PoS)标签,而PoS标记模型是基于句子/文档进行训练的,而不是单个标记(单词)。例如,基于斯坦福PoS标记器的
parts-of-speech.info不允许您输入单个单词。
在您的情况下,单词“consulting”被标记为名词,您正在使用的spaCy模型认为“consulting”是这种情况下适当的词形。如果您将字符串更改为“consulting tomorrow”,则会看到spaCy将“consulting”词形还原为“consult”,因为它被标记为动词(请参见下面代码的输出)。简而言之,我建议不要尝试对单个标记执行词形还原,而是按照其设计意图,在句子/文档上使用该模型。
作为附注:确保您了解词元和词干之间的区别。如果您不确定,请阅读维基百科词元(形态学)页面上提供的
this部分。
import spacy
nlp = spacy.load('en_core_web_trf', disable=['parser', 'ner'])
doc = nlp('consulting')
print([[token.pos_, token.lemma_] for token in doc])
doc_verb = nlp('Consulting tomorrow')
print([[token.pos_, token.lemma_] for token in doc_verb])
如果你确实需要对单词进行词形还原,
this GeeksforGeeks Python 词形还原教程的第二种方法会产生“consult”的词元。我在此创建了一个简化版本以备将来参考,以防链接失效。我没有测试它在其他单个标记(单词)上的效果,因此可能并不适用于所有情况。
import nltk
from nltk.stem import WordNetLemmatizer
nltk.download('averaged_perceptron_tagger')
from nltk.corpus import wordnet
def pos_tagger(nltk_tag):
if nltk_tag.startswith('J'):
return wordnet.ADJ
elif nltk_tag.startswith('V'):
return wordnet.VERB
elif nltk_tag.startswith('N'):
return wordnet.NOUN
elif nltk_tag.startswith('R'):
return wordnet.ADV
else:
return None
lemmatizer = WordNetLemmatizer()
sentence = 'consulting'
pos_tagged = nltk.pos_tag(nltk.word_tokenize(sentence))
lemmatized_sentence = []
for word, tag in pos_tagged:
lemmatized_sentence.append(lemmatizer.lemmatize(word, pos_tagger(tag)))
print(lemmatized_sentence)