我尝试了所有的nltk词干提取方法,但对于某些单词它给出了奇怪的结果。
例如:
它经常在不应该的情况下切掉单词的结尾:
- poodle => poodl
- article => articl
或者不能很好地进行词干提取:
- easily和easy没有被提取为相同的单词
- leaves、grows、fairly没有被提取
你知道Python中其他的词干提取库或好的词典吗?
谢谢
我尝试了所有的nltk词干提取方法,但对于某些单词它给出了奇怪的结果。
例如:
它经常在不应该的情况下切掉单词的结尾:
或者不能很好地进行词干提取:
你知道Python中其他的词干提取库或好的词典吗?
谢谢
import nltk
ps = nltk.stemmer.PorterStemmer()
ps.stem('grows')
'grow'
ps.stem('leaves')
'leav'
ps.stem('fairly')
'fairli'
结果是'grow','leav'和'fairli',即使它们是您想要的,也是原始单词的词干版本。
如果我们切换到Snowball词干分析器,我们必须提供语言作为参数。
import nltk
sno = nltk.stem.SnowballStemmer('english')
sno.stem('grows')
'grow'
sno.stem('leaves')
'leav'
sno.stem('fairly')
'fair'
“grows”和“leaves”的结果与之前相同,但“fairly”被词干提取为“fair”。
因此,在这两种情况下(nltk中有多于两个的词干提取器可供选择),你所说未经过词干提取的单词实际上已经过了。当使用LancasterStemmer输入“easily”或“easy”时,它将返回“easy”。
也许你真正想要一个词形还原器?那样会不改变“article”和“poodle”的形式。
import nltk
lemma = nltk.wordnet.WordNetLemmatizer()
lemma.lemmatize('article')
'article'
lemma.lemmatize('leaves')
'leaf'
这里讨论的所有词干提取器都是算法词干提取器,因此它们始终可以产生意外的结果,例如:
In [3]: from nltk.stem.porter import *
In [4]: stemmer = PorterStemmer()
In [5]: stemmer.stem('identified')
Out[5]: u'identifi'
In [6]: stemmer.stem('nonsensical')
Out[6]: u'nonsens'
为了正确获取词根,需要使用基于字典的分词器,例如Hunspell Stemmer。以下是其Python实现的链接:link。示例代码在此处。>>> import hunspell
>>> hobj = hunspell.HunSpell('/usr/share/myspell/en_US.dic', '/usr/share/myspell/en_US.aff')
>>> hobj.spell('spookie')
False
>>> hobj.suggest('spookie')
['spookier', 'spookiness', 'spooky', 'spook', 'spoonbill']
>>> hobj.spell('spooky')
True
>>> hobj.analyze('linked')
[' st:link fl:D']
>>> hobj.stem('linked')
['link']
词干处理器的侵略性因人而异。对于英语,Porter是最具攻击性的词干处理器之一。我发现它通常会带来更多的负面影响而非帮助。
在轻松的一面,您可以使用建议过的词形还原器或轻量级算法词干处理器。
词形还原器的限制在于无法处理未知单词。
个人喜欢 Krovetz 词干处理器,它是一个混合解决方案,结合了字典词形还原器和轻量级词干处理器以处理词汇表外的单词。Krovetz 还在 Elasticsearch 中提供 kstem 或 light_stemmer 选项。pypi 上有一个 Python 实现,链接为 https://pypi.org/project/KrovetzStemmer/,不过那不是我用过的。
另一个选择是 spaCy 中的词形还原器。使用 spaCy 处理后,每个标记都有一个 lemma_ 属性。请注意下划线 lemma 包含一个 lemma_ 的数字标识符 - 链接为 https://spacy.io/api/token
以下是一些比较各种词干处理算法的论文:
词干提取是指去除后缀(通常仅限于后缀,据我所试,nltk的词干提取器无法去除前缀,更不用说中缀了)。 因此,我们可以明确地将词干提取称为一个愚蠢/不太智能的程序。它在进行词干提取之前不会检查单词是否具有含义。 例如,如果您尝试对“xqaing”进行词干提取,虽然这不是一个单词,但它将去除“-ing”并给出“xqa”。
因此,为了使用更智能的系统,可以使用词形还原器。 词形还原器使用以WordNet和字典形式呈现的良好形式的词元(单词)。 因此,它始终返回并接受正确的单词。但是,由于需要遍历所有单词以找到相关单词,因此速度较慢。
这个问题已经有非常好的答案了,但我想补充一些我认为可能有用的信息。在我的研究中,我发现了一个链接,它提供了关于词干提取和词形还原的详细信息https://nlp.stanford.edu/IR-book/html/htmledition/stemming-and-lemmatization-1.html。
以下是该页面的一些见解:
词干提取和词形还原
由于语法原因,文档将使用单词的不同形式,例如 organize、organizes 和 organizing。此外,还有一些具有相似含义的派生词族,例如 democracy、democratic 和 democratization。在许多情况下,搜索其中一个单词并返回包含该集合中另一个单词的文档似乎很有用。
am、are、is -> be car、cars、car's、cars' -> car 这种文本映射的结果将会是: the boy's cars are different colors -> the boy car be differ color 此外,nltk包已经更新,您可以使用“from nltk.stem import WordNetLemmatizer”导入WordNetLemmatizer。词形还原器需要在使用之前下载一个软件包,下面的命令适用于3.6.1版本。词干提取和词形还原的目标是将单词的屈折形式和有时具有派生关系的形式减少到一个共同的基本形式。例如:
import nltk
nltk.download("wordnet")
def SrchpattrnStmmed(self):
KeyWords =[]
SrchpattrnTkn = word_tokenize(self.input)
for token in SrchpattrnTkn:
if token not in stop_words:
KeyWords.append(ps.stem(token))
continue
#print(KeyWords)
return KeyWords
希望这能有所帮助。
Python实现的Porter、Porter2、Paice-Husk和Lovins英文词干提取算法可在词干提取包中获取。