Saltar al contenido
Almar Ramos Curto

§ Caso de estudio · Académico

SportStats

Mi trabajo de fin de grado: datos deportivos y mensajes cortos con recomendaciones TF-IDF y k-NN. 10/10 con matrícula de honor.

Rol
Desarrollo en solitario (académico)
Periodo
2025
Estado
Completado
Código
Repositorio público

Stack

  • Python
  • Flask
  • scikit-learn
  • MySQL
  • SQLAlchemy
  • pandas
  • BeautifulSoup
  • Bootstrap

Contexto

SportStats es mi trabajo de fin de grado. Es una plataforma web que reúne datos deportivos con un flujo de mensajes cortos parecido a X, donde los usuarios publican, y que recomienda contenido a cada usuario.

Es un proyecto que realicé yo solo y el código es público.

Datos

La plataforma se alimenta de dos fuentes. API-SPORTS aporta datos deportivos a través de su API, y los datos de atletismo se extraen de World Athletics con BeautifulSoup, con pandas para tratar los datos.

Las dos fuentes son externas y no las controlo, así que una caché en disco con caducidad limita el número de llamadas que se les hacen.

Los datos de la aplicación están en MySQL, con acceso mediante SQLAlchemy.

Recomendaciones

El contenido se recomienda con TF-IDF y k vecinos más cercanos, implementados en scikit-learn. TF-IDF convierte cada texto en un vector ponderado, y los vecinos se buscan con distancia coseno y búsqueda por fuerza bruta. El modelo ajustado se guarda con joblib, para no tener que construirlo de nuevo en cada arranque.

La distancia coseno compara la dirección de dos vectores y no su longitud, de modo que un mensaje largo y uno corto sobre el mismo tema pueden quedar cerca. Por eso encaja mejor con texto que una distancia euclídea simple.

La fuerza bruta da vecinos exactos y no necesita un índice que mantener sincronizado. Solo miraría un índice aproximado si el volumen de contenido lo pidiera.

Notas de ingeniería

El backend es Flask. Las cuentas y los formularios usan Flask-Login, Bcrypt para el hash de contraseñas y WTForms para la validación, y la interfaz está hecha con Bootstrap. Las contraseñas se guardan con hash y no en claro, y los datos de los formularios se validan en el servidor antes de usarse.

Resultado

El proyecto obtuvo una calificación de 10/10 con matrícula de honor.

Límites y qué haría después

El repositorio público no tiene pruebas automáticas ni CI. Es la carencia principal, y pesa más donde el comportamiento es delicado: la ingesta de datos y el recomendador.

Si volviera a él, empezaría por ahí, con pruebas de la salida del extractor y de las recomendaciones sobre un conjunto de datos pequeño y fijo, y un flujo de CI que las ejecute.