separar - palabras reservadas python significado
Cálculo rápido de n-gramas (3)
Para los n-gramas a nivel de caracteres, puede utilizar la siguiente función
def ngrams(text, n):
n-=1
return [text[i-n:i+1] for i,char in enumerate(text)][n:]
Estoy usando NLTK para buscar n-grams en un corpus pero en algunos casos está demorando mucho tiempo. Me he dado cuenta de que calcular n-grams no es una característica poco común en otros paquetes (al parecer, Haystack tiene alguna funcionalidad para ello). ¿Significa esto que hay una forma potencialmente más rápida de encontrar n-gramas en mi corpus si abandono NLTK? Si es así, ¿qué puedo usar para acelerar las cosas?
Puede encontrar una función de generación ngram pythonic, elegante y rápida utilizando zip
operador zip
y splat (*) here :
def find_ngrams(input_list, n):
return zip(*[input_list[i:] for i in range(n)])
Ya que no indicó si desea n-gramas de palabra o de nivel de carácter, solo asumiré lo primero, sin pérdida de generalidad.
También supongo que empiezas con una lista de tokens, representada por cadenas. Lo que puedes hacer fácilmente es escribir la extracción de n-gramas tú mismo.
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]
Luego reemplace el yield
con la acción real que desea realizar en cada n-gramo (agréguelo a un dict
, almacénelo en una base de datos, lo que sea) para deshacerse de la sobrecarga del generador.
Finalmente, si realmente no es lo suficientemente rápido, convierte lo anterior en Cython y compílalo. Ejemplo utilizando un valor defaultdict
lugar de 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