3

我有一个包含 8000 个字符串 (stop_words) 的列表和一个包含 100,000 个不同长度的字符串的列表,这些字符串包含数百万个单词。我正在使用该函数对 100,000 个字符串进行标记,并从列表 stop_words 中排除非字母数字标记和标记。

    def tokenizer(text):

       return [stemmer.stem(tok.lower()) for tok in nltk.word_tokenize(text)/ 
       if tok.isalpha() and tok.lower() not in stop_words]

我已经使用 600 个字符串测试了这段代码,它需要 60 秒。如果我删除排除停用词的条件,则在相同的 600 个字符串上需要 1 秒

    def tokenizer(text):

       return [stemmer.stem(tok.lower()) for tok in nltk.word_tokenize(text)/ 
       if tok.isalpha()]

我希望有一种更有效的方法可以从另一个列表中排除在一个列表中找到的项目。

我很感激任何帮助或建议

谢谢

4

3 回答 3

5

stop_words一个集合,以便查找是 O(1)。

stop_words = set(('word1', 'word2', 'word3'))
于 2013-01-12T13:10:19.030 回答
3
  • stop_words一个集合,因为检查集合中的成员是 O(1),而检查列表中的成员是 O(N)。
  • 为每个令牌调用lower()text一次)而不是两次。lower()

stop_words = set(stop_words)
def tokenizer(text):
   return [stemmer.stem(tok) for tok in nltk.word_tokenize(text.lower())
           if tok.isalpha() and tok not in stop_words]

由于访问局部变量比查找限定名称更快,因此您还可以通过 makenltk.word_tokenizestemmer.stemlocal 获得一点速度:

stop_words = set(stop_words)
def tokenizer(text, stem = stemmer.stem, tokenize = nltk.word_tokenize):
   return [stem(tok) for tok in tokenize(text.lower())
           if tok.isalpha() and tok not in stop_words]

stem和的默认值在定义函数时tokenize设置一次。里面,和是局部变量。通常这种微优化并不重要,但既然你调用 了 100K 次,它可能对你有一点帮助。tokenizertokenizerstemtokenizetokenizer

于 2013-01-12T13:12:50.540 回答
0

使用集:

{x for x in one_list} - other_list

但是,它会删除重复项和排序,因此如果很重要,您还需要其他东西。

于 2013-01-12T13:12:19.557 回答