Creando un bot de Twitter con el estado de la vacunación COVID-19

9 min
Creando un bot de Twitter con el estado de la vacunación COVID-19

Vacunas COVID Twitter bot

Bot de Twitter que informa diariamente del estado de vacunación en España contra la COVID-19.

PythonTwitter API

No es la primera vez que hablo de Coronavirus en esta web. Al poco de iniciar la pandemia, traté el caso de AliPay Health Code, el sistema de códigos QR en China que determinaba lo que podías o no hacer según tu exposición al virus. Más adelante, al terminar el curso en la universidad, traté de sacar algunas conclusiones tecnológicas de la pandemia. Hoy pretendo añadir un artículo más a esta serie con lo que secuencialmente tiene más sentido después de los dos posts anteriores: la vacunación. Hoy hablaremos de vacunas, bots de Twitter, modelos de predicción y sobre todo, de lo difícil que nos lo pone el gobierno a los que desarrollamos.

No obstante, este no será el último artículo que tengo pendiente sacar sobre este tema. Antes de verano intentaré exponer por qué no se le ha sacado todo el partido a la aplicación Radar COVID en España. Creo que puede salir un artículo interesante, así que estad atentos.

Contexto de la COVID-19

1 de enero del 2020. A ojos de casi cualquier persona, este nuevo año no prometía nada inesperado. Ya nos llegaban por aquel entonces algunas noticias e imágenes de China, más concretamente de la provincia de Hubei, donde al parecer un nuevo virus desconocido estaba causando cierto pánico en la población. Era evidente, pero en Europa, y particularmente en España, no lo vimos venir. No hay más que recordar las palabras a finales de enero de Fernando Simón, director del Centro de Coordinación de Alertas y Emergencias Sanitarias: "España no va a tener, como mucho, más allá de algún caso diagnosticado". ¿Era imposible darse cuenta de que algo así iba a pasar? Gates en 2015 ya auguraba que no estábamos preparado y que nos pillaría totalmente desprevenidos. Taleb, por su parte, dice que la pandemia no es un cisne negro y que ha sido un evento predecible y cuyo riesgo tendríamos que haber tenido en cuenta.

El día 14 de marzo de 2020, después de una serie de actos multitudinarios de diferentes índoles, cuya relación con la propagación del virus se sigue discutiendo, se declara el Estado de Alarma por primera vez en España. Lo que en un principio iban a ser 15 días, pronto se convirtieron en 30, después en 45, después en dos meses, hasta que finalmente, a mediados de mayo, se comenzaron a reducir las restricciones de movilidad y socialización.

Aunque la primera ola nos pilló totalmente desprevenidos, luego vino una segunda después, la más suave de las tres que llevamos a marzo de 2021. Por último, después de Navidad, una tercera ola irrumpió con fuerza en nuestro país, dejando la mayor cifra de personas contagiadas registradas en nuestro país.

Desde los primeros días de la pandemia, siempre se ha planteado que la única forma de salir de este círculo vicioso era con el desarrollo de una vacuna contra la COVID-19. Al principio, muchos expertos desconocían si un fármaco podría lograr la inmunidad como se ha conseguido con otras enfermedades virulentas como la polio. Miles de laboratorios al rededor del mundo comenzaron a trabajar en una posible vacuna de diferentes formas y maneras. ¿Hubiesen acelerado el proceso si todas ellas hubiesen trabajado conjuntamente? Nunca lo llegaremos a saber, pero la simple existencia de la competencia entre ellas puede haber sido un factor clave.

Pronto, Pfizer, una de las compañías farmacéuticas más importantes del mundo, conocida por haber sido propietaria de la patente de la Viagra hasta hace poco. Siguiéndole los pasos, también tuvimos a la compañía estadounidense Moderna, cuya vacuna también está basada en ARM mensajero, pero es de las primeras que desarrolla y distribuye la firma. Esta es la razón por la que la bolsa ha reaccionado de forma diferente con las acciones de ambas empresas. Pero, ¡volvamos al tema!, que como siempre, me voy por las ramas.

Finalmente, el 27 de diciembre de 2021, Araceli se pone la primera vacuna en España, comenzando así la campaña de vacunación en este país. Veintitrés días más tarde, el 18 de enero, se ponen las segundas dosis de la vacuna de Pfizer, es decir, que se completaron las primeras pautas completas de vacunación. Pero, ¿cómo funciona la vacunación contra la COVID-19? ¿Es similar a otras campañas?

Cómo funciona la vacunación

En un primer momento, los países miembros de la Unión Europea dependerán de esta supraorganización para la compra y distribución de vacunas. No obstante, con el tiempo, y debido a la falta de vacunas, algunos países miembros han comenzado sus propios negociaciones directamente con las farmacéuticas. España, de momento, no es uno de esos países y no se espera que tome acciones de manera independiente en el corto plazo.

A 18 de marzo de 2020, las vacunas que se han administrado o que se tiene pensado administrar son las siguientes:

Captura de pantalla 2021-03-24 a las 22.01.33.png

No obstante, por ahora, únicamente se han administrado vacunas de Pfizer, Moderna y AstraZeneca. Estas últimas se vieron envueltas en una controversia al detectar evidencias de que la vacuna podría causar trombos, y como consecuencia, la muerte de los pacientes. En España, la vacunación con esta vacuna se suspendió el 15 de marzo y una semana y media después, al no encontrar evidencias claras de que la vacuna no fuese segura, se volvió a incluir en la campaña de vacunación.

Como se puede observar en la ilustración anterior, obtenida del Ministerio de Sanidad, se puede observar que la gran mayoría de las vacunas necesitan dos dosis para que considere efectiva. El tiempo que debe pasar entre esas dosis depende de la vacuna, pero por ejemplo, en la de Pfizer, el tiempo de espera es de unas 3 semanas. La única que rompe estos esquemas es la de J&J, de la que sólo es necesaria una dosis para completar la pauta.

En España, la vacunación se divide en 3 etapas:

Captura de pantalla 2021-03-24 a las 22.15.03.png

La primera etapa, que comenzó en diciembre con la inoculación de la primera vacuna. A 18 de marzo, todavía no se ha finalizado esta primera fase, aunque se encuentra en sus últimos días. Por otro lado, la etapa dos se inició en febrero de 2021, paralelamente a la primera, y una de las más importantes. Por último, en junio de 2021 comenzará la tercera etapa, en la que se vacunará el resto de la población no vulnerable o expuesta.

Desarrollo del bot

Nos ponemos manos a la obra. Una vez entendido el contexto y cómo funciona el proceso de vacunación, paso a explicar cómo se desarrolló el bot:

Código en GitHub

Quiero avisar que el código que se ve en este artículo son porciones obtenidas del script que podéis encontrar en el enlace anterior. Por eso mismo, es posible que hay ciertas funciones y/o variables que no entenderéis, ya que estarán sacadas de contexto. Para más información, consulta el script completo en el repositorio.

Por qué Python

Quizás la primera pregunta que nos hacemos a la hora de comenzar a escribir un script como este es cuál el lenguaje de programación que usaremos. Como ya habréis intuido por el título de esta sección, terminé decantándome por Python por las siguientes razones:

  • Tenía ganas de usarlo en un proyecto real
  • Cuenta con una potente librería para utilizar la API de Twitter
  • Existen varias librerías para el análisis de datos
  • Su sencillez

No me he puesto a estudiarlo, pero estoy casi seguro que este script también se podría haber hecho en un servidor con JavaScript y Node JS. No obstante, opino que la mayor dificultad que encontraréis será a la hora de encontrar un buen módulo para el análisis de datos

Solicitar a Twitter el permiso para hacer un bot

Antes de poder utilizar la API de Twitter, necesitas dar de alta tu cuenta en la plataforma de desarrolladores (developer.twitter.com). Para registrarte, tendrás que cumplimentar un formulario en inglés en el que tendrás que describir el uso que vas a hacer de la API:

Captura de pantalla 2021-03-20 a las 20.52.30.png

La libraría que usaremos para publicar tuits es Tweepy. En su documentación se explica perfectamente cómo funciona. No obstante, lo primero que tenemos que hacer es inicializar el cliente con las claves que nos facilitará Twitter una vez nos hayan aceptado la solicitud:

auth = tweepy.OAuthHandler(TW_CONSUMER_KEY, TW_CONSUMER_SECRET)
auth.set_access_token(TW_ACCESS_TOKEN, TW_ACCESS_TOKEN_SECRET)
api = tweepy.API(auth)

Ahora ya podemos usar Tweepy para publicar el tweet, concretamente el que informa de la vacunación, el porcentaje con la pauta completa y la fecha estimada a nivel nacional:

hilo = api.update_status(tweet)

Es importante que guardemos el resultado de la llamada en un variable, en este caso llamada hilo, porque la usaremos a continuación.

A parte de los datos nacionales de toda España, también se publica el porcentaje de vacunación de cada una de las comunidades y ciudades autónomas. Twitter solo nos deja incluir 280 caracteres por cada tuit, por lo que tenemos que crear un hilo, donde en cada respuesta pondremos los datos de 5 comunidades. Para esto, usaremos la variable hilo, que nos permitirá anidar respuestas para crear un hilo:

aux = 0
respuesta = ''
for c in comunidades:
    if (aux <= 4):
        aux += 1
        respuesta = respuesta + c
    else:
        hilo = api.update_status(status=respuesta, in_reply_to_status_id=hilo.id, auto_populate_reply_metadata=True)
        aux = 1
        respuesta = c
hilo = api.update_status(status=respuesta, in_reply_to_status_id=hilo.id, auto_populate_reply_metadata=True)

Obtención de los datos

Quizás una de las tareas más ardua de todas en el desarrollo de este bot ha sido la obtención de datos. A diferencia de lo que esperaríamos de un servicio tan importante como el Ministerio de Sanidad, los datos de vacunación solo se pueden obtener de una hoja de cálculo subida los días laborales a última hora con un nombre diferente a la web del Ministerio.. Lo primero que haremos entonces es obtener los datos:

fecha_url = today.strftime('%Y%m%d')
url = 'https://www.mscbs.gob.es/profesionales/saludPublica/ccayes/alertasActual/nCov/documentos/Informe_Comunicacion_' + fecha_url + '.ods'
r = requests.get(url, allow_redirects=True)
open('data.ods', 'wb').write(r.content)
ods = get_data("data.ods")
datos = json.loads(json.dumps(ods, default=convertidor_fecha, indent=4))

El formato del nombre de los archivos es el año, mes y día del que se quieren obtener los datos sin ningún tipo de separación. De esta forma, solo tenemos que hacer una petición GET a esa dirección y descargar el contenido en un fichero .ods, hoja de cálculo de Open Office. Una vez guardada la hoja de cálculo, la abrimos y parseamos toda la información para poder utilizarla como en un diccionario. El convertidor_fecha sirve para parsear las fechas y que podamos tratarlas de forma correcta posteriormente.

Para obtener los datos de este formulario, solo tenemos que acceder a ellos como si fuera un diccionario de Python. Hay que tener en cuenta, que lo primero que hay que hacer es entrar dentro del libro Comunicación, donde se encuentran los datos de vacunación. Luego, podemos acceder a la última fila, donde se encuentran los valores a escala nacional:

array_totales = datos[u'Comunicación'][-2]
dosis_administradas = array_totales[-3]
porc_admin = round((dosis_administradas/float(POBLACION_ESP)*100), 2)
personas_vacunadas = array_totales[-1]
porc_vac = round((personas_vacunadas/float(POBLACION_ESP)*100), 2)

Barra de progreso

Para la barra de progreso es más necesario crear una función que en ningún otro caso, ya que se utiliza tanto para los datos nacionales, como para los datos de cada comunidad. En este caso, la barra de progreso he decidido hacerla con bullets (○ y ●), pero se puede hacer de muchas otras formas. Hay que tener en cuenta que la barra debe ser de una longitud total no muy larga, ya que si no se podría truncar en algunos dispositivos con pantalla pequeña.

def obtener_barra_progreso(porc_vac):
    simbolo_vacio = '○'
    simbolo_lleno = '●'
    return (int(porc_vac/DIV_BARRA_PROGRESO)*simbolo_lleno) + ( int((100/DIV_BARRA_PROGRESO) - int(porc_vac/DIV_BARRA_PROGRESO)) *simbolo_vacio)

Fecha de estimación

Por último, una de las funcionalidades que más me han preguntado y que que más controversia va a generar: la fecha de estimación que aparece en el tuit. Para lograrlo, el bot almacena en una base de datos de RestDB.io todos los resultados de vacunación desde el inicio.

Para hacer la estimación, usaremos regresión lineal. Sí, ya sé que no es la mejor forma de hacerlo, pero es la única que he logrado aplicar por ahora. De momento la vacunación está siguiendo una tendencia lineal, por lo que la estimación debería ser bastante correcta. No obstante, cuando en unos meses se comience a recibir un mayor número de vacunas, la tendencia se volverá exponencial y la estimación será más incorrecta.

Para realizar la estimación, se utiliza la librería sklearn, que incluye la función linear_model que nos permite trabajar con modelos de regresión lineal.

def obtener_fecha_estimada(porc_buscado, today):
    # Obtenemos los datos
    datos = obtener_dias_porcentajes()

    # Declaramos los arrays
    x = np.array(datos['porcentajes']).astype(np.float64).reshape((-1, 1))
    y = np.array(datos['dias']).astype(np.float64)

    # Inicializamos el modelo lineal y añadimos los datos
    model = linear_model.LinearRegression()
    model.fit(x, y)

    # Realizamos la predicción de dias
    x_predict = [[porc_buscado]]
    y_predict = int(model.predict(x_predict)[0])

    # Calculamos la fecha estimada
    fecha_est = FECHA_INICIO_VACUNACION + datetime.timedelta(y_predict)

    # Formulamos el strig con la fecha estimada
    fecha_est_str = str(fecha_est.day) + ' de ' + obtener_mes_esp(fecha_est.month) + ' del ' + str(fecha_est.year)
    
    return fecha_est_str