Python 快速n-gram计算
我使用NLTK在语料库中搜索n-gram,但在某些情况下需要很长时间。我注意到计算n-gram在其他软件包中并不少见(显然Haystack有一些功能)。这是否意味着如果我放弃NLTK,有可能更快地在我的语料库中找到n-gram?如果是这样的话,我可以用什么来加速呢?既然你没有指出你想要的是单词级还是字符级的n-grams,我就假设前者,而不丧失一般性 我还假设您从一个由字符串表示的令牌列表开始。您可以轻松地自己编写n-gram提取Python 快速n-gram计算,python,nlp,nltk,n-gram,Python,Nlp,Nltk,N Gram,我使用NLTK在语料库中搜索n-gram,但在某些情况下需要很长时间。我注意到计算n-gram在其他软件包中并不少见(显然Haystack有一些功能)。这是否意味着如果我放弃NLTK,有可能更快地在我的语料库中找到n-gram?如果是这样的话,我可以用什么来加速呢?既然你没有指出你想要的是单词级还是字符级的n-grams,我就假设前者,而不丧失一般性 我还假设您从一个由字符串表示的令牌列表开始。您可以轻松地自己编写n-gram提取 def ngrams(tokens, MIN_N, MAX_N)
def ngrams(tokens, MIN_N, MAX_N):
n_tokens = len(tokens)
for i in xrange(n_tokens):
for j in xrange(i+MIN_N, min(n_tokens, i+MAX_N)+1):
yield tokens[i:j]
然后将yield
替换为您希望对每个n-gram采取的实际操作(将其添加到dict
,将其存储在数据库中,等等),以消除生成器开销
最后,如果它真的不够快,请将上面的转换为并编译它。使用defaultdict
代替yield
的示例:
def ngrams(tokens, int MIN_N, int MAX_N):
cdef Py_ssize_t i, j, n_tokens
count = defaultdict(int)
join_spaces = " ".join
n_tokens = len(tokens)
for i in xrange(n_tokens):
for j in xrange(i+MIN_N, min(n_tokens, i+MAX_N)+1):
count[join_spaces(tokens[i:j])] += 1
return count
使用
zip
和splat(*)操作符,您可能会发现一个pythonic、优雅且快速的ngram生成函数:
对于字符级别的n-grams,可以使用以下函数
def ngrams(text, n):
n-=1
return [text[i-n:i+1] for i,char in enumerate(text)][n:]
相关问题:Cython的较新版本识别Python for语句,并尽可能加快它们的速度。此外,在内部迭代中还有一个方法查找。在循环外部定义'tokenjoiner=”“.join'并替换内部“”。join应该可以加快速度。您可以使用“count.get(..)+=1”重写内行,引入另一个变量以避免方法查找。
def ngrams(text, n):
n-=1
return [text[i-n:i+1] for i,char in enumerate(text)][n:]