【问题标题】:What is the best stemming method in Python?Python中最好的词干提取方法是什么?
【发布时间】:2014-08-30 02:35:48
【问题描述】:

我尝试了所有用于词干提取的 nltk 方法,但它给了我一些奇怪的结果。

例子

它经常在不应该这样做的时候切断词尾:

  • 贵宾犬 => 贵宾犬
  • 文章文章

或者干得不太好:

  • easy 和 easy 不是同一个词
  • 叶子,生长,几乎没有茎

你知道python中的其他词干库,还是一本好的词典?

谢谢

【问题讨论】:

  • 这些结果并不奇怪,因为stemming 是将屈折(或有时派生)的词减少到其词干、基本或词根形式的过程——通常是书面词形式。更多详情,请查看here
  • btw NLTK 是构建 Python 程序以处理人类语言数据的最佳平台。
  • 您可能只要求提供英语词干分析器,对吧?

标签: python nltk stemming


【解决方案1】:

Porter、Porter2、Paice-Husk 和 Lovins 的英语词干算法的 Python 实现可在 stemming package 中获得

【讨论】:

  • 似乎他们使用不同的算法。我试试看,谢谢!
  • 请注意,词干提取是一个纯 Python 实现,不会像 PyStemmer 那样快,后者是一个 c 库的包装器,在 PyPi 中也可用。
【解决方案2】:

您获得的结果(通常)是英语词干分析器所期望的。您说您尝试了“所有 nltk 方法”,但是当我尝试您的示例时,情况似乎并非如此。

以下是一些使用 PorterStemmer 的示例

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 中有两个以上的词干分析器可用),您所说的词实际上不是词干提取器。当提供“easy”或“easy”作为输入时,LancasterStemmer 将返回“easy”。

也许你真的想要一个词形还原器?这将返回 'article' 和 'poodle' 不变。

import nltk
lemma = nltk.wordnet.WordNetLemmatizer()
lemma.lemmatize('article')
'article'
lemma.lemmatize('leaves')
'leaf'

【讨论】:

  • 这应该是选择的答案。
  • 黑白词干分析器和词干分析器的区别:stackoverflow.com/questions/1787110/…
  • 补充一点:词形还原器在与词性标注器配对时产生更好的结果;它尝试匹配的默认 POS 是名词(尝试使用单词“ate”的词形还原器)。
  • lemmatizer.lemmatize('randomly') # 输出 'randomly', stemmer.stem('randomly') # 输出'random'。你赢不了。 (nltk lemmatizer,来自 stemmer 包)
  • 第一个例子,为什么叫stemmer?它对我不起作用,但 stem 起作用了。
【解决方案3】:

这里讨论的所有这些词干分析器都是算法词干分析器,因此它们总是会产生意想不到的结果,例如

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。下面是 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']

【讨论】:

【解决方案4】:

在我的聊天机器人项目中,我使用了 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】:

    词干是关于删除后缀的(通常只有后缀,据我所知,没有一个 nltk 词干分析器可以删除前缀,忘记中缀)。 因此,我们可以清楚地将词干称为愚蠢/不那么智能的程序。它不会检查一个词在词干之前或之后是否有意义。 例如。如果你试图阻止“xqaing”,虽然不是一个词,它会删除“-ing”并给你“xqa”。

    因此,为了使用更智能的系统,可以使用词形还原器。 Lemmatizers 以 wordnet 和字典的形式使用格式良好的词条(单词)。 所以它总是返回并接受一个正确的词。但是,它很慢,因为它会遍历所有单词以找到相关的单词。

    【讨论】:

      【解决方案6】:

      词干的攻击性各不相同。 Porter 是英语中最具攻击性的词干分析器之一。我发现它通常带来的伤害大于帮助。 在较轻的方面,您可以按照已经建议的方式使用 lemmatizer, 或更轻的算法词干分析器。 lemmatizer 的局限性在于它们不能处理未知单词。

      就我个人而言,我喜欢 Krovetz 词干分析器,它是一种混合解决方案,结合了字典词形还原器和轻量级词干分析器来处理词汇表外的单词。 Krovetz 还在 Elasticsearch 中提供了 kstemlight_stemmer 选项。在 pypi https://pypi.org/project/KrovetzStemmer/ 上有一个 python 实现,虽然那不是我用过的。

      另一个选项是spaCy 中的词形还原器。使用spaCy 处理后,每个令牌都有一个lemma_ 属性。 (注意下划线lemmalemma_的数字标识符)-https://spacy.io/api/token

      这里有一些比较各种词干算法的论文:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-18
        • 1970-01-01
        • 2019-12-08
        • 2013-05-25
        • 1970-01-01
        • 2021-09-11
        • 1970-01-01
        相关资源
        最近更新 更多