Skip to content

Latest commit

 

History

History
407 lines (299 loc) · 16.2 KB

File metadata and controls

407 lines (299 loc) · 16.2 KB

Documentación: Sistema de Recomendación de Ciudades con KNN

1. Introducción

Este script implementa un sistema de recomendación de ciudades basado en el algoritmo K-Nearest Neighbors (KNN). El sistema utiliza la métrica de distancia coseno para encontrar las ciudades más similares a las preferencias de un usuario, representadas mediante un vector de características numéricas.

Propósito

El recomendador permite:

  • Entrenar un modelo con una base de datos de ciudades y sus características
  • Guardar el modelo entrenado para uso posterior
  • Generar recomendaciones personalizadas basadas en las preferencias del usuario

Algoritmo

El script utiliza KNN (K-Nearest Neighbors) con:

  • Métrica: Distancia coseno (similaridad entre vectores)
  • Algoritmo: Búsqueda exhaustiva (brute force)
  • Normalización: MinMaxScaler para escalar características al rango [0, 1]

2. Arquitectura y Funcionamiento

Clase Principal: CityRecommender

La clase CityRecommender encapsula toda la lógica del sistema de recomendación.

Componentes Principales

  1. Modelo KNN (self.model)

    • Instancia de NearestNeighbors de scikit-learn
    • Configurado con métrica coseno y algoritmo brute force
    • Se entrena con los vectores normalizados de las ciudades
  2. Scaler (self.scaler)

    • Instancia de MinMaxScaler para normalización de características
    • Normaliza todas las características al rango [0, 1]
    • Es crítico usar el mismo scaler entrenado tanto para entrenamiento como para predicción
  3. Base de Datos (self.cities_df)

    • DataFrame de pandas que contiene toda la información de las ciudades
    • Incluye nombres de ciudades y todas sus características
    • Se guarda junto con el modelo para permitir recuperar información completa

Flujo de Trabajo

Entrenamiento:
CSV → Leer datos → Extraer características numéricas → Normalizar → Entrenar KNN → Guardar modelo

Predicción:
Cargar modelo → Normalizar características usuario → Buscar vecinos más cercanos → Calcular scores → Retornar recomendaciones

3. Métodos Principales

fit(csv_path: str)

Lee un archivo CSV, extrae las características numéricas, entrena el scaler y el modelo KNN.

Proceso:

  1. Valida que el archivo CSV exista
  2. Lee el CSV en un DataFrame
  3. Filtra solo las columnas numéricas (automáticamente detecta las 10 características)
  4. Entrena el MinMaxScaler con los datos
  5. Normaliza los vectores de ciudades
  6. Entrena el modelo KNN con los vectores normalizados

Parámetros:

  • csv_path: Ruta al archivo CSV con los datos de ciudades

save_model(filepath: str)

Guarda el estado completo del recomendador en un archivo .pkl usando joblib.

Contenido guardado:

  • Modelo KNN entrenado
  • Scaler entrenado (con parámetros de normalización)
  • Base de datos completa (DataFrame con todas las ciudades)

Parámetros:

  • filepath: Ruta donde guardar el archivo .pkl

load_model(filepath: str)

Carga un modelo pre-entrenado desde disco y restaura todo el estado interno.

Parámetros:

  • filepath: Ruta al archivo .pkl del modelo

Importante: El modelo debe haber sido guardado previamente con save_model().

recommend(person_features: list, n_recommendations: int = 3)

Genera recomendaciones basadas en las características proporcionadas por el usuario.

Proceso:

  1. Convierte las características a un vector numpy
  2. Normaliza el vector usando el scaler entrenado (sin re-entrenar)
  3. Busca los n_recommendations vecinos más cercanos
  4. Calcula el match_score como (1 - distancia) para obtener un score de similitud
  5. Retorna un DataFrame con las ciudades recomendadas y sus scores

Parámetros:

  • person_features: Lista de 10 valores numéricos representando las características del usuario
  • n_recommendations: Número de recomendaciones a retornar (por defecto: 3)

Retorna:

  • DataFrame con el nombre de la ciudad (primera columna) y el match_score (0-1, donde 1 es máxima similitud)

4. Uso del Script

El script se ejecuta desde la línea de comandos y soporta dos subcomandos principales.

Comando: train

Entrena el modelo con un archivo CSV y lo guarda en disco.

Sintaxis:

python KNN-recomendation.py train --data <ruta_csv> [--out <archivo_modelo>]

Parámetros:

  • --data (requerido): Ruta al archivo CSV con los datos de ciudades
  • --out (opcional): Nombre del archivo donde guardar el modelo. Por defecto: city_model.pkl

Ejemplo:

python KNN-recomendation.py train --data ciudades.csv --out mi_modelo.pkl

Salida esperada:

Modelo entrenado exitosamente con 50 ciudades.
Modelo guardado en: mi_modelo.pkl

Comando: predict

Carga un modelo pre-entrenado y genera recomendaciones basadas en características de usuario.

Sintaxis:

python KNN-recomendation.py predict [--model <archivo_modelo>] <característica1> <característica2> ... <característica10>

Parámetros:

  • --model (opcional): Ruta al archivo del modelo entrenado. Por defecto: city_model.pkl
  • features (requerido): 10 valores numéricos separados por espacios, representando las características del usuario

Ejemplo:

python KNN-recomendation.py predict --model mi_modelo.pkl 8.5 7.2 9.0 6.5 8.0 7.8 9.2 6.0 8.5 7.5

Salida esperada:

--- RESULTADOS ---
      Ciudad  match_score
   Barcelona        0.9234
      Madrid        0.9012
    Valencia        0.8876

5. Perfil del Usuario y Características Buscadas

Perspectiva del Usuario

El sistema de recomendación está diseñado para ayudar a una persona que busca una ciudad que se ajuste a sus preferencias y necesidades personales. La persona debe definir qué tan importante es cada una de las 10 características para ella, creando así un perfil personalizado que el algoritmo utilizará para encontrar las ciudades más similares.

Definición de Preferencias

La persona que busca recomendaciones debe evaluar sus necesidades en cada una de las 10 características. Estas características representan diferentes aspectos que pueden ser importantes al elegir una ciudad para vivir, visitar o considerar como destino.

Proceso de evaluación:

  1. La persona reflexiona sobre qué tan importante es cada característica para ella
  2. Asigna un valor numérico a cada característica según su nivel de importancia o necesidad
  3. El sistema compara estas preferencias con las características reales de las ciudades en la base de datos
  4. Se recomiendan las ciudades cuyas características se alinean mejor con las preferencias del usuario

Interpretación de Valores

Aunque el script acepta cualquier valor numérico, se recomienda usar una escala de 0 a 10 para facilitar la interpretación:

  • 0-2: Muy baja importancia / No es relevante para la persona
  • 3-4: Baja importancia / Poco relevante
  • 5-6: Importancia media / Moderadamente importante
  • 7-8: Alta importancia / Muy importante para la persona
  • 9-10: Máxima importancia / Crítico o esencial para la persona

Ejemplo de interpretación:

  • Si una persona valora mucho la seguridad y la cultura, asignará valores altos (8-10) a esas características
  • Si la naturaleza no es prioritaria, asignará un valor bajo (2-4) a esa característica
  • Si el transporte público es moderadamente importante, asignará un valor medio (5-6)

Ejemplos de Perfiles de Usuario

Perfil 1: Profesional Joven

Una persona joven que busca oportunidades profesionales y vida social activa:

  • Seguridad: 7.0 (importante pero no crítico)
  • Transporte: 9.0 (esencial para movilidad)
  • Cultura: 8.5 (muy importante para entretenimiento)
  • Gastronomía: 8.0 (disfruta de la vida social)
  • Naturaleza: 4.0 (poco relevante)
  • Entretenimiento: 9.5 (muy importante)
  • Educación: 6.0 (moderadamente importante)
  • Salud: 7.5 (importante)
  • Economía: 9.0 (crítico para oportunidades laborales)
  • Calidad de Vida: 8.0 (importante)

Perfil 2: Familia con Niños

Una familia que prioriza seguridad, educación y servicios:

  • Seguridad: 10.0 (máxima prioridad)
  • Transporte: 7.0 (importante pero no crítico)
  • Cultura: 6.5 (moderadamente importante)
  • Gastronomía: 6.0 (moderadamente importante)
  • Naturaleza: 7.5 (importante para actividades familiares)
  • Entretenimiento: 6.0 (moderadamente importante)
  • Educación: 10.0 (crítico para los hijos)
  • Salud: 9.5 (muy importante)
  • Economía: 8.0 (importante para estabilidad)
  • Calidad de Vida: 9.0 (muy importante)

Perfil 3: Persona Mayor Retirada

Una persona que busca tranquilidad, salud y calidad de vida:

  • Seguridad: 9.0 (muy importante)
  • Transporte: 6.0 (moderadamente importante)
  • Cultura: 7.0 (importante para actividades)
  • Gastronomía: 7.5 (importante)
  • Naturaleza: 8.5 (muy importante para tranquilidad)
  • Entretenimiento: 5.0 (poco relevante)
  • Educación: 3.0 (muy poco relevante)
  • Salud: 10.0 (máxima prioridad)
  • Economía: 6.5 (moderadamente importante)
  • Calidad de Vida: 9.5 (muy importante)

Relación entre Características

Las 10 características representan diferentes dimensiones que una persona puede considerar al evaluar una ciudad:

  1. Características de Infraestructura: Transporte, Salud, Economía

    • Relacionadas con servicios y facilidades disponibles
  2. Características de Calidad de Vida: Seguridad, Calidad de Vida, Naturaleza

    • Relacionadas con bienestar personal y entorno
  3. Características Culturales y Sociales: Cultura, Gastronomía, Entretenimiento

    • Relacionadas con actividades sociales y opciones de ocio
  4. Características de Desarrollo Personal: Educación

    • Relacionada con oportunidades de crecimiento y formación

Importante: La persona debe evaluar cada característica de forma independiente según sus propias prioridades. No hay características "mejores" o "peores"; cada persona tiene necesidades y preferencias únicas que el sistema respeta al generar recomendaciones personalizadas.

Correspondencia con el CSV

Las características que la persona define como sus preferencias deben corresponder exactamente con las características que están evaluadas en el CSV de ciudades. Es decir:

  • Si el CSV tiene columnas: Seguridad, Transporte, Cultura, Gastronomía, Naturaleza, Entretenimiento, Educación, Salud, Economía, CalidadVida
  • La persona debe proporcionar sus preferencias en ese mismo orden: [Seguridad, Transporte, Cultura, Gastronomía, Naturaleza, Entretenimiento, Educación, Salud, Economía, CalidadVida]

El sistema compara las preferencias de la persona con las características reales de cada ciudad para encontrar las mejores coincidencias.

6. Requisitos de Datos

Formato del CSV de Entrada

El archivo CSV debe cumplir con la siguiente estructura:

  1. Primera columna: Nombre de la ciudad (texto)
  2. Siguientes columnas: Exactamente 10 características numéricas

Estructura esperada:

Ciudad,Caracteristica1,Caracteristica2,Caracteristica3,Caracteristica4,Caracteristica5,Caracteristica6,Caracteristica7,Caracteristica8,Caracteristica9,Caracteristica10
Barcelona,8.5,7.2,9.0,6.5,8.0,7.8,9.2,6.0,8.5,7.5
Madrid,7.8,8.0,8.5,7.2,7.5,8.2,8.0,7.8,7.0,8.5
Valencia,7.0,6.5,7.8,8.0,6.8,7.5,7.2,8.5,6.5,7.8

Características Numéricas

  • Tipo: Valores numéricos (int o float)
  • Rango: Aunque el script menciona valores 0-10 en el help, acepta cualquier valor numérico
  • Cantidad: Exactamente 10 características por ciudad
  • Normalización: El script normaliza automáticamente todas las características al rango [0, 1] usando MinMaxScaler

Requisitos Adicionales

  • El CSV debe tener encabezados (nombres de columnas)
  • Todas las filas deben tener el mismo número de columnas
  • No deben existir valores faltantes (NaN) en las columnas numéricas
  • La primera columna puede contener cualquier tipo de dato (se usa como identificador)
  • Correspondencia con preferencias del usuario: Las características del CSV deben representar los mismos aspectos que la persona busca. El orden de las columnas en el CSV debe coincidir con el orden en que la persona proporciona sus preferencias

7. Dependencias

El script requiere las siguientes librerías de Python:

Librerías Estándar

  • argparse: Manejo de argumentos de línea de comandos
  • sys: Funciones del sistema
  • os: Operaciones del sistema de archivos

Librerías Externas

Instalar con pip:

pip install pandas numpy scikit-learn joblib

Dependencias:

  • pandas: Manipulación y análisis de datos (lectura de CSV, DataFrames)
  • numpy: Operaciones numéricas y arrays
  • scikit-learn: Algoritmos de machine learning (NearestNeighbors, MinMaxScaler)
  • joblib: Serialización eficiente de objetos Python (guardado/carga de modelos)

8. Salida del Modelo

Formato del Archivo .pkl

El modelo se guarda en formato .pkl usando la librería joblib, que es más eficiente que pickle para objetos de NumPy y scikit-learn.

Contenido del Diccionario Guardado

El archivo .pkl contiene un diccionario con tres claves:

{
    'knn_model': NearestNeighbors,      # Modelo KNN entrenado
    'scaler': MinMaxScaler,              # Scaler con parámetros entrenados
    'database': DataFrame                # Base de datos completa de ciudades
}

Importancia de la Persistencia

Es crítico guardar los tres componentes juntos porque:

  • El modelo KNN necesita los vectores normalizados para funcionar correctamente
  • El scaler debe ser el mismo usado en entrenamiento para normalizar nuevas características
  • La base de datos contiene los nombres y datos completos de las ciudades para generar resultados legibles

9. Ejemplo Completo de Uso

Paso 1: Preparar los Datos

Crear un archivo ciudades.csv:

Ciudad,Seguridad,Transporte,Cultura,Gastronomia,Naturaleza,Entretenimiento,Educacion,Salud,Economia,CalidadVida
Barcelona,8.5,9.0,9.5,9.2,7.0,8.8,8.5,8.0,7.5,8.7
Madrid,8.0,9.2,9.0,8.8,6.5,9.0,9.2,8.5,8.0,8.5
Valencia,7.5,7.8,7.5,8.5,8.0,7.5,7.8,8.2,7.0,7.8
Sevilla,7.0,7.5,8.5,9.0,7.5,8.0,7.5,7.8,6.5,7.5
Bilbao,8.0,7.2,8.0,8.2,8.5,7.2,8.0,8.5,7.8,8.0

Paso 2: Entrenar el Modelo

python KNN-recomendation.py train --data ciudades.csv --out city_model.pkl

Salida:

Modelo entrenado exitosamente con 5 ciudades.
Modelo guardado en: city_model.pkl

Paso 3: Generar Recomendaciones

Supongamos que un usuario tiene las siguientes preferencias (en orden):

  • Seguridad: 8.5
  • Transporte: 9.0
  • Cultura: 9.5
  • Gastronomía: 9.2
  • Naturaleza: 7.0
  • Entretenimiento: 8.8
  • Educación: 8.5
  • Salud: 8.0
  • Economía: 7.5
  • Calidad de Vida: 8.7
python KNN-recomendation.py predict --model city_model.pkl 8.5 9.0 9.5 9.2 7.0 8.8 8.5 8.0 7.5 8.7

Salida:

--- RESULTADOS ---
      Ciudad  match_score
  Barcelona        0.9987
      Madrid        0.9856
    Valencia        0.9234

Interpretación de Resultados

  • match_score: Valor entre 0 y 1 que indica la similitud entre las preferencias del usuario y la ciudad
    • 1.0: Máxima similitud (ciudad perfectamente alineada con preferencias)
    • 0.0: Mínima similitud (ciudad muy diferente a las preferencias)
  • El score se calcula como (1 - distancia_coseno), por lo que valores más altos indican mayor similitud
  • Las ciudades se ordenan de mayor a menor score (mejores recomendaciones primero)

Notas Importantes

  1. Orden de características: Las características deben proporcionarse en el mismo orden que aparecen en el CSV (después de la columna de nombre de ciudad)

  2. Normalización automática: No es necesario normalizar manualmente los valores de entrada; el script usa el scaler entrenado para normalizarlos automáticamente

  3. Reentrenamiento: Si se modifica el CSV de ciudades, es necesario reentrenar el modelo con el comando train

  4. Compatibilidad: El modelo guardado es específico de la versión de scikit-learn usada. Modelos guardados con versiones diferentes pueden no ser compatibles