简单来说,两者都是对词的归一化,但 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 meetingWe are meeting again tomorrow 这两句话中,lemma 就更能选择一个正确的结果。

nltk 中,这两者都在 nltk.stem 中,常见的有这么几种:PorterStemmerSnowballStemmerWordNetLemmatizer。其中 WordNetLemmatizer 是通过 pos 来获取上下文信息的,pos 可以使用 nltk.pos_tag(nltk.word_tokenize('YOUR SENTENCE')) 来获得。

下面以几个例子了解下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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

END