Estoy buscando una manera de dividir un texto en n-gramas. Normalmente haría algo como:
import nltk
from nltk import bigrams
string = "I really like python, it's pretty awesome."
string_bigrams = bigrams(string)
print string_bigrams
Soy consciente de que nltk solo ofrece bigrams y trigrams, pero ¿hay alguna forma de dividir mi texto en cuatro gramos, cinco gramos o incluso cien gramos?
¡Gracias!
ingrams
cuyo segundo parámetro es el grado de los ngrams que desea. ¿Es ESTA la versión de nltk que estás usando? Incluso si no, aquí está la fuente EDITAR: Hayngrams
yingrams
allí,ingrams
ser un generador.Respuestas:
Excelentes respuestas basadas en Python nativas dadas por otros usuarios. Pero aquí está el
nltk
enfoque (por si acaso, el OP se penaliza por reinventar lo que ya existe en lanltk
biblioteca).Hay un módulo ngram que la gente rara vez usa
nltk
. No es porque sea difícil de leer ngrams, sino entrenar una base de modelo en ngrams donde n> 3 dará como resultado mucha escasez de datos.fuente
sixgrams
?Me sorprende que esto aún no se haya presentado:
fuente
Usando solo herramientas nltk
Salida de ejemplo
Para mantener los ngrams en formato de matriz simplemente elimine
' '.join
fuente
Aquí hay otra forma simple de hacer n-gramos
fuente
La gente ya ha respondido bastante bien para el escenario en el que necesita bigramas o trigramas, pero si necesita cada gramo para la oración en ese caso, puede usar
nltk.util.everygrams
En caso de que tenga un límite, como en el caso de los trigramas donde la longitud máxima debe ser 3, puede usar max_len param para especificarlo.
Puede modificar el parámetro max_len para lograr cualquier gramo, es decir, cuatro gramos, cinco gramos, seis o incluso cien gramos.
Las soluciones mencionadas anteriormente se pueden modificar para implementar la solución mencionada anteriormente, pero esta solución es mucho más sencilla que eso.
Para leer más, haga clic aquí
Y cuando solo necesita un gramo específico como bigram o trigram, etc., puede usar nltk.util.ngrams como se menciona en la respuesta de MAHassan.
fuente
Puede preparar fácilmente su propia función para hacer esto usando
itertools
:fuente
izip(*(islice(seq, index, None) for index, seq in enumerate(tee(s, N))))
Me puede explicar que no lo entiendo del todo?Un enfoque más elegante para construir bigrams con la construcción incorporada de Python
zip()
. Simplemente convierta la cadena original en una listasplit()
, luego pase la lista una vez normalmente y una vez desplazada por un elemento.fuente
Nunca he tratado con nltk pero hice N-gramos como parte de algún proyecto de clase pequeña. Si desea encontrar la frecuencia de todos los N-gramos que ocurren en la cadena, aquí hay una manera de hacerlo.
D
te daría el histograma de tus N palabras.fuente
collections.Counter(tuple(strparts[i:i+N]) for i in xrange(len(strparts)-N))
funcionará más rápido que el try-exceptPara four_grams ya está en NLTK , aquí hay un fragmento de código que puede ayudarlo a lograrlo:
Espero que ayude.
fuente
Puede usar sklearn.feature_extraction.text.CountVectorizer :
salidas:
Puede establecer
ngram_size
en cualquier número entero positivo. Es decir, puede dividir un texto en cuatro gramos, cinco gramos o incluso cien gramos.fuente
Si la eficiencia es un problema y tiene que construir varios n-gramas diferentes (hasta cien como usted dice), pero desea utilizar Python puro, lo haría:
Uso:
~ Misma velocidad que NLTK:
Repost de mi respuesta anterior .
fuente
Nltk es genial, pero a veces es una sobrecarga para algunos proyectos:
Ejemplo de uso:
fuente
Puede obtener todos los 4-6 gramos usando el código sin otro paquete a continuación:
la salida está debajo:
puedes encontrar más detalles en este blog
fuente
Después de unos siete años, aquí hay una respuesta más elegante usando
collections.deque
:Salida:
fuente
Si desea una solución iteradora pura para cadenas grandes con uso constante de memoria:
Prueba:
Salida:
fuente