SnowballStemmer处理英文单词列表失效,疑似默认用PorterStemmer问题
我正在学习NLTK中的词干提取(Stemming)技术,使用SnowballStemmer处理英文单词时遇到问题:单个单词处理正常,但处理单词列表时,结果似乎是用PorterStemmer生成的。我创建了名为singles的列表存储词干结果,但不符合预期。示例中单独处理"generously"结果正常,但处理plurals列表得到的singles结果却不对,我实际需要处理的是plurals列表,烦请帮忙排查问题。
相关代码:
from nltk.stem.snowball import SnowballStemmer plurals = ['caresses', 'flies', 'dies', 'mules', 'denied','died', 'agreed', 'owned', 'humbled', 'sized','meeting', 'stating', 'siezing', 'itemization','sensational', 'traditional', 'reference', 'colonizer','plotted'] stemmer = SnowballStemmer("english") singles = [stemmer.stem(plural) for plural in plurals] print(SnowballStemmer("english").stem("generously")) print(" ".join(singles))
你的代码逻辑完全正确,之所以会误以为列表处理用了PorterStemmer,核心原因是SnowballStemmer的英文模式(Porter2算法)是PorterStemmer的优化版,绝大多数单词的词干结果和PorterStemmer完全一致,只有少数词会体现出差异(比如你测试的generously:Snowball返回generous,而PorterStemmer返回gener)。
验证差异的测试代码
可以通过同时对比两种词干器的结果,明确差异:
from nltk.stem.snowball import SnowballStemmer from nltk.stem import PorterStemmer plurals = ['caresses', 'flies', 'dies', 'mules', 'denied','died', 'agreed', 'owned', 'humbled', 'sized','meeting', 'stating', 'siezing', 'itemization','sensational', 'traditional', 'reference', 'colonizer','plotted'] snowball = SnowballStemmer("english") porter = PorterStemmer() snowball_results = [snowball.stem(word) for word in plurals] porter_results = [porter.stem(word) for word in plurals] print("SnowballStemmer 结果:") print(" ".join(snowball_results)) print("\nPorterStemmer 结果:") print(" ".join(porter_results))
执行后会发现,两者仅在极少数词上有差异(比如reference:Snowball返回refer,Porter返回referenc),其余单词的处理结果完全相同。这意味着你当前的代码确实在使用SnowballStemmer,只是它的输出和PorterStemmer高度重合,导致了你误解。
如果需要确认当前使用的词干器类型,可以直接打印stemmer对象:
print(stemmer)
输出会明确显示SnowballStemmer(language='english'),证明你确实在使用SnowballStemmer。
内容的提问来源于stack exchange,提问作者Pedram Najafizadeh

