快速n-gram计算

Tri*_*daz 18 python nlp nltk n-gram

我正在使用NLTK在语料库中搜索n-gram,但在某些情况下需要很长时间.我注意到计算n-gram在其他包中并不常见(显然Haystack有一些功能).这是否意味着如果我放弃NLTK,我的语料库中有更快的方法可以找到n-gram?如果是这样,我可以用什么来加快速度?

Fre*_*Foo 23

既然你没有说明你是否想要单词或字符级的n-gram,我只是假设前者,而不失一般性.

我还假设你从一个由字符串表示的标记列表开始.您可以轻松完成的是自己编写n-gram提取.

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]
Run Code Online (Sandbox Code Playgroud)

然后用yield你想要对每个n-gram执行的实际操作替换(将其添加到a dict,将其存储在数据库中,等等)以消除生成器开销.

最后,如果它真的不够快,将上面的内容转换为Cython并进行编译.使用a 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
Run Code Online (Sandbox Code Playgroud)

  • 较新版本的Cython可识别Python语句,并在可能的情况下加速它们.此外,您在内部迭代中有一个方法查找.在循环外定义'tokenjoiner ="".join"并替换内部"".join应该加快速度. (3认同)

小智 8

您可以在这里使用zip 和splat(*)运算符找到pythonic,优雅和快速的ngram生成函数 :

def find_ngrams(input_list, n):
  return zip(*[input_list[i:] for i in range(n)])
Run Code Online (Sandbox Code Playgroud)