Estoy a punto de salir de Ingeniería, ya es mi último semestre, y si bien tengo muchas ganas de salir al mundo laboral, hay algunas cosas que extrañaré de mi paso por la universidad: los amigos y la TNE. Los que estudiamos en San Joaquín conocemos lo agradable que es tener una estación de metro literalmente en la entrada del campus. No obstante, desde que empezó a disminuir la crisis pandémica el año pasado (2021), me las di de deportista y comencé a moverme mucho en bicicleta. Todos los días que tenía clases intentaba ir en bicicleta (11 km de ida y otros 11 de vuelta), y creo que mejoré bastante mi estado físico. Cuando llevaba más semanas pedaleando, ya lograba llegar más rápido que si me fuese en metro.
Como va a subir el precio del pasaje de metro que tendré que pagar a partir del próximo año, empieza a ser atractivo el evaluar reemplazar el transporte público por el uso de la bicicleta. El principal problema es que muchas veces no se puede dejar la chancha en el lugar de destino de forma segura. Eso me ha hecho considerar seriamente pagar la suscripción al servicio más grande de bicicletas públicas que hay en Santiago: BikeSantiago (también conocido como BikeItau). Este servicio funciona con la modalidad de cicloestaciones: se retira una bicicleta en una estación y se devuelve en otra.
Al momento que escribo esto, la suscripción anual a las bicicletas naranjas cuesta algo así como $32.000, o sea poco más de $2.600 al mes. ¡Literalmente tres pasajes de metro en hora punta al mes! Por el precio, parece no-brainer, pero con esta visualización quiero ver si realmente vale la pena, comparando los niveles de servicio (es decir, cantidad de bicicletas que puedo tomar en una ubicación, día y hora determinada) en distintos lugares de la ciudad. Tal vez le sirva a alguien que esté pensando en suscribirse.
También consideré Uber Bikes / Scooters, pero con una tarifa de $500 por solo desbloquear y luego $160 por minuto, basta que el viaje dure 15 minutos para que convenga más pagar una mensualidad de BikeSantiago. Claro que las bicicletas de Uber son eléctricas, se pueden tomar y dejar en cualquier lugar, pero aún la cobertura es limitada y antes prefiero tomar una micro.
Acá hay un pantallazo de la aplicación de Bikesantiago centrado en el metro Pedro de Valdivia. Si bien este lugar tiene buena oferta de transporte público no-autopropulsado, Bikesantiago tiene la gracia que no cierra a las 11pm (hay micros, lo sé, pero sigamos la onda). Puedes sacar una bicicleta de una estación a cualquier hora del día, siempre que haya disponibilidad...
Y es justamente la disponibilidad lo que me preocupa. La foto es de las 8:30 pm de un día martes, y de las 17 estaciones que se ven en la foto, solo 4 tienen al menos una bicicleta. Y ojo con las que tienen una sola bici, puede que justo esa esté pinchada y tendremos que caminar a la cicloestación siguiente.
Por lo anterior, aproximadamente en abril de 2022 comencé a prestar más atención a la app, sobre todo para ver si existe alguna forma de que pueda obtener (y almacenar) los datos de disponibilidad de bicicletas por cicloestación, en todo momento del día y de forma automática.
Varios posts de Medium más tarde, con un emulador de Android que casi llena todo mi disco duro, y con un par de horas de programar en Google Apps Script, logré un proceso automático que guarda en Google Sheets todos los datos de disponibilidad de bicicletas, para cada estación, cada minuto del día. Y lo dejé correr. 7 meses.
El dataset que recopilé tiene 238 cicloestaciones con sus posiciones geográficas, y ~200 mil filas con la disponibilidad de bicicletas en cada estación. Como guardar la disponibilidad de cada estación una vez por minuto necesitaría casi 72 millones de filas en 7 meses, una optimización obvia es guardar solo los "deltas", es decir, registrar en qué momento una estación registró un cambio, y cuál es la cantidad de bicicletas que quedaron en esa estación en ese momento.
Cada estación tiene un nombre y una posición geográfica. Además, tienen un atributo de capacidad, que es la cantidad máxima de bicicletas que pueden estar en esa estación. Sin embargo, para efectos del análisis, no consideré la capacidad de las estaciones, ya que me importa más tomar una bici rápido sin tener que caminar tanto, que pedalear un par de metros más para llegar a una estación con disponibilidad si la primera opción estaba llena.
A partir del dataset descrito, diseñé una herramienta de visualización con algunos usuarios en mente. El primer usuario soy yo, o más bien una persona con curiosidad por conocer la dinámica de disponibilidad a lo largo de la semana, según hora del día y posición geográfica, potencialmente para evaluar el servicio antes de contratarlo. Otro usuario podría ser un analista de Bikesantiago, que busque insights sobre la dinámica de uso de la red de bicicletas, mejorar la redistribución, buscar incentivos para que los mismos usuarios devuelvan las bicicletas donde más se necesitarán, o para definir las mejores ubicaciones para nuevas estaciones en función de la demanda observada.
En términos de la clasificación de los datos, se puede encontrar de tipo ítem, atributo y posiciones. Una cicloestación es un ítem, y se caracteriza por atributos como su identificador (categórico tipo llave, determina los demás atributos), el nombre (categórico tipo valor), y la capacidad (cuantitativo, discreto, secuencial, no cíclico, de tipo valor). Además, tiene una posición geográfica, que es de tipo posición.
Nombre del atributo | Clasificación |
---|---|
Identificador | Categórico, tipo llave (compuesta) |
Nombre | Categórico, tipo valor |
Capacidad (la ignoraremos) | Cuantitativo, discreto, secuencial, no cíclico, tipo valor |
Posición geográfica | Posición, tipo valor |
Por otra parte, existen los datos (ítems) de la serie de tiempo, que son enlazados mediante el identificador de la estación, un timestamp (cuantitativo, discreto [en segundos enteros], secuencial y de tipo valor) y una disponibilidad instantánea de bicicletas (cuantitativo, discreto, secuencial, no cíclico, de tipo valor).
No obstante, la visualización no utiliza los datos de la serie de tiempo en bruto, sino una versión procesada que deriva ciertas propiedades. En primer lugar, agrega un atributo para el día de la semana y otro para la hora del día. Adicionalmente, usa un atributo al que me refiero como threshold (umbral), que es utilizado para determinar una probabilidad de la siguiente forma. Dada una estación, un día de la semana, una hora del día, y un umbral, se calcula la probabilidad de que la estación tenga una disponibilidad mayor o igual al umbral en esa ventana horaria, tomando como referencia el historial de disponibilidad de la estación en esa misma ventana. Por ejemplo, si el umbral es 5, y la estación tiene una disponibilidad de 5 o más bicicletas en el 90% de las veces cuando se revisó esa ventana horaria, entonces la probabilidad de disponibilidad es 0.9 para un umbral de 5.
Nombre del atributo | Clasificación |
---|---|
Día de la semana | Categórico, discreto, cíclico, tipo llave (compuesta) |
Hora del día | Categórico, discreto, cíclico, tipo llave (compuesta) |
Umbral | Cuantitativo, discreto, secuencial, no cíclico, tipo llave (compuesta) |
Identificador de la estación | Categórico, tipo llave (compuesta) |
Probabilidad de disponibilidad | Cuantitativo, continuo, secuencial, no cíclico, tipo valor |
En definitiva, los ítems a visualizar corresponden a una tupla identificada por una llave compuesta, que contiene un día de la semana, una hora, un umbral y un identificador de estación. Dicha llave compuesta tiene asociada la probabilidad de disponibilidad en la estación en esa ventana horaria, para el umbral dado.
La razón de incluir el umbral como parte de la llave compuesta es que permite tomar decisiones sobre la certeza de que la o las bicicletas que están disponibles en una estación se encuentren en buenas condiciones. Si fuese una visualización binaria, del estilo "hay bicicletas o no" con cierta probabilidad, dentro del "hay bicicletas" puede haber algunas en mal estado, y queremos evitar sorpresas. Por eso, considero importante que el usuario pueda definir su margen de seguridad.
En cuanto a la abstracción de tareas que busca soportar la visualización, se encuentran las tres siguientes:
Para la primera tarea, se busca que la herramienta permita conocer la posición geográfica de las 238 cicloestaciones en un marco de referencia que un usuario común pueda entender, como un mapa de la ciudad. En el caso de la segunda tarea, se pretende que el usuario sea capaz de centrarse en una zona de la ciudad, y determinar las cicloestaciones que se ubican a un radio "caminable" predeterminado, simulando una búsqueda de bicicletas en la zona. La funcionalidad de presentar también las tendencias horarias de disponibilidad dentro de la zona es lo que más necesita un usuario como yo, que ya conoce la cobertura a alto nivel de la red de estaciones, pero no tiene una idea clara de la disponibilidad de bicicletas en una zona en particular. Por último, para la tercera tarea, se busca que el usuario pueda comparar la disponibilidad de forma panorámica, pudiendo seleccionar o filtrar una hora, día y umbral como parte de los atributos de la llave compuesta.
La visualización tiene como capa base un mapa de Santiago, que se puede desplazar y acercar. Este mapa permite contextualizar las tres tareas que se pretenden abstraer, dado que sin esa referencia, no se puede hacer sentido de la ubicación de las estaciones. Cada estación se representa con una marca de tipo punto, y utiliza un canal bidimensional que codifica el atributo de tipo posición correspondiente. Esta marca satisface principalmente a los requerimientos de la primera tarea.
Para la segunda tarea, elegí un ítem de tipo área circular, que representa el radio que definimos como "caminable". La marca de círculo se desplaza junto con el cursor y es utilizable en cualquier posición y nivel de acercamiento, manteniendo el radio proyectado constante en aproximadamente 500m (arbitrario, pero razonable, unos cinco minutos caminando rápido). Además, este ítem tiene asociado un canal de color que codifica la probabilidad de encontrar al menos "umbral" bicicletas en cualquiera de las estaciones que se encuentran dentro del área circular. Este canal de color satisface principalmente a los requerimientos de la segunda tarea. Para complementar la codificación de color, que se sabe tiene menor fidelidad o exactitud, agregué una marca de tipo texto que muestra el valor de la probabilidad en formato numérico. Esta marca de texto se encuentra cerca del centro del círculo, y se actualiza en tiempo real. Si bien esto no agrega una dimensión de datos, considero que mantiene elevado el data-ink ratio, ya que es útil para el usuario que necesita más precisión. Una sutileza visual es que el color de la marca de posición de cada estación codifica si se encuentra dentro del área circular (color verde) o no (color rojo, por defecto).
Para satisfacer el requisito adicional de mostrar las tendencias presente en la segunda tarea, agregué una marca de punto en forma de gráfico de líneas, que muestra la probabilidad de disponibilidad de bicicletas en cualquier estación (posición en el eje vertical) a lo largo de todo el día seleccionado (posición en el eje horizontal). Este ítem se encuentra a la derecha del mapa y se actualiza en tiempo real, de forma que se puede analizar la tendencia de disponibilidad de bicicletas en la zona seleccionada. Para no eliminar la visualización en caso de que no haya estaciones dentro del área circular, reutilicé el espacio del gráfico para mostrar la tendencia de probabilidad promedio en todas las estaciones de la red, para el día y umbral seleccionado.
Como son muchas estaciones que se deben representar en forma panorámica, opté por no codificar la probabilidad de disponibilidad individual directamente en esta marca, sino utilizar una estrategia de agregación mediante HexBins. Cada hexágono es una marca de tipo área, y representa un grupo de estaciones que se encuentran dentro de su área. Esta marca es independiente del área circular utilizada para responder a la segunda abstracción de tareas, pero por consistencia también utiliza el canal de color para codificar la probabilidad de disponibilidad agregada. Un color rojo indica que la probabilidad de disponibilidad es baja, un color amarillo que es media, y un color verde que es alta. Dado que se muestra una panorámica de la probabilidad de disponibilidad a lo largo de toda la región de cobertura de Bikesantiago, esta codificación satisface los requerimientos de la tercera tarea. La capa de HexBins es estática (no interactiva directamente) y se genera en respuesta a las marcas de punto que codifican la posición de las estaciones. Se desactiva cuando se mueve o acerca el mapa, permitiendo al usuario encontrar un destino de análisis antes de realizar la agregación automática, con lo que minimiza la interferencia visual entre las tareas de exploración y comparación.
Cabe destacar que la probabilidad de disponibilidad dentro de un área se calcula considerando que cualquier estación en su interior podría satisfacer el umbral por sí sola. Es decir, si el umbral es 5 bicicletas y hay 3 estaciones en el área, entonces la probabilidad se calcula observando todas las ventanas de tiempo en las que hay al menos 5 bicicletas disponibles en cualquiera de las 3 estaciones. Nuevamente, si durante 50% de las ventanas de tiempo hay 5 bicicletas disponibles en al menos una de las 3 estaciones, entonces la probabilidad de disponibilidad es 0.5 para dicha configuración hora-día y un umbral de 5.
La implementación más reciente se encuentra publicada en https://bikesantiago.coloro.cl.
Acabo de contratar el plan anual. Puedes conseguirlo acá con mi código de referidos (broma).