Image for post Guía para Principiantes: Cómo Construir un Sistema de Recomendación Simple con Python y Scikit-Learn

Guía para Principiantes: Cómo Construir un Sistema de Recomendación Simple con Python y Scikit-Learn


Los sistemas de recomendación forman parte fundamental de muchas aplicaciones actuales, desde plataformas de streaming hasta tiendas en línea. Su función principal es sugerir contenido o productos relevantes basados en los gustos o comportamientos previos del usuario. En esta guía para principiantes, aprenderemos cómo construir un sistema de recomendación básico utilizando Python y la biblioteca Scikit-Learn, con un enfoque claro y didáctico.

¿Qué es un Sistema de Recomendación?

Los sistemas de recomendación son algoritmos que filtran información para ofrecer opciones personalizadas a cada usuario. Se dividen principalmente en dos tipos:

  • Filtrado Colaborativo: basado en las preferencias y comportamientos de usuarios similares.
  • Filtrado Basado en Contenido: basado en las características o atributos del contenido.

En este artículo, construiremos un sistema sencillo basado en filtrado colaborativo usando la similitud entre usuarios.

Requisitos Previos

Para seguir esta guía necesitarás:

  • Python 3 instalado (preferiblemente 3.7+)
  • Bibliotecas: scikit-learn, pandas y numpy

Si no las tienes instaladas, puedes hacerlo fácilmente con:

pip install scikit-learn pandas numpy

Descripción del Dataset de Ejemplo

Usaremos un conjunto reducido de datos simulado que incluye valoraciones de usuarios para ciertos productos (por ejemplo, películas). La estructura es una matriz donde filas son usuarios, columnas son productos y valores son puntuaciones.

import pandas as pd

data = {
    'Producto A': [5, 4, 0, 1, 0],
    'Producto B': [3, 0, 4, 2, 1],
    'Producto C': [0, 2, 5, 4, 0],
    'Producto D': [1, 0, 2, 5, 4],
    'Producto E': [0, 1, 3, 0, 5]
}

usuarios = ['Usuario 1', 'Usuario 2', 'Usuario 3', 'Usuario 4', 'Usuario 5']

ratings = pd.DataFrame(data, index=usuarios)
print(ratings)

Esto generará un DataFrame con puntuaciones asignadas por cada usuario a cada producto.

Construyendo el Sistema de Recomendación Básico

El objetivo es recomendar productos que un usuario no haya valorado aún pero que usuarios con gustos similares sí hayan calificado positivamente. Para ello usaremos la similitud entre usuarios:

  1. Calcular la similitud entre usuarios usando la distancia del coseno.
  2. Encontrar los usuarios más parecidos a un usuario objetivo.
  3. Predecir puntuaciones para productos no valorados sumando las valoraciones ponderadas de usuarios similares.
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

# Calculamos la matriz de similitud entre usuarios
sim_matrix = cosine_similarity(ratings.fillna(0))
sim_matrix_df = pd.DataFrame(sim_matrix, index=usuarios, columns=usuarios)
print(sim_matrix_df)

# Función para recomendar productos a un usuario

def recomendar(usuario_objetivo, ratings_df, sim_df, n_recomendaciones=3):
    if usuario_objetivo not in ratings_df.index:
        return "Usuario no encontrado en el dataset."
    
    # Obtenemos índices y puntuaciones del usuario objetivo
    usuario_idx = ratings_df.index.get_loc(usuario_objetivo)

    # Calculamos puntuaciones ponderadas usando la similitud
    sim_scores = sim_df.iloc[usuario_idx]

    # Productos que el usuario objetivo no ha valorado
    productos_no_valorados = ratings_df.columns[ratings_df.iloc[usuario_idx] == 0]

    predicciones = {}
    
    for producto in productos_no_valorados:
        # Valoraciones de otros usuarios para el producto
        ratings_producto = ratings_df[producto]

        # Eliminamos valoraciones cero para que no afecten
        mask = ratings_producto > 0

        if mask.sum() == 0:
            predicciones[producto] = 0
            continue

        # Suma ponderada de valoraciones
        score = np.dot(sim_scores[mask], ratings_producto[mask]) / sim_scores[mask].sum()
        predicciones[producto] = score

    # Ordenamos predicciones y seleccionamos las mejores
    recomendaciones = sorted(predicciones.items(), key=lambda x: x[1], reverse=True)[:n_recomendaciones]
    
    return recomendaciones

# Ejemplo de recomendación para Usuario 1
recoms = recomendar('Usuario 1', ratings, sim_matrix_df, n_recomendaciones=2)
print('Recomendaciones para Usuario 1:', recoms)

Este código proporcionará recomendaciones basadas en los gustos de usuarios similares.

Explicación Detallada de la Implementación

Similitud Coseno: mide el ángulo entre dos vectores de puntuaciones, lo que indica la similitud en preferencias independientemente de la escala numérica absoluta.

Puntuaciones ponderadas: Las recomendaciones se basan en la combinación ponderada de valoraciones de usuarios similares, dando mayor peso a los usuarios más parecidos.

Manejo de valores faltantes: En este ejemplo se asume que la puntuación 0 significa no valorado. En implementaciones reales puede utilizarse NaN para mayor precisión y evitar sesgos.

Pasos siguientes para mejorar el sistema

  • Incorporar filtrado basado en contenido usando atributos de productos.
  • Usar matrices dispersas para mejorar rendimiento con grandes volúmenes de datos.
  • Implementar sistemas híbridos que combinen filtrado colaborativo y basado en contenido.
  • Explorar librerías especializadas para recomendación como Surprise o LightFM.

Conclusión

Con esta introducción hemos construido un sistema básico de recomendación colaborativo usando Python y Scikit-Learn. Aunque muy simple, este modelo sirve como base para entender el funcionamiento de estos algoritmos tan presentes actualmente. A partir de aquí, ampliando el dataset y mejorando las técnicas, es posible crear sistemas potentes para aplicaciones reales.