我尝试了所有用于词干分析的nltk方法,但它给了我一些奇怪的结果。
实施例
当它不应该这样做时,通常会削减单词的结尾:
或者不是很好:
你知道python中的其他词干库,还是一本好词典?
谢谢
答案 0 :(得分:97)
您获得的结果(通常)是预期的英语词干分析器。你说你试过"所有的nltk方法"但是当我尝试你的例子时,情况似乎并非如此。
以下是使用PorterStemmer
的一些示例import nltk
ps = nltk.stemmer.PorterStemmer()
ps.stem('grows')
'grow'
ps.stem('leaves')
'leav'
ps.stem('fairly')
'fairli'
结果是'成长,' leav'和' fairli'即使它们是你想要的,也是原始单词的词干版本。
如果我们切换到Snowball词干分析器,我们必须提供语言作为参数。
import nltk
sno = nltk.stem.SnowballStemmer('english')
sno.stem('grows')
'grow'
sno.stem('leaves')
'leav'
sno.stem('fairly')
'fair'
结果与以前一样“增长”。并且'离开'但是“公平地”#39;被认为是公平的
所以在这两种情况下(并且nltk中有两个以上的词干分析器),你说的词实际上并没有被阻止。 LancasterStemmer将返回' easy'当提供'轻松'或者' easy'作为输入。
也许你真的想要一个lemmatizer?这将返回'文章'和&#p; poodle'不变。
import nltk
lemma = nltk..wordnet.WordNetLemmatizer()
lemma.lemmatize('article')
'article'
lemma..lemmatize('leaves')
'leaf'
答案 1 :(得分:9)
这里讨论的所有这些词干分析器都是算法词干分析器,因此它们总能产生意想不到的结果,例如
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.Here是以下link中的python实现。示例代码在这里
>>> 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']
答案 2 :(得分:1)
加粗仅是删除后缀(据我所试,通常只有后缀,nltk词干无法删除前缀,而忽略后缀)。 因此,我们可以清楚地将词干称为愚蠢/不太聪明的程序。它不会检查单词在词干之前或之后是否具有含义。 例如。如果您尝试词干“ xqaing”,尽管不是一个单词,它将删除“ -ing”并给您“ xqa”。
因此,为了使用更智能的系统,可以使用lemmatizers。 留语者使用格式完善的词条(词)和词网和词典。 因此,它总是返回并使用正确的词。但是,它很慢,因为它会遍历所有单词以找到相关的单词。
答案 3 :(得分:0)
词干的攻击性各不相同。波特(Porter)是英语中最激进的词干之一。我发现它通常带来的伤害大于帮助。 在较轻的一面,您可以改用lemmatizer, 或更轻的算法词干。 lemmatizers的局限性在于它们不能处理不知名的单词,这不是一个严重的问题。
我个人比较喜欢Krovetz词干分析器,它是一种混合解决方案,它结合了字典词条分解器和轻量词干分析器来解决词汇量不足的问题。 Elasticsearch中的Krovetz也是kstem
或light_stemmer
选项。在pypi https://pypi.org/project/KrovetzStemmer/上有一个python实现,尽管那不是我用过的。
另一个选择是spaCy中的lemmatizer。使用spaCy evry令牌进行事后处理具有lemma_
属性。 (请注意,下划线lemma
包含lemma_
的数字标识符)-https://spacy.io/api/token
有些论文比较了各种词干提取算法:
答案 4 :(得分:-1)
在我的聊天机器人项目中,我使用了PorterStemmer,但是LancasterStemmer也达到了目的。最终目的是将单词词根扎根,以便我们可以搜索并与搜索词输入进行比较。
例如: 从nltk.stem导入PorterStemmer ps = PorterStemmer()
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
希望这会有所帮助。
答案 5 :(得分:-5)
您是否尝试过阻止1.0 here?