Los ngramas y las colocaciones son conceptos fundamentales en el procesamiento del lenguaje natural. Un ngrama es una secuencia de palabras consecutivas en un texto. Puede ser un bigrama (dos palabras), un trigrama (tres palabras) o más. Las colocaciones, por otro lado, son conjuntos de palabras que tienden a aparecer juntas debido a factores culturales o de uso en el lenguaje, como "tomar una decisión" o "romper el hielo". Estas secuencias nos permiten analizar textos de manera profunda, identificando patrones y relaciones significativas entre palabras.
¿Cómo extraer bigramas usando NLTK?
Para trabajar con bigramas en NLTK, es importante seguir ciertos pasos para obtener un análisis significativo. Empezamos importando las librerías necesarias como NLTK, Pandas, Matplotlib y Plotly. Estas herramientas nos permiten manejar textos y realizar visualizaciones interactivas.
import nltk
from nltk import bigrams
from nltk.book import text1
# Cargar libronltk.download('book')# Generar bigramasmd_bigrams =list(bigrams(text1))
¿Cómo calcular la frecuencia de bigramas?
Una vez extraídos los bigramas de un texto, podemos calcular su frecuencia utilizando la función FreqDist de NLTK. Esto nos proporciona una distribución de apariencia de los bigramas en el texto.
from nltk import FreqDist
# Calcular la frecuencia de bigramasf_dist = FreqDist(md_bigrams)# Obtener los 10 bigramas más comunescommon_bigrams = f_dist.most_common(10)
¿Cómo filtrar bigramas de forma efectiva?
Podemos aplicar filtros a nuestros bigramas para eliminar palabras irrelevantes o caracteres especiales. Esto se puede hacer utilizando listas y condiciones dentro de bucles for.
threshold =2filtered_bigrams =[bigram for bigram in md_bigrams iflen(bigram[0])> threshold andlen(bigram[1])> threshold]
¿Cómo trabajar con trigramas y engramas en general?
El análisis de trigramas sigue una lógica similar a la de los bigramas. La función ngrams de NLTK permite calcular secuencias de cualquier longitud.
from nltk.util import ngrams
# Definir trigramasmd_trigrams =list(ngrams(text1,3))# Calcular frecuencia de trigramastrigram_dist = FreqDist(md_trigrams)
¿Cuál es la importancia de los engramas en la PNL?
Los engramas juegan un papel crucial en muchas aplicaciones del procesamiento del lenguaje natural. Son la base para:
La clasificación de texto
La traducción automática
El aprendizaje de embeddings para vectores de palabras
El desarrollo de algoritmos avanzados en deep learning
Además, si estás en redes sociales analizando comentarios sobre una marca, usar engramas te facilitará la creación de nubes de palabras o frases, ayudándote a entender mejor el contexto y sentimiento asociado a un tema específico.
Recomendaciones para seguir aprendiendo
Entender y aplicar correctamente el análisis de ngramas y colocaciones te abrirá puertas a una amplia gama de posibilidades en el procesamiento del lenguaje natural. Te animo a seguir explorando y practicando con diferentes textos y herramientas, ¡el campo de la PNL está lleno de oportunidades emocionantes!
Extracción de Ngramas y Bigramas con NLTK en Python
Extracción de Ngramas y Bigramas con NLTK en Python
from nltk.utilimport ngrams
md_trigrams =list(ngrams(text1,3))# objeto que va a guardar una lista, el segundo argumento es la cantidad de palabras que quiero extraer
#list es para que lo pueda mostrar
filtered_trigrams =[trigram for trigram in md_trigrams iflen(trigram[0])> threshold and len(trigram[1])> threshold and len(trigram[2])> threshold]fdist =FreqDist(filtered_trigrams)print(fdist.most_common(10))fdist.plot(10)
Aquí dejo un ejemplo de como es que quedarían los tri-gramas ya filtrados y ploteados, además dejo el código comentado por si es que te ha surgido una duda de que hace cada paso :)
from nltk.utilimport ngrams
# extraemos los trigramas
md_trigrams =list(ngrams(text1,3))# obtenemos su distribucion
fdist =FreqDist(md_trigrams)# AHORAVAMOSAVERLOSMASCOMUNRESYFILTRARLOS# minimo de caracteres para las palabras de los bi-gramas
threshold =2# hacemos el filtrado
filtered_trigrams =[trigram for trigram in md_trigrams \
iflen(trigram[0])> threshold \
and len(trigram[1])> threshold \
and len(trigram[2])> threshold]
# obtenemos las distribuciones
filtered_dist =FreqDist(filtered_trigrams)# procedemos directamente al plot de los 20 mas comunes
filtered_dist.plot(20)
filtered =[trigram for trigram in trigrama if re.search("[a-z0-9]", trigram[0]) and re.search("[a-z0-9]", trigram[1]) and re.search("[a-z0-9]", trigram[2]) and len(trigram[0])>2 and len(trigram[1])>2 and len(trigram[2])>2]filtered
fdist =FreqDist(filtered)fdist.most_common(4)fdist.plot(4)
Sería interesante saber cual es el tamaño óptimo de un N-Grama para un texto cualquiera, calculo que las estadísticas para las colocaciones varían según el tamaño del n-grama.
from nltk.corpusimport stopwords
stop_words = stopwords.words('english')tokens_filtrados =[palabra for palabra in text1 if palabra.isalpha() and palabra.lower() not in stop_words]md_bigrams =list(bigrams(tokens_filtrados))fdist =FreqDist(md_bigrams)md_bigrams[:15]
Obtengo el siguiente error al ejecutar la primera celda del C5 ipynb.
import nltk
nltk.download('book')
from nltk.book import *
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import plotly.express as px
Mi entorno es JupyterLab 1.2.6 dentro de la instalacion de Anaconda Navigator 1.9.7
¿Alguien sabe por qué?
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-1-fde300df6df3> in <module>
5 import numpy as np
6 import pandas as pd
----> 7 import plotly.express as px
aun tenemos un problema y es las mayusculas y las minusculas
from nltk.utilimport ngrams
tgrams=list(ngrams(text1,3))fd_tgrams=FreqDist(tgrams)fd_tgrams.most_common(5)threshold=2filter_tgrams=[tgram for tgram in tgrams iflen(tgram[0])>threshold and len(tgram[1])>threshold and len(tgram[2])>threshold]fd_tgrams_filter=FreqDist(filter_tgrams)fd_tgrams_filter.most_common(5)```
[(('the','Sperm','Whale'),77),(('the','White','Whale'),63),(('the','old','man'),32),(('the','sperm','whale'),30),(('the','Right','Whale'),25)]
filtered_bigrams =[bigram for bigram in md_bigrams
if not bigram[0]in stop_words
and bigram[1] not in stop_words
and bigram[0]instr(re.search('[a-zA-Z]{3,}', bigram[0])) and bigram[1]instr(re.search('[a-zA-Z]{3,}', bigram[1]))]
threshold =2filtered_trigrams =[ngram for ngram in md_trigrams iflen(ngram[0])>threshold and len(ngram[1])>threshold and len(ngram[2])>threshold]filtered_tri_dist =FreqDist(filtered_trigrams)filtered_tri_dist.plot(20)filtered_tri_dist.most_common(20)
Qué les parece esta forma para definir los bigramas y los trigramas. Creo que es un poco más rápido y más significativo.
import nltk
nltk.download('book')from nltk.bookimporttext1from nltk.probabilityimportFreqDistnltk.download('stopwords')from nltk.corpusimport stopwords
english_stopwords = stopwords.words("english")filtered_freqdist =FreqDist(nltk.bigrams(filter(lambda word: word.isalpha() and word.lower() not in english_stopwords, text1)))filtered_freqdist.plot(20)
Y para los trigramas
filtered_freqdist =FreqDist(nltk.ngrams(filter(lambda word: word.isalpha() and word.lower() not in english_stopwords, text1),3))filtered_freqdist.plot(20)
threshold =2filtered_trigrams =(trigram for trigram in md_trigrams iflen(trigram[0])>threshold and len(trigram[1])>threshold and len(trigram[2])>threshold)filtered_trigrams_dist =FreqDist(filtered_trigrams)filtered_trigrams_dist.most_common(10)filtered_trigrams_dist.plot(10)
Cuando grafiqué los bigramas pude observar que algunos se repetían, debido a que a la minúscula y mayúscula. Así que después de importar las librerías le añadí las siguientes líneas para transformar las palabras a lowercase:
# stopwords
stop_words = stopwords.words('english')# Eliminado de stopwords y conversión a lowercase
text1 =[word.lower()for word in text1 if word not in stop_words]
Ojalá más tarde no tenga que darme cuenta que no es correcto hacerlo.
Hola!
Porfa verifica que tienes instalado el módulo de plotly usando el siguiente comando en la consola de tu entorno virtual:
>pip freeze
De no estar allí listado, te invito a que uses el siguiente comando para la instalación: