Skip to content

El proyecto de GoMotion consiste en la creación de un sistema de predicción de picos de movilidad. Se implementan modelos predictivos que anticipen flujos con la finalidad de mejorar la red de movilidad local.

Notifications You must be signed in to change notification settings

TheSpaceHub/GoMotion

Repository files navigation

Logo GoMotion

Predicción de picos de movilidad en Barcelona

El proyecto de GoMotion consiste en la creación de un sistema de predicción de picos de movilidad utilizando datos históricos de Telefónica combinados con datos públicos como son archivos meteorológicos y calendarios de eventos. Se implementan modelos predictivos que anticipan flujos de movilidad con la finalidad de mejorar la red de movilidad local.

For the English version of this readme, go here.

Importante

  • GoMotion ha sido creado con la intención de hacer una predicción de la movilidad en Barcelona para poder detectar fuertes picos y comprender de dónde vienen. La falta de datos precisos e útiles sobre el transporte público en Barcelona hace que sea complicado intentar proponer cambios en el transporte para lidiar con éstos. Sin embargo, hemos creado un modelo capaz de predecir picos de movilidad con gran precisión que hace que, teniendo datos de calidad sobre el transporte público de Barcelona (como proporciones de trayectos en transporte privado / público, capacidades exactas de autobuses y metro, número diario de buses/metro de cada línea, etc...), sea fácil proponer cambios en éste para hacer frente a dichos picos.
  • Para realizar un proyecto realmente útil es importante construir una buena base, por ello hemos creado un documento mathematical_model.pdf cuyo objetivo es crear una abstracción matemática de la ciudad que permita modelar las propiedades reales a partir de un conjunto de datos proporcionados.
  • El alcance predictivo del programa es el estipulado de 7 días. Una implementación completa requeriría una conexión con los datos de Telefónica a tiempo real (granularidad diaria). Puesto que esto no es posible, la aplicación incluye un proceso de "relleno de datos", donde se crean datos utilizando el modelo predictivo desde la última fecha con datos determinados (31 de agosto de 2025) hasta el día de ejecución. Esto provoca una acumulación de error a medida que la fecha de predicción se aleja de la última estipulada (dado que hacemos predicciones sobre predicciones), por lo que los datos que se observan pueden presentar discrepancias mayores con la realidad que las medidas por las herramientas del programa.

Requisitos

  • Python 3.12+
  • Conexión a internet
  • Acceso a la carpeta output_limite_legal proporcionada por Telefónica (de no ser el caso, se pueden generar datos usando example_data.py)
  • Acceso a los archivos barris.csv, events.csv y holidays.csv
  • Una llave de API para Gemini

Instalación

Para poder utilizar GoMotion, es necesario crear un entorno virtual y descargar las librerías necesarias.

  1. Crear el entorno virtual desde la raíz: python -m venv .venv
  2. Activar el entorno virtual:
  • MacOS / Linux: source .venv/bin/activate
  • Windows PowerShell / Windows Cmd: .venv\Scripts\Activate.ps1 / .venv\Scripts\activate
  1. Descargar librerías pip install -r requirements.txt
  2. Añadir API key en .env: GEMINI_API_KEY="key"
  • Nota: dependiendo del tier de Gemini API que tenga el usuario, es posible que el regenerado repetido del programa consuma el límite de requests.

Estructura del Proyecto

GoMotion/
├── data/                   
│   ├── output_limite_legal # Datos proporcionados por Telefónica
|   └── barris.csv          # Datos públicos de OpenData BCN
│   └── events.csv          # Registro de eventos
|   └── holidays.csv          # Registro de festivos sacados del ajuntament de Barcelona 
│
├── media/               
|    └── analysis.png   
│    └── GoMotionLogo.png    
|    └── GoMotionShortLogo.png  
|    └── GoMotionShortLogo.ico 
|    └── barri_list.png
|    └── daily_metrics.png
|    └── general_stats.png
|    └── heatmap.png
|    └── model_analysis.png
│
├── stats/   
|   ├── stats/                  
|   |     └── statistics_day_of_the_week.py # Exceso de intensidad promedia por día de la semana
|   |     └── statistics_month.py           # Exceso de intensidad promedia por mes del año
|   |                
│   ├── llm_scraper.py      # Extracción de eventos y festivos con web scrapping
│   └── barri_manager.py    # Creación del "mapa/grafo" con los barrios de Barcelona
|   └── metadata_manager.py # Metadatos 
|   └── stats.py            # Cálculo de estadísticas útiles
|   └── xgb_model.py        # Modelo de xgb para la predicción
|   └── event_encoder       # Conversión de eventos para una mejor predicción
|   └── hyperparameter_optimizer.py # Entrenamiento y optimización de modelo de predicción
|   └── peak_classifier.py  # Definición y clasificación de picos
|   └── data_filler.py      # Realizar Predicciones (1 semana)
|   └── meteo.py            # Archivo y predicción meteorológica
|   └── intensities.py      # Modelo matemático para definir las intensidades
|   └── pipeline.py         # Pipeline y archivo principal del proyecto
|   └── dashboard.py        # Visualización con Streamlit
|   └── example_data.py     # Generación de datos de prueba simulando datos reales
│
├── .env                    # Variables de entorno (API Keys - No subir al repo)
└── requirements.txt        # Dependencias del proyecto
└── mathematical_model.pdf  # Documento con fundamentos matemáticos

Ejecución

Para acceder a todas las funciones del proyecto es suficiente con ejecutar el pipeline.
Desde la raíz del proyecto MacOS / Linux: python3 src/pipeline.py, Windows Cmd: python src/pipeline.py.

  • Si no se dispone de la carpeta output_limite_legal, se debe ejecutar anteriormente el archivo src/example_data.py para crear los datos de ejemplo.
  • Nota: Es normal que la primera vez que se ejecute pipeline.py tarde un buen rato. El programa tiene que hacer una serie de procesos con costes computacionales relativamente alto. Sin embargo, una vez ejecutado, los archivos se guardan y sólo necesitan actualizarse poco a poco, lo que reduce drásticamente el tiempo de espera.

1. Preparación de los datos

1.1. Limpieza y organización de datos

Una vez descargados los datos movilidad entre barrios proporcionados por Telefónica, eliminaremos las columnas irrelevantes para nuestro proyecto, y nos quedaremos únicamente con las columnas siguientes: day, barrio_origen_name, barrio_destino_name y viajes.
Utilizaremos el dataset resultante y el modelo explicado en el pdf adjunto para crear un nuevo dataset con las siguientes columnas: day, barri, intensity.
Estas funciones se implementan en los archivos barri_manager.py y intensities.py.

1.2 Archivo de Eventos, Festivos y Meteorología

Para mejorar la precisión de nuestro modelo utilizaremos datos históricos de eventos, festivos y meteorología.
Los archivos de eventos y festivos han sido recopilados a mano y se encuentran en data/events.csv y data/holidays.csv respectivamente.
Cada evento tiene asociados una fecha, una categoría, una lista de barrios en los que tiene lugar, y un impacto (del 1 al 5) relativo a su categoría. Los festivos únicamente tienen asociada una fecha.

Para recopilar datos meteorológicos utilizaremos la API de OpenMeteo, en el archivo meteo.py. Por simplicidad y porque creemos que es lo mejor para el modelo, recopilaremos para cada día, únicamente el nivel de lluvia y las temperaturas máxima y mínima.

1.2.1. Eventos Seleccionados

También por simplicidad, y porque es prácticamente imposible tener controlados todos los eventos de una ciudad tan activa como Barcelona, hemos seleccionado para nuestro análisis los eventos que creemos más relevantes. Es decir:

  • Eventos del Estadio Olímpico
  • Partidos locales del Fútbol Club Barcelona
  • Festivales de música: Primavera Sound, Crüilla y Sonar
  • Eventos de Running: Cursa del Corte Inglés y Zurich Maratón de Barcelona
  • Eventos de la Fira de Barcelona
  • Fiestas Populares: Sant Jordi, La Diada y La Mercè

1.3. Metadatos

A lo largo del uso del programa hay información que necesita compartirse entre varios archivos y entre sesiones que no corresponde a datos en sí. Esta información la denominamos metadatos y la almacenamos en data/metadata.py (archivo creado automáticamente). No conviene modificar manualmente los metadatos, pues pueden haber comportamientos inesperados.

1.4. Dot-env

Este proyecto hace uso de la API de Google Gemini. Su utilización está sujeta a la posesión de una llave que deberá almacenarse en un archivo .env en el mismo directorio que el resto de carpetas.

2. Predicción de Picos de Movilidad

GoMotion es capaz de predecir las intensidades de cada barrio con 7 días de antelación.

2.1. Datos Futuros de Meteorología

De la misma manera que para los datos meteorológicos históricos, utilizaremos la API de OpenMeteo (en meteo.py) para obtener las predicciones de temperatura y lluvia de la semana siguiente.

2.2. Datos Futuros de Festivos y Eventos

Para conocer los eventos y los de la semana siguiente hemos creado un sistema de web-scrapping. En llm_scrapper.py, utilizamos playwright y bs4 para obtener el texto de las páginas web de nuestro interés (mencionadas en el apartado 1.2.1), y un LLM (gemini) que formatea los eventos y festivos encontrados para dejarlos listos para entrenar al modelo.

2.3. Codificación de Eventos

Con la finalidad de extraer la información más importante y usarla en nuestro modelo de predicción, codificamos los eventos de un día en un barrio en un espacio latente de 5 dimensiones. Para ello entrenamos 2 modelos: un codificador y un descodificador. Esta arquitectura permite entrenar un modelo usando los eventos como input y validation al mismo tiempo, pues el descodificador debería actuar como una función inversa y llevar el vector del espacio latente de vuelta al espacio de eventos.

Una vez tenemos el modelo entrenado, guardamos la primera mitad del modelo entrenado en models/encoder.keras. Además, codificamos los eventos hasta la fecha necesaria (una semana a partir del día en el que se ejecuta el programa) usando el codificador. El resultado se guarda en data/encoded_events.csv.

2.4. Creación de Modelo de Predicción

La predicción de los datos se hará usando un modelo de extreme gradient boosting (XGBoost), dado que es una arquitectura que:

  • permite la fácil integración de características categóricas
  • tiene documentación y uso extensos
  • es una de las más adecuadas para tratar datos de naturaleza tabular (todos nuestros datos se estructuran en archivos .csv)

La definición del modelo y las herramientas para su entrenamiento y su optimización se encuentran en el archivo hyperparameter_optimizer.py.

A continuación están las características utilizadas y su descripción:

Característica Tipo Descripción
barri Categórica Nombre del barrio
temperature_2m_max Numérica Temperatura máxima para el día (ºC)
temperature_2m_min Numérica Temperatura mínima para el día (ºC)
precipitation_sum Numérica Suma de mm de precipitación en el día
is_holiday Booleana Si el día es festivo o no
month_cat Categórica Nombre del mes
day_cat Categórica Día de la semana
lag_7 Numérica Intensidad calculada hace 7 días
lag_14 Numérica Intensidad calculada hace 14 días
lag_21 Numérica Intensidad calculada hace 21 días
lag_28 Numérica Intensidad calculada hace 28 días
dt_7_w1 Numérica Derivada discreta de la semana más reciente: (lag_7 - lag_14) / 7
dt_7_w2 Numérica Derivada discreta de la segunda semana más reciente: (lag_14 - lag_21) / 7
enc1 Numérica Coordenada 1 de la codificación de los eventos para el día en el barrio especificado
enc2 Numérica Coordenada 2 de la codificación de los eventos para el día en el barrio especificado
enc3 Numérica Coordenada 3 de la codificación de los eventos para el día en el barrio especificado
enc4 Numérica Coordenada 4 de la codificación de los eventos para el día en el barrio especificado
enc5 Numérica Coordenada 5 de la codificación de los eventos para el día en el barrio especificado

El archivo permite entrenar el modelo en una variedad de hiperparámetros. Para ello implementa un grid search personalizado: dada una colección de rangos de hiperparámetros, se entrenan modelos para todos los elementos de su producto cartesiano y se guarda aquel con mayor precisión (evaluada según los aciertos en la predicción). Los hiperparámetros que se pueden ajustar son:

  • Base de los pesos: el modelo XGBoost asigna unos pesos a los errores de cada muestra según su z-score con la siguiente formula: $weight = max(1, base ^{\text{z-score}})$. Aumentar el hiperparámetro base pondera más fuertemente los errores en días con movilidad excesiva.
  • Learning rate: se permite modificar el learning rate para variar el ritmo de convergencia y explorar nuevos mínimos. El valor especial None implementa el siguiente schedule:
Ronda de corte Learning rate
0 0.1
100 0.001
150 0.0001

Cuando se escoge el mejor modelo, se guarda en models/regressor.joblib.

3. Dashboard y Visualización

Con el fin de entender mejor las predicciones, hemos implementado un dashboard utilizando streamlit.

3.1. Carga de Datos

Nada más entrar al dashboard se llamará a la función fill_data(), que se encuentra en data_filler.py. Así nos aseguramos de tener los datos y las predicciones de los días que nos interesan.

3.2. Métricas Diarias

Tendremos la opción de seleccionar una fecha. Una vez seleccionada, se nos mostrarán algunas métricas relevantes de ese día: temperatura, lluvia, eventos, festivos y el tráfico total del día. Además obtenemos una comparación histórica de estos valores. En concreto:
Temperatura y Precipitaciones: Comparación con la media de los últimos 30 días.
Eventos: Comparación con la media de eventos diarios que hubo en los últimos 30 días.
Tráfico Total: Comparación con la media de los 4 últimos días con el mismo día de la semana (por ej. Domingo)

plot

3.3. Tabla de Barrios

Para el día seleccionado se nos mostrará una tabla con, para cada barrio, su intensidad, la media histórica de esta, su z-score, su densidad (intensidad/superficie), y el típo de pico frente al que estamos (definidos en matematical_model.pdf y peak_classifier.py).

plot

3.4. Mapa de Calor

Además se mostrará un mapa de calor de las intensidades de cada barrio. Estas intensidades son relativas al barrio, es decir: se considera que hay un pico cuando el valor se aleja mucho de lo que suele haber en ese barrio. Podremos hacer clic en un barrio en concreto para seleccionarlo.

plot

3.5. Análisis Detallado por Barrio

Una vez seleccionado un barrio en el mapa, obtendremos una serie de gráficas que explican cómo afecta cada variable a la intensidad histórica de ese barrio. En concreto:

  • Impacto festivo/laborable
  • Impacto de cada tipo de evento
  • Impacto del día de la semana
  • Impacto del mes
  • Impacto de la precipitación

plot

3.6. Análisis del Modelo

Encontraremos un análisis detallado del modelo, para tener una visión más general de cuáles son los parámetros que afectan en mayor medida a la intensidad de la movilidad en Barcelona. Además, podremos ver el porcentaje de precisión de picos acertados del modelo, el porcentaje de picos subestimados y el porcentaje de picos sobrestimado.

plot

3.7. Estadísticas de todos los barrios

Finalmente, se podrá visualizar las siguientes estadísticas de todos los barrios: exceso de intensidad promedio como porcentaje según el día de la semana y exceso de intensidad promedio como porcentaje según el mes del año.

plot

Autores

  • Javier Badesa Pérez
  • Alexander Cameron Hall Parrilla
  • Oscar Senesi Aladjem
  • Dan Manuel Vancea Boros

About

El proyecto de GoMotion consiste en la creación de un sistema de predicción de picos de movilidad. Se implementan modelos predictivos que anticipen flujos con la finalidad de mejorar la red de movilidad local.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •