更快地删除Python中的停用词

时间:2013-10-24 08:13:45

标签: python regex stop-words

我正在尝试从一串文字中删除停用词:

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(),但这没有任何区别。

谢谢。

5 个答案:

答案 0 :(得分:72)

尝试缓存停用词对象,如下所示。每次调用函数时构造它似乎都是瓶颈。

    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 cumulative test.py 。相关的行列在下面。

nCalls累积时间

10000 7.723 words.py:7(testFuncOld)

10000 0.140 words.py:11(testFuncNew)

因此,缓存停用词实例可以提供~70倍的加速。

答案 1 :(得分:12)

使用正则表达式删除所有不匹配的单词:

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

这可能方式比循环自己更快,特别是对于大型输入字符串。

如果文本中的最后一个单词被删除,则可能有尾随空格。我建议单独处理。

答案 2 :(得分:4)

首先,您要为每个字符串创建停用词。创建一次。确实在这里设置很棒。

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在这里会有很好的替代。请参阅thist hread了解s.split()实际上为什么很快。

最后,并行执行此类工作(删除6m字符串中的停用词)。这是一个完全不同的主题。

答案 3 :(得分:0)

对不起,请稍后答复。 对新用户有用。

  • 使用收藏库创建停用词词典
  • 使用该词典进行非常快速的搜索(时间= O(1)),而不要在列表上进行搜索(时间= O(停用词))

    from collections import Counter
    stop_words = stopwords.words('english')
    stopwords_dict = Collections.counter(stop_words)
    text = ' '.join([word for word in text.split() if stopwords_dict[word]==0])
    

答案 4 :(得分:0)

尝试通过避免循环并使用正则表达式来删除停用词来使用它:

import re
from nltk.corpus import stopwords

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