简单来说,两者都是对词的归一化,但 Stemming(中文一般译为词干提取,以下简称 stem)更为简单、快速一些,通常会使用一种启发式方法去掉一个词的结尾。 Lemmatization(中文一般译为词形还原,以下简称 lemma)更为「智能」一些,上下文相关,有一个 vocab,不在其中的词不会被处理:
Returns the input word unchanged if it cannot be found in WordNet. —— nltk.stem.wordnet — NLTK 3.5 documentation
例如
- 对于
better
,stem 的结果仍然是better
,但是 lemma 结果是good
。 - 对于
meeting
,在没有上下文的情况下,既可以指名词会议,也可以是动词meet
的 ing 形式。在in our last meeting
和We are meeting again tomorrow
这两句话中,lemma 就更能选择一个正确的结果。
nltk 中,这两者都在 nltk.stem
中,常见的有这么几种:PorterStemmer
、SnowballStemmer
和 WordNetLemmatizer
。其中 WordNetLemmatizer
是通过 pos 来获取上下文信息的,pos 可以使用 nltk.pos_tag(nltk.word_tokenize('YOUR SENTENCE'))
来获得。
下面以几个例子了解下:
def test_stemmer(word: str, pos='n'):
porter = nltk.stem.PorterStemmer()
snowball = nltk.stem.SnowballStemmer('english')
wordnet = nltk.stem.WordNetLemmatizer()
print(f"Origin: {word}")
print('----------------------')
print(f"PorterStemmer: {porter.stem(word)}")
print(f"SnowballStemmer: {snowball.stem(word)}")
print(f"WordNetLemmatizer: {wordnet.lemmatize(word, pos=pos)}") # pos 的默认值是 n,即名词
test_stemmer('apples', pos='n')
# Origin: apples
# ----------------------
# PorterStemmer: appl
# SnowballStemmer: appl
# WordNetLemmatizer: apple
test_stemmer('better', pos='a')
# Origin: better
# ----------------------
# PorterStemmer: better
# SnowballStemmer: better
# WordNetLemmatizer: good
test_stemmer('meeting', pos='n')
# Origin: meeting
# ----------------------
# PorterStemmer: meet
# SnowballStemmer: meet
# WordNetLemmatizer: meeting
test_stemmer('meeting', pos='v')
# Origin: meeting
# ----------------------
# PorterStemmer: meet
# SnowballStemmer: meet
# WordNetLemmatizer: meet
Reference
- python - What is the difference between lemmatization vs stemming? - Stack Overflow
- nlp - Stemmers vs Lemmatizers - Stack Overflow