Saltar al contenido

Dibujando 100k tweets de mi ciudad

[Esta entrada apareció originalmente en inglés en mi blog].
Hace tiempo que he querido jugar con la API de Twitter. El pasado verano se me ocurrió que podría ser interesante dibujar un mapa de mi ciudad (Murcia, España, bella ciudad con comida increible) mostrando un heatmap de tweets.
La idea es que dibujando esos tweets podría encontrar patrones interesantes de mi ciudad. Por ejemplo:

  • ¿Desde qué áreas la gente tuitea más?
  • ¿Qué horas del día son las más activas?
  • ¿Cuales son los lugares más felices/tristes?
  • ¿Hay alguna comunidad tuitera local extranjera?

Con esas ideas en la cabeza empecé la investigación. Primero, necesitaba una librería para interactuar con la API de Twitter. Después de probar la extensa cantidad de wrappers disponibles me decidí por Tweepy. Posee una interfaz simple y agradable de usar y está bien mantenida.
(INCISO, todo el código y los datos que se usan en esta entrada está disponible en Github).
De cara a obtener los tweets de mi ciudad en tiempo real decidí ajustarme al API Streaming de Twitter. Este es el código sencillo que usé:

import json
from tweepy import Stream
from tweepy import OAuthHandler
from tweepy.streaming import StreamListener
ckey = CONSUMER_KEY
csecret = CONSUMER_SECRET
atoken = APP_TOKEN
asecret = APP_SECRET
murcia = [-1.157420, 37.951741, -1.081202, 38.029126] #Venid a verla, es una ciudad muy bonita!
file =  open('tweets.txt', 'a')
class listener(StreamListener):
    def on_data(self, data):
        # La API de Twitter devuelve datos en formato JSON, asi que hay que decodificarlos.
        try:
            decoded = json.loads(data)
        except Exception as e:
            print(e) #no queremos que el script se pare
        return True
        if decoded.get('geo') is not None:
            location = decoded.get('geo').get('coordinates')
        else:
            location = '[,]'
        text = decoded['text'].replace('\n',' ')
        user = '@' + decoded.get('user').get('screen_name')
        created = decoded.get('created_at')
        tweet = '%s|%s|%s|s\n' % (user,location,created,text)
        file.write(tweet)
        print(tweet)
        return True

    def on_error(self, status):
        print(status)

if __name__ == '__main__':
    print('Empezando...')
    auth = OAuthHandler(ckey, csecret)
    auth.set_access_token(atoken, asecret)
    twitterStream = Stream(auth, listener())
    twitterStream.filter(locations=murcia)

El script solo requiere las claves y secretos de la API de Twitter además de un par de puntos (latitudes y longitudes de los puntos). La API de Twitter solo devolverá tweets cuyas lat/lon estén dentro de los límites definidos (al menos, en teoria).
INCISO: Si no quieres tener que descargarte los tweets puedes bajarte el archivo en Github
Dejé este script ejecutándose durante meses en una de mis instancias en Digital Ocean. Obtuve alrededor de 600K tweets. De esos 600K, alrededor de 1/6 estaban geolocalizados. Por tanto, me quedé con 100K tweets para hacer el gráfico.
Una vez que tenemos los datos de Twitter parseados, solo tuve que buscar una buena librería para dibujar heatmaps. La mejor que encontré, tanto por su simplicidad (solo un fichero)como por su nivel de ajustes, fue Heatmap.py.
Puedes echar un vistazo en Github para ver como usé heatmap. Aquí puedes varios de los mapas que dibujé:

Bonito, ¿verdad?
En la próxima entrada os mostraré como aplicar análisis de sentimientos al conjunto de datos para encontrar los lugares de la ciudad más alegres/tristes.

8 comentarios en «Dibujando 100k tweets de mi ciudad»

  1. Pingback: Como hacer un mapa de calor de tu ciudad mostrando las zonas donde más se usa Twitter

  2. Pingback: Como hacer Análisis de Sentimiento en español | Pybonacci

  3. Se ve interesante, el tema voy a probarlo apenas pueda, pero una consulta esas latitudes y longitudes las busco en el mapa y me aparecen en una cuidad en kenia xD, las probé en google maps, por eso mi consulta, como obtengo las coordenadas de mi zona donde quiero probar?
    Saludos

  4. Hola Macjob,
    Has comprobado que efectivamente, estas buscando latitudes y longitudes y no longitudes y latitudes? Hay sistemas que usan lat,lon y otros usan lon, lat (no es standard desafortunadamente).

  5. ¡Hola, Manuel!
    Antes que nada, ¡gracias por tus aportaciones al campo del NLP!
    Verás, acabo de empezar un MSc y ando en búsqueda de un proyecto de Research a desarrollar. Una de las cosas que me apasiona leer es sobre NLP y Opinion Mining; sin embargo, llevo dedicándome al área de tecnología como Oracle DBA, desde ya casi 14 años. Esto me especializó en muchas cosas, pero me alejó de otras; por ejemplo, la programación OOP.
    Yendo al grano: si pudieras darme un consejo, ¿por dónde me recomedarías empezar para realizar un Análisis de Sentimientos “a bajo nivel” (por ejemplo, descargar un data set de tweets y buscar en éste alguna tendencia “básica” en “Política o Gobierno de un país”)?, pero tomando en cuenta que tengo que entregar el proyecto de Research en 3 meses. ¿Lo ves factible? Mis habilidades son: RDBMS, Linux, Replicación de Datos, BBDD > 25 TB, PLSQL, Shell / Bash Scripting.
    En caso de que lo veas factible, ¿por dónde me recomendarías empezar? Me podrías dar, a gran escala por supuesto, una serie de pasos a seguir; digamos: “instala Python, descarga y lee la doc. de tweepy, activa el feed de Twitter y descarga tweets durante…” etc etc. ¡Lo que se te ocurra es bienvenido y extremadamente agradecido!
    Pregunta final y con menos importancia, que esto ya lo puedo seguir investigando: debido a la política de Twitter, ¿no es posible descargar tweets antiguos? Es decir, si quiero buscar una tendencia cronológica, puedo comparar tweets actuales versus el año pasado?
    De nuevo, mil gracias por leerme y perdona tanta pregunta y texto!
    Un saludo desde Cambridge, UK!
    Carlos.

  6. Hola Manuel. Disculpas de antemano por “reflotar” un post tan antiguo, pero me ha parecido muy bueno y quise probarlo. Soy un iniciado en python, ciencia de datos y tal, por lo cual aun me falta un largo camino y enfrento un problema al ejecutar este script y es que si bien queda ejecutando, no me escribe nada en el archivo txt ni me imprime tuits en pantalla a medida que los captura.
    Quizá tenga que ver con que cuando al ejecutarlo me pedía que le pusiera los parentesis curvos a las sentencias PRINT, esa fue la única modificación que hice y cambiarle el nombre al archivo que utilizo. Estoy corriendo sobre linux mint 19.2 en un proyecto creado con ambiente pipenv.

    Gracias de antemano por cualquier “insight”

    1. Si te está pidiendo paréntesis curvos, significa que estás usando python3.

      Con lo cual, para montar el entorno usa la orden python3 -m venv venv (donde el primer venv es el nombre del módulo python que estás utilizando y el segundo el nombre que le vas a poner al entorno)

      Saludos

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

+ 46 = fifty six

Pybonacci