web-dev-qa-db-ja.com

Pythonでストップワードを削除するより速い方法

テキストの文字列からストップワードを削除しようとしています:

_from nltk.corpus import stopwords
text = 'hello bye the the hi'
text = ' '.join([Word for Word in text.split() if Word not in (stopwords.words('english'))])
_

このようなストリングを6ミル処理しているので、速度が重要です。私のコードをプロファイリングすると、最も遅い部分は上の行ですが、これを行うより良い方法はありますか?正規表現の_re.sub_などを使用することを考えていますが、一連の単語のパターンを記述する方法がわかりません。誰かが私に手を差し伸べることができますか、そして私は他のおそらくより速い方法を聞いてうれしいです。

注:stopwords.words('english')set()でラップするという誰かの提案を試しましたが、違いはありませんでした。

ありがとうございました。

37
mchangun

次に示すように、ストップワードオブジェクトをキャッシュしてみてください。関数を呼び出すたびにこれを作成することがボトルネックのようです。

    from nltk.corpus import stopwords

    cachedStopWords = stopwords.words("english")

    def testFuncOld():
        text = 'hello bye the the hi'
        text = ' '.join([Word for Word in text.split() if Word not in stopwords.words("english")])

    def testFuncNew():
        text = 'hello bye the the hi'
        text = ' '.join([Word for Word in text.split() if Word not in cachedStopWords])

    if __name__ == "__main__":
        for i in xrange(10000):
            testFuncOld()
            testFuncNew()

これをプロファイラーで実行しました:python -m cProfile -s incremental test.py。関連する行を以下に掲載します。

nCalls累積時間

10000 7.723 words.py:7(testFuncOld)

10000 0.140 words.py:11(testFuncNew)

したがって、ストップワードインスタンスをキャッシュすると、最大70倍のスピードアップが得られます。

83
Andy Rimmer

正規表現を使用して、一致しないすべての単語を削除します。

import re
pattern = re.compile(r'\b(' + r'|'.join(stopwords.words('english')) + r')\b\s*')
text = pattern.sub('', text)

これはおそらく、特に大きな入力文字列の場合、ループするよりもway速くなります。

これによってテキストの最後のWordが削除された場合、末尾に空白がある可能性があります。これは別に処理することを提案します。

15
Alfe

まず、文字列ごとにストップワードを作成します。一度作成してください。セットは本当にここで素晴らしいでしょう。

_forbidden_words = set(stopwords.words('english'))
_

その後、join内の_[]_を削除します。代わりにジェネレータを使用してください。

_' '.join([x for x in ['a', 'b', 'c']])
_

に置き換える

_' '.join(x for x in ['a', 'b', 'c'])
_

次に対処することは、配列を返す代わりに.split()の値を生成することです。 私はregexが良い代替品になると思います。 s.split()が実際に高速である理由については thist hread を参照してください。

最後に、このような作業を並行して実行します(6m文字列のストップワードを削除します)。それはまったく別のトピックです。

4

返事が遅れて申し訳ありません。新規ユーザーに役立つでしょう。

  • コレクションライブラリを使用してストップワードの辞書を作成する
  • その辞書を非常に高速な検索に使用します(時間= O(1))リストで実行するのではなく(時間= O(ストップワード))

    from collections import Counter
    stop_words = stopwords.words('english')
    stopwords_dict = Counter(stop_words)
    text = ' '.join([Word for Word in text.split() if Word not in stopwords_dict])
    
4
Gulshan Jangid