Nubes de palabras en Python

Publicado por Andrea Navarro en

En este artículo veremos como realizar nubes de palabras utilizando la librería Wordcloud a partir de un texto o una tabla de frecuencias. Veremos como personalizar el tamaño, forma y estilo de nuestra nube y descargarlo como imagen.

Las nubes de palabras o nubes de tags son un tipo de gráfico que representa visualmente la frecuencia con la que una palabra o frase aparece en un conjunto de datos. La cantidad de apariciones se ve reflejado en el tamaño de la fuente con la que dicha palabra o frase es graficada en la nube, a mayor frecuencia mayor tamaño de fuente.

Además de ser visualmente atractivas las nubes de palabras permiten identificar los elementos más relevantes de un texto o las opiniones más significativas de una encuesta o un estudio de mercado. Es una manera de mostrar de una manera sintética y rápida datos complejos entendibles para cualquier tipo de púbico.

Wordcloud

Wordcloud es una librería de Python liberada bajo licencia MIT que permite generar nubes de palabras de manera automática. Depende de las librerías numpy, pillow y matplotlib.

from wordcloud import WordCloud
import matplotlib.pyplot as plt

texto=("Regular Bueno Regular Excelente Malo Bueno Bueno Bueno Bueno Malo Regular Regular ")
nube = WordCloud().generate(texto)
plt.imshow(nube,interpolation='bilinear')
plt.axis("off")
plt.show()

Para generar una nube de palabras se utiliza la clase WordCloud junto con el método generate al que se le pasa como atributo el texto que debe analizarse. Luego, para que esta imagen se muestre se utiliza el método imshow de Matplotlib pasando como parámetro la nube que se ha generado.

Para evitar que se muestren los valores por defecto de los ejes X e Y estos se ocultan con la opción axis configurada a off. Finalmente se solicita que se muestre la imagen con el método show.

Obtener texto de archivo

Si los valores a analizar se encuentran dentro de un archivo estos pueden ser leídos utilizando la opción read de manera de generar una sola variable que contenga todas las palabras. En el siguiente ejemplo se analiza la obra Martin Fierro desde un archivo .txt descargado de Proyecto Gutenberg.

from wordcloud import WordCloud
import matplotlib.pyplot as plt
texto=open ("martinfierro.txt").read()
nube = WordCloud().generate(texto)
plt.imshow(nube,interpolation='bilinear')
plt.axis("off")
plt.show()

En la nube resultante puede verse las palabras más utilizadas en la obra.

Eliminar palabras no relevantes

En el ejemplo anterior puede observarse que la nube se ha llenado de palabras que no se relacionan directamente con la obra sino que se tratan de conectores, artículos y pronombres que son muy utilizados en el idioma español. Este tipo de palabras se llaman stop words y pueden ser eliminadas de la nube para mostrar un resultado más significativo.

En el siguiente ejemplo se utiliza la librería Natural Language Toolkit para descargar las stop words típicas de los idiomas inglés y español. Existen otras opciones y fuentes desde las cuales pueden obtenerse stop words de diferentes idiomas.

En este caso específico se ha sumando a las stop words algunas palabras inglesas que aparecen a la obra debido a la versión del archivo. Finalmente se le pasa la lista de palabras a ignorar a la nube de palabras con el argumento stopwords.

from wordcloud import WordCloud
import matplotlib.pyplot as plt
import nltk
from nltk.corpus import stopwords
stop_words_es = stopwords.words("spanish")
stop_words = stop_words_es +stopwords.words("english")
stop_words = stop_words + ["Project","Gutenberg","work","electronic","tm","Foundation","works","donation","License","agreement","terms","state","eBook","full","States","copyright","paragraph","may","use","Archive","org","copy","literay"]
texto=open ("martinfierro.txt").read()
nube = WordCloud(stopwords=stop_words).generate(texto)
plt.imshow(nube,interpolation='bilinear')
plt.axis("off")
plt.show()

Limitar cantidad de palabras

Es posible limitar la cantidad de palabras que se muestran en la nube de palabras se utiliza el argumento max_words. En el siguiente ejemplo solo se mostrarán las 20 palabras más usadas.

from wordcloud import WordCloud
import matplotlib.pyplot as plt
# Generar stopowords
texto=open ("martinfierro.txt").read()
nube = WordCloud(stopwords=stop_words,
                 max_words = 20,
                 ).generate(texto)
plt.imshow(nube,interpolation='bilinear')
plt.axis("off")
plt.show()

Modificar dimensiones

Los atributos width y height permite seleccionar el ancho y alto respectivamente de la imagen resultante permitiendo diferentes proporciones.

from wordcloud import WordCloud
import matplotlib.pyplot as plt
# Generar stopowords
texto=open ("martinfierro.txt").read()
nube = WordCloud(stopwords=stop_words,
                 max_words = 40,
                 width = 1000,
                 height = 200
                ).generate(texto)
plt.imshow(nube,interpolation='bilinear')
plt.axis("off")
plt.show()

Colores

Wordcloud provee diferentes opciones para la selecciones de los colores de la imagen. Para seleccionar el color de fondo de la imagen se utiliza el argumento background_color.

from wordcloud import WordCloud
import matplotlib.pyplot as plt
# Generar stopowords
texto=open ("martinfierro.txt").read()
nube = WordCloud(stopwords=stop_words,
                 max_words = 40,
                 background_color = "grey"
                ).generate(texto)
plt.imshow(nube,interpolation='bilinear')
plt.axis("off")
plt.show()

Para modificar el color de las palabras de las nubes puede usarse el atributo colormap y pasar como valor algunas de las paletas de colores permitidas por Matplotlib.

from wordcloud import WordCloud
import matplotlib.pyplot as plt
# Generar stopowords
texto=open ("martinfierro.txt").read()
nube = WordCloud(stopwords=stop_words,
                 max_words = 40,
                 background_color = "white",
                 colormap = "copper_r"
                ).generate(texto)
plt.imshow(nube,interpolation='bilinear')
plt.axis("off")
plt.show()

Generar nube a partir de frecuencias

En el caso que no se quiera realizar el análisis previo donde se contabilizan las palabras sino que ya se cuente con elementos asociados con un valor es posible utilizarlos para la creación de la nube convirtiendo los valores primeros a un diccionario.

Para hacerlo se utiliza la opción generate_from_frequencies en lugar de generate pasando como resultado el diccionario.

from wordcloud import WordCloud
import matplotlib.pyplot as plt

resultados = {'Excelente': 50, 'Muy bueno': 10, 'Bueno': 5, 'Malo': 8 }
nube = WordCloud().generate_from_frequencies(resultados)
plt.imshow(nube,interpolation='bilinear')
plt.axis("off")
plt.show()

Repetir palabras

En el caso que no exista suficiente variedad de términos y la nube resultante tenga demasiados espacios vacíos puede solicitarse que los elementos se repitan hasta llenar el espacio con el atributo repeat.

from wordcloud import WordCloud
import matplotlib.pyplot as plt

resultados = {'Excelente': 50, 'Muy bueno': 10, 'Bueno': 5, 'Malo': 8 }
nube = WordCloud(repeat = True).generate_from_frequencies(resultados)
plt.imshow(nube,interpolation='bilinear')
plt.axis("off")
plt.show()

Descargar como archivo

Una vez que la nube haya sido configurado correctamente esta puede ser descargada como archivo utilizando el método to_file y especificando la ubicación, nombre y extensión del archivo.

from wordcloud import WordCloud
import matplotlib.pyplot as plt
# Generar stopowords
texto=open ("martinfierro.txt").read()
nube = WordCloud(stopwords=stop_words,
                 max_words = 40,
                 background_color = "grey",
                 colormap = "magma"
                ).generate(texto).to_file("nube-martinfierro.jpeg")

En este artículo hemos visto como generar una nube de palabras a partir de un texto o un conjunto de frecuencias utilizando la librería Wordcloud de Python. También hemos visto algunas configuraciones básicas para modificar el estilo resultante. Espero que les sirva!


¿Preguntas? ¿Comentarios?

Si tenés dudas, o querés dejarnos tus comentarios y consultas, sumate al grupo de Telegram de la comunidad JuncoTIC!
¡Te esperamos!


Andrea Navarro

- Ingeniera en Informática - Docente universitaria - Investigadora