Python での NLTK ステミング異常の修正
-
Python での
NLTK
ステミング異常の修正 -
Python の
NLTK
のPorterStemmer
モジュールのステミング異常の修正 -
Python の
NLTK
でのステマーに対するレマタイザーの使用 - まとめ
ステミングは、その名前が示すように、単語を原形に還元する方法です。 たとえば、happiness
、happily
、happier
などの単語はすべて語根の単語 happy
に分類されます。
Python では、Python の NLTK
ライブラリによって提供されるさまざまなモジュールの助けを借りてこれを行うことができますが、期待した結果が得られない場合があります。 たとえば、fairly
は fairli
になり、fair
ではなく、NLTK
ライブラリの PorterStemmer
モジュールになります。
この記事では、このような違いが発生する理由と、必要なルート ワードを取得するためにそれらを修正する方法について説明します。 それでは、コーヒーを飲みながら読んでください!
Python での NLTK
ステミング異常の修正
Python の NLTK
ライブラリにはいくつかのステマーがありますが、最も一般的に使用されるのは PorterStemmer
です。 PorterStemmer
がどのように機能するかの例を次に示します。
まず、このコードで何が起こっているかを理解しましょう。
最初に PorterStemmer
を nltk
ライブラリからインポートし、そのインスタンスを作成します。 これで、このインスタンスを使用して、nltk
ライブラリで提供されている stem()
関数を使用して、指定された単語のリストをステミングできます。
from nltk.stem import PorterStemmer
p = PorterStemmer()
similar_words = ["act", "acting", "acts"]
for x in similar_words:
print(x, "comes from", p.stem(x))
出力:
act comes from act
acting comes from act
acts comes from act
このリストのすべての単語は、PorterStemmer
モジュールの助けを借りて、ルート単語 act
に縮小されます。 しかし、これはこのモジュールが常に機能する方法ではありません。
別の例を次に示します。
from nltk.stem import PorterStemmer
p = PorterStemmer()
print(p.stem("loudly"))
出力:
'loudli'
今度は loud
ではなく loudli
として出力が得られることがわかります。
なぜこれが起こるのだろうか。 そして、さらに重要なことに、これを修正する方法は?
Python の NLTK
の PorterStemmer
モジュールのステミング異常の修正
PorterStemmer
モジュールは 5つのフェーズで動作し、それぞれに独自のルールと手順があります。 さらに、それが一般的に与える結果は英語に基づいています。
これは、loudi
という単語は私たちが望んでいたものではありませんが、PorterStemmer
モジュールのルールに従って正しくステミングされた単語であることを意味します。
ただし、良いニュースもあります。NLTK
モジュールのすべてのステマーが同じように機能するわけではありません。 今度は、SnowballStemmer
を使って loudly
という単語をステミングしてみましょう。
ここで、言語をパラメーターとして SnowballStemmer()
関数に渡す必要があることに注意してください。
from nltk.stem import SnowballStemmer
s = SnowballStemmer("english")
print(s.stem("loudly"))
出力:
'loud'
SnowballStemmer
は確かに PorterStemmer
とは異なる一連のルールを使用しているため、今回は目的の出力が得られていることがわかります。 ここで興味深いことがあります。
これらのモジュールの両方を使用して、単語 actor
のステミングを試してみてください。 これは以下で行われます。
from nltk.stem import SnowballStemmer
from nltk.stem import PorterStemmer
p = PorterStemmer()
print(p.stem("actor"))
s = SnowballStemmer("english")
print(s.stem("actor"))
出力:
'actor'
'actor'
これらのモジュールはどちらも、ルート ワード act
ではなく、同じ出力 actor
を返すことがわかります。 LancasterStemmer
と呼ばれる別のステマーでこれを試してみましょう。
from nltk.stem import LancasterStemmer
l = LancasterStemmer()
print(l.stem("actor"))
出力:
'act'
今度は目的の出力 act
が得られていることがわかります。
さまざまなステマーが、さまざまな単語でさまざまな出力を生成する様子を確認しました。
他のさまざまなステマーを使用できますが、それらはすべて何らかのアルゴリズムに基づいているため、目的の出力が得られない可能性が常にあります。 また、これらのステマーは、アルゴリズムに基づいて単語を切り捨てる際に非常に厳密です。
また、ステミングは主にサフィックス部分で機能し、プレフィックスまたはインフィックスを削除して単語を解決するほどスマートではありません. ステミング アルゴリズムは、単語の意味と結果の語根を調べることさえしません。
この例を見てください。
これは、末尾に ing
が付いたランダムな文字列で、ステマーはこの接尾辞を削除して出力を返します。
from nltk.stem import PorterStemmer
p = PorterStemmer()
print(p.stem("wkhfksafking"))
出力:
'wkhfksafk'
したがって、この問題を解決するには、レンマタイザーを使用することをお勧めします。 レマタイザーの働きを詳しく見てみましょう。
Python の NLTK
でのステマーに対するレマタイザーの使用
ステマーとは異なり、レンマタイザーは単語を形態学的に分析し、単語が使用されるコンテキストに基づいて最も適切なレンマを見つけることができます。 補題は語幹とは異なり、すべての語形の基本形であるため、語幹と同じではないことに注意してください。
レンマタイザーがステマーよりも優れていることを示す例を見てみましょう。
ここでは、PorterStemmer
を使用していくつかの単語をステミングしています。
from nltk.stem import PorterStemmer
p = PorterStemmer()
w = ["studies", "studying", "study"]
for i in w:
print(p.stem(i))
出力:
studi
studi
studi
得られる出力があまり役に立たないことがわかります。 先に進んで、同じ単語セットでレンマタイザーを使用しましょう。
最初に WordNetLemmatizer
モジュールをインポートし、そのインスタンスを作成します。 次に、lemmatize()
関数を for
ループで使用して、各単語の補題を見つけます。
from nltk.stem import WordNetLemmatizer
l = WordNetLemmatizer()
w = ["studies", "studying", "study"]
for i in w:
print(l.lemmatize(i))
出力:
study
studying
study
今回はばかげた出力は得られず、すべての言葉は理にかなっています。
これが、レンマタイザーを使用する方がステマーを使用するよりも優れている理由です。
ステマーとレンマタイザーの詳細については、この リンクを参照してください。
まとめ
この記事では、Python の NLTK
のステマーとレンマタイザーについて説明しました。 ステマーがときどきばかげた結果を返す方法と理由、およびレンマタイザーを使用してより良い結果を得る方法について説明しました。