Por: Isabel Yepes
El análisis de sentimiento utiliza técnicas de procesamiento de lenguaje natural (NLP) para obtener conclusiones sobre textos producidos por personas y analizar en ellos rasgos de interés asociados a emociones positivas o negativas. Se requiere un modelo que ya haya sido entrenado con textos que nos permita obtener valores cuantificables.
Hoy nos apoyaremos en la guía de Free Code Camp “Basic data analysis on Twitter with Python” para hacer Análisis de Sentimientos sobre Twitter usando la librería TextBlob de Python que dispone de modelos de NLP para diversos usos.
Puedes ver este ejemplo en GitHub
Primero debemos tener instalada la librería tweepy.
#pip3 install tweepy
Si estás usando Python 3.7 tendrás un error al tratar de usar la librería que todavía no ha sido corregido en la última versión disponible (hoy, eso puede variar en poco tiempo) para resolverlo usamos la siguiente recomendación de StackOverFlow para reemplazar una palabra reservada Async en el archivo streaming.py de la librería.
La ubicación del archivo varía según tu sistema operativo, en Mac estará ubicado en /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tweepy/streaming.py edítala con un editor de texto plano y reemplaza todas las ocurrencias de async por async_ grabas y listo. Versiones anteriores a 3.7 de Python no requieren este cambio.
Previamente debemos tener la librería NLTK instalada, las instrucciones para hacerlo puedes verlas AQUÍ, para actualizarla si ya la tienes instalada
#python3 >>>import nltk >>>python3 nltk.download >>>quit()
Procedemos a clonar la librería TextBlob, realizar su instalación y descargar el corpus asociado sobre nltk
#git clone https://github.com/sloria/textblob #cd textblob #python3 setup.py install #python3 -m textblob.download_corpora
Si quieres saber más sobre la librería puede visitar su sitio en GitHub, tiene más herramientas de análisis para texto en Inglés, si deseamos análisis en español es necesario utilizar otra diferente https://github.com/sloria/textblob Dentro del script analizaremos los tweets cuya propiedad “lang” = “en” es decir aquellos cuyo lenguaje fue identificado como inglés. Para otras propiedades del tweet pueden consultar la documentación de Twitter.
Tendremos las claves de aplicación de Twitter en un archivo separado, de modo que no queden en el mismo código que estamos empleando y puedan reusarse en otros scripts, llamaremos a este script de claves twkeys.py
Recientemente Twitter cambió su forma de usar credenciales y ahora debe aplicarse por una cuenta de desarrollador, el proceso para aplicar puedes verlo en https://apps.twitter.com
#Credenciales del Twitter API def consumer_key(): #API Key return "Add Consumer Key here" def consumer_secret(): #API Secret return "Add Consumer Secret here" def access_key(): #Access Key return "Add Access Token here" def access_secret(): #Access Secret return "Add Access Token Secret here"
Este es el código que usamos para realizar el análisis, el resultado nos mostrará las gráficas de dispersión de dos cuentas, el promedio simple y promedio ponderado de sentimiento de ambas.
#Importar consumer API de Twitter https://github.com/tweepy/tweepy import tweepy #importar las credenciales de Twitter de un script import twkeys #Importar librería para Sentiment Analysis from textblob import TextBlob from time import sleep from datetime import datetime #Importar para graficar los Datos #Para Jupyter notebooks quitar el comentario a la siguiente línea #%matplotlib inline import matplotlib.pyplot as plt #Importar para calcular promedio ponderado import numpy as np #Credenciales del Twitter API que están el el script twkeys.py consumer_key = twkeys.consumer_key() consumer_secret = twkeys.consumer_secret() access_key = twkeys.access_key() access_secret = twkeys.access_secret() def get_all_tweets(screen_name,graph_id): #Este método solo tiene permitido descargar máximo los ultimos 3240 tweets del usuario #Especificar aquí durante las pruebas un número entre 200 y 3240 limit_number = 3240 #autorizar twitter, inicializar tweepy auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_key, access_secret) api = tweepy.API(auth) #inicializar una list to para almacenar los Tweets descargados por tweepy alltweets = [] #Hacer una petición inicial por los 200 tweets más recientes (200 es el número máximo permitido) new_tweets = api.user_timeline(screen_name = screen_name,count=200) #guardar los tweets más recientes alltweets.extend(new_tweets) #guardar el ID del tweet más antiguo menos 1 oldest = alltweets[-1].id - 1 #recorrer todos los tweets en la cola hasta que no queden más while len(new_tweets) > 0 and len(alltweets) <= limit_number: print ("getting tweets before" + str(oldest)) #en todas las peticiones siguientes usar el parámetro max_id para evitar duplicados new_tweets = api.user_timeline(screen_name = screen_name,count=200,max_id=oldest) #guardar los tweets descargados alltweets.extend(new_tweets) #actualizar el ID del tweet más antiguo menos 1 oldest = alltweets[-1].id - 1 #informar en la consola como vamos print (str(len(alltweets)) + " tweets descargados hasta el momento") #Realizar el análisis de sentimiento de los tweets descargados #Crear las listas de polaridad polarity_list y frecuencia de polaridad numbers_list polarity_list = [] numbers_list = [] number = 1 for tweet in alltweets: if tweet.lang == "en": try: analysis = TextBlob(tweet.text) analysis = analysis.sentiment #Guardar la polaridad polarity = analysis.polarity polarity_list.append(polarity) #Contar las veces que esa polaridad ha ocurrido numbers_list.append(number) number = number + 1 except tweepy.TweepError as e: print(e.reason) except StopIteration: break #Crear eje cartesiano plt.figure(graph_id) axes = plt.gca() axes.set_ylim([-1, 3]) plt.scatter(numbers_list, polarity_list) #Calcular el promedio de polaridad, NOTA: No es promedio ponderado averagePolarity = (sum(polarity_list))/(len(polarity_list)) averagePolarity = "{0:.0f}%".format(averagePolarity * 100) time = datetime.now().strftime("At: %H:%M\nOn: %m-%d-%y") #Calcular el promedio ponderado weighted_avgPolarity = np.average(polarity_list, weights=numbers_list) weighted_avgPolarity = "{0:.0f}%".format(weighted_avgPolarity * 100) #Agregar texto con el promedio de sentimiento plt.text(10, 1.5, "Average Sentiment: " + str(averagePolarity) + "\n" + " Weighted Average Sentiment: " + str(weighted_avgPolarity) + "\n" + time, fontsize=12, bbox = dict(facecolor='none', edgecolor='black', boxstyle='square, pad = 1')) #Título plt.title("Sentiment of " + screen_name + " on Twitter") plt.xlabel("Number of Tweets") plt.ylabel("Sentiment") pass if __name__ == '__main__': #especificar el nombre de usuario de la cuenta a la cual se descargarán los tweets get_all_tweets("Add_account_1",200) get_all_tweets("Add_account_2",300) #Mostrar las gráfica plt.show()
El siguiente video explica todo el proceso.