web-dev-qa-db-ja.com

Pythonの最良のステミング方法は何ですか?

私はステミングのためにすべてのnltkメソッドを試しましたが、いくつかの単語で奇妙な結果が得られました。

すべきではないときに、しばしば単語の終わりをカットします。

  • プードル=> poodl
  • 記事記事

または非常に良いステム:

  • 簡単に、簡単に同じWordで語幹を持たない
  • 葉、成長、かなり茎がない

Pythonの他のステミングライブラリ、または優れた辞書を知っていますか?

ありがとうございました

29
PeYoTlL

あなたが得ている結果は、(一般的に)英語のステマーに期待されています。あなたは「すべてのnltkメソッド」を試したと言いますが、私があなたの例を試してみると、そうではないようです。

PorterStemmerを使用した例を次に示します

import nltk
ps = nltk.stemmer.PorterStemmer()
ps.stem('grows')
'grow'
ps.stem('leaves')
'leav'
ps.stem('fairly')
'fairli'

結果は 'grow'、 'leav'、および 'fairli'になります。これらは、たとえあなたが望むものであったとしても、元のWordの語幹バージョンです。

Snowballステマーに切り替える場合、言語をパラメーターとして指定する必要があります。

import nltk
sno = nltk.stem.SnowballStemmer('english')
sno.stem('grows')
'grow'
sno.stem('leaves')
'leav'
sno.stem('fairly')
'fair'

結果は「成長」と「葉」の場合と同じですが、「かなり」は「公平」になります

したがって、両方の場合(およびnltkで使用可能なステマーが3つ以上あります)、実際には、ステム処理されていないと言う単語はステム処理されません。 LancasterStemmerは、「easyly」または「easy」が入力として提供されると「easy」を返します。

たぶん、あなたは本当にレンマタイザーが欲しいですか?これは、「article」と「poodle」を変更せずに返します。

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

ここで説明したこれらのステマーはすべてアルゴリズムのステマーであるため、次のような予期しない結果を常に生成する可能性があります。

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']
11
0xF

ステミングとは、接尾辞を削除することです(通常は接尾辞のみです。nltkのステマーが接頭辞を削除できなかった限り、接尾辞は忘れてください)。したがって、ステミングは、愚かではない/インテリジェントではないプログラムとして明確に呼ぶことができます。 Wordがステミングの前または後に意味を持っているかどうかはチェックしません。例えば「xqaing」を語幹にしようとすると、Wordではありませんが、「-ing」が削除され、「xqa」が得られます。

したがって、よりスマートなシステムを使用するために、レンマタイザーを使用できます。 Lemmatizersは、整形式の語彙(単語)をワードネットと辞書の形式で使用します。したがって、常に適切なWordを返します。ただし、関連する単語を見つけるためにすべての単語を調べるため、時間がかかります。

2
Ritveak Dugar

ステマーの攻撃性はさまざまです。ポーターは、英語の最も攻撃的なステマーの1つです。私はそれが通常それが助けるよりももっと痛いのがわかります。ライター側では、既に提案されているように代わりにレンマタイザーを使用するか、ライターのアルゴリズムステム機能を使用できます。レマタイザーの制限は、未知の単語を処理できないことです。

個人的には、ボキャブラリーの単語に辞書レマタイザーと軽量ステマーを組み合わせたハイブリッドソリューションであるKrovetzステマーが好きです。 Krovetzは、Elasticsearchのkstemまたはlight_stemmerオプションも使用します。 python pypiの実装 https://pypi.org/project/KrovetzStemmer/ がありますが、これは私が使用したものではありません。

別のオプションは、spaCyのlemmatizerです。 spaCyすべてのトークンを使用した後処理には、lemma_属性があります。 (アンダースコアlemmalemma_の数値識別子を保持していることに注意してください)- https://spacy.io/api/token

さまざまなステミングアルゴリズムを比較するいくつかの論文を次に示します。

2
Daniel Mahler

私のチャットボットプロジェクトでは、PorterStemmerを使用しましたが、LancasterStemmerも目的を果たします。最終的な目的は、検索語の入力を検索して比較できるように、Wordをそのルートにステムすることです。

例: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

これが役立つことを願っています。

0
sarvesh Kumar