Каков наилучший метод стримера в Python?

Я пробовал все методы nltk для создания, но это дает мне странные результаты с некоторыми словами.

Примеры

Он часто прерывает слова, когда он не должен этого делать:

  • Пудель => Пудель
  • статья articl

или не является очень хорошим:

  • легко и легко не связаны одним и тем же словом
  • листья, растут, справедливо не стебли

Знаете ли вы, что в python есть другие libring, или хороший словарь?

спасибо

Ответы

Ответ 1

Python-реализации алгоритмов stemming Porter, Porter2, Paice-Husk и Lovins для английского языка доступны в пакете stemming

Ответ 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'

Результаты такие же, как и раньше, для "растет" и "уходит", но "справедливо" сводится к "честному"

Таким образом, в обоих случаях (а в nltk доступно более двух модулей), слова, которые вы говорите, на самом деле не основаны. LancasterStemmer вернет "easy", если в качестве входных данных указано "easy" или "easy".

Может быть, вы действительно хотели лемматизатор? Это вернет "статью" и "пудель" без изменений.

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

Ответ 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. Вот его реализация на основе 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

Стемминг - это удаление суффиксов (как правило, только суффиксы, поскольку, как я пытался, ни один из стеммеров nltk не может удалить префикс, забудьте об инфиксах). Таким образом, мы можем четко назвать стемминг глупой/не очень умной программой. Он не проверяет, имеет ли слово значение до или после Например, Если вы попытаетесь остановить "xqaing", хотя это не слово, оно удалит "-ing" и выдаст "xqa".

Таким образом, чтобы использовать более разумную систему, можно использовать лемматизаторы. Лемматизаторы используют правильно сформированные леммы (слова) в форме словосочетания и словарей. Так что всегда возвращается и принимает правильное слово. Тем не менее, это медленно, потому что он проходит через все слова, чтобы найти соответствующее.

Ответ 5

Стеммеры различаются по своей агрессивности. Портер является одним из самых агрессивных монстров для английского языка. Я нахожу, что обычно болит больше, чем помогает. На более легкой стороне вы можете использовать лемматизатор, как уже предлагалось, или более легкий алгоритмический стеммер. Недостатком лемматизаторов является то, что они не могут обрабатывать неизвестные слова.

Лично мне нравится стеммер Krovetz, который представляет собой гибридное решение, сочетающее лемматизатор словаря и облегченный стеммер для словарных слов. Krovetz также вариант kstem или light_stemmer в Elasticsearch. В pypi есть https://pypi.org/project/KrovetzStemmer/ реализация Python, хотя я не использовал ее.

Другой вариант - лемматизатор в spaCy. После обработки с помощью spaCy каждый токен имеет атрибут lemma_. (обратите внимание, подчеркивание lemma содержит числовой идентификатор lemma_) - https://spacy.io/api/token

Вот несколько работ, сравнивающих различные алгоритмы

Ответ 6

В моем проекте чат-бота я использовал PorterStemmer, однако LancasterStemmer также служит этой цели. Конечная цель состоит в том, чтобы свести слово к его корню, чтобы мы могли искать и сравнивать вводимые слова.

Например: из nltk.stem import 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

Надеюсь, это поможет..