Proyecto: Recomendador de Destinos Turísticos con Machine Learning

Ver en Colab ➜

Personalizar y entregar el archivo con comentarios en el código:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics.pairwise import cosine_similarity

# Semilla para reproducibilidad
np.random.seed(42)

# Crear un DataFrame ficticio de historial de viajes
usuarios = np.arange(1, 21)  # 20 usuarios
destinos = ['París', 'Roma', 'Barcelona', 'Nueva York', 'Singapur', 'Tokio', 
            'Londres', 'Sídney', 'Dubái', 'Estambul', 'Río de Janeiro', 'Bangkok',
            'San Francisco', 'Moscú', 'Los Ángeles']

# Crear visitas aleatorias
num_visitas = 100
df_destinos = pd.DataFrame({
    'UsuarioID': np.random.choice(usuarios, num_visitas),
    'Destino': np.random.choice(destinos, num_visitas)
})

# Crear una matriz usuario-destino con puntuaciones aleatorias (1-5)
matriz_usuario_destino = pd.DataFrame(
    np.random.randint(0, 6, size=(len(usuarios), len(destinos))),
    index=usuarios,
    columns=destinos
)

# Clase RecomendadorDestinos con un enfoque de filtrado colaborativo basado en vecinos
class RecomendadorDestinos:
    def __init__(self, df, matriz_usuario_destino, temp=0.9, k=5):
        self.df = df
        self.matriz_usuario_destino = matriz_usuario_destino
        self.todos_destinos = df['Destino'].unique()
        self.temp = temp
        self.k = k  # Número de vecinos más cercanos para recomendación

        # Calcular la similitud entre usuarios utilizando la similitud de coseno
        self.similitud_usuarios = cosine_similarity(self.matriz_usuario_destino)

    def recomendar_destinos(self, usuario_id, num_recomendaciones=3):
        if usuario_id not in self.matriz_usuario_destino.index:
            print(f"Usuario {usuario_id} no encontrado. Generando recomendaciones aleatorias. 🌍✨")
            return list(np.random.choice(self.todos_destinos, num_recomendaciones, replace=False))

        destinos_visitados = self.df[self.df['UsuarioID'] == usuario_id]['Destino'].unique()
        destinos_no_visitados = [d for d in self.todos_destinos if d not in destinos_visitados]

        if len(destinos_no_visitados) == 0:
            print(f"Usuario {usuario_id} ha visitado todos los destinos. Generando recomendaciones aleatorias. 🌟✨")
            return list(np.random.choice(self.todos_destinos, num_recomendaciones, replace=False))

        # Obtener los k usuarios más similares al usuario dado
        idx_usuario = usuario_id - 1  # Para ajustar índice a 0-based
        similitudes = self.similitud_usuarios[idx_usuario]
        vecinos_similares = np.argsort(similitudes)[-self.k-1:-1]  # Excluir el propio usuario

        # Contar cuántas veces cada destino fue visitado por los vecinos
        destinos_recomendados = {}
        for vecino in vecinos_similares:
            destinos_vecino = self.matriz_usuario_destino.iloc[vecino]
            for destino, puntuacion in destinos_vecino.items():
                if destino not in destinos_visitados:
                    if destino not in destinos_recomendados:
                        destinos_recomendados[destino] = 0
                    destinos_recomendados[destino] += puntuacion

        # Seleccionar los destinos con más puntuación
        recomendaciones = sorted(destinos_recomendados.items(), key=lambda x: x[1], reverse=True)
        return [rec[0] for rec in recomendaciones[:num_recomendaciones]]

# Crear la instancia del recomendador con el parámetro temp actualizado
recomendador = RecomendadorDestinos(df_destinos, matriz_usuario_destino, temp=0.9, k=5)

# Función para mostrar recomendaciones
def mostrar_recomendaciones(usuario_id):
    print(f"🌟 Recomendaciones para Usuario {usuario_id}:\n")

    destinos_previos = df_destinos[df_destinos['UsuarioID'] == usuario_id]['Destino'].unique()
    if len(destinos_previos) > 0:
        print("🏖️ Destinos Visitados Previamente:")
        for destino in destinos_previos:
            print(f"  - {destino}")
    else:
        print("Este usuario no tiene destinos visitados registrados. 😕")

    print("\n🎯 Recomendaciones Personalizadas:")
    recomendaciones = recomendador.recomendar_destinos(usuario_id)
    for destino in recomendaciones:
        print(f"  - {destino} 🌍")

# Mostrar recomendaciones para el Usuario 5
mostrar_recomendaciones(5)

# Visualización de las puntuaciones de un usuario específico
usuario_id = 5
preferencias_usuario = matriz_usuario_destino.loc[usuario_id]
preferencias_usuario = preferencias_usuario[preferencias_usuario > 0]
plt.figure(figsize=(10, 6))
sns.barplot(x=preferencias_usuario.index, y=preferencias_usuario.values, palette='viridis')
plt.title(f"Preferencias del Usuario {usuario_id}")
pltimport pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics.pairwise import cosine_similarity

# Semilla para reproducibilidad
np.random.seed(42)

# Crear un DataFrame ficticio de historial de viajes
usuarios = np.arange(1, 21)  # 20 usuarios
destinos = ['París', 'Roma', 'Barcelona', 'Nueva York', 'Singapur', 'Tokio', 
            'Londres', 'Sídney', 'Dubái', 'Estambul', 'Río de Janeiro', 'Bangkok',
            'San Francisco', 'Moscú', 'Los Ángeles']

# Crear visitas aleatorias
num_visitas = 100
df_destinos = pd.DataFrame({
    'UsuarioID': np.random.choice(usuarios, num_visitas),
    'Destino': np.random.choice(destinos, num_visitas)
})

# Crear una matriz usuario-destino con puntuaciones aleatorias (1-5)
matriz_usuario_destino = pd.DataFrame(
    np.random.randint(0, 6, size=(len(usuarios), len(destinos))),
    index=usuarios,
    columns=destinos
)

# Clase RecomendadorDestinos con un enfoque de filtrado colaborativo basado en vecinos
class RecomendadorDestinos:
    def __init__(self, df, matriz_usuario_destino, temp=0.9, k=5):
        self.df = df
        self.matriz_usuario_destino = matriz_usuario_destino
        self.todos_destinos = df['Destino'].unique()
        self.temp = temp
        self.k = k  # Número de vecinos más cercanos para recomendación

        # Calcular la similitud entre usuarios utilizando la similitud de coseno
        self.similitud_usuarios = cosine_similarity(self.matriz_usuario_destino)

    def recomendar_destinos(self, usuario_id, num_recomendaciones=3):
        if usuario_id not in self.matriz_usuario_destino.index:
            print(f"Usuario {usuario_id} no encontrado. Generando recomendaciones aleatorias. 🌍✨")
            return list(np.random.choice(self.todos_destinos, num_recomendaciones, replace=False))

        destinos_visitados = self.df[self.df['UsuarioID'] == usuario_id]['Destino'].unique()
        destinos_no_visitados = [d for d in self.todos_destinos if d not in destinos_visitados]

        if len(destinos_no_visitados) == 0:
            print(f"Usuario {usuario_id} ha visitado todos los destinos. Generando recomendaciones aleatorias. 🌟✨")
            return list(np.random.choice(self.todos_destinos, num_recomendaciones, replace=False))

        # Obtener los k usuarios más similares al usuario dado
        idx_usuario = usuario_id - 1  # Para ajustar índice a 0-based
        similitudes = self.similitud_usuarios[idx_usuario]
        vecinos_similares = np.argsort(similitudes)[-self.k-1:-1]  # Excluir el propio usuario

        # Contar cuántas veces cada destino fue visitado por los vecinos
        destinos_recomendados = {}
        for vecino in vecinos_similares:
            destinos_vecino = self.matriz_usuario_destino.iloc[vecino]
            for destino, puntuacion in destinos_vecino.items():
                if destino not in destinos_visitados:
                    if destino not in destinos_recomendados:
                        destinos_recomendados[destino] = 0
                    destinos_recomendados[destino] += puntuacion

        # Seleccionar los destinos con más puntuación
        recomendaciones = sorted(destinos_recomendados.items(), key=lambda x: x[1], reverse=True)
        return [rec[0] for rec in recomendaciones[:num_recomendaciones]]

# Crear la instancia del recomendador con el parámetro temp actualizado
recomendador = RecomendadorDestinos(df_destinos, matriz_usuario_destino, temp=0.9, k=5)

# Función para mostrar recomendaciones
def mostrar_recomendaciones(usuario_id):
    print(f"🌟 Recomendaciones para Usuario {usuario_id}:\n")

    destinos_previos = df_destinos[df_destinos['UsuarioID'] == usuario_id]['Destino'].unique()
    if len(destinos_previos) > 0:
        print("🏖️ Destinos Visitados Previamente:")
        for destino in destinos_previos:
            print(f"  - {destino}")
    else:
        print("Este usuario no tiene destinos visitados registrados. 😕")

    print("\n🎯 Recomendaciones Personalizadas:")
    recomendaciones = recomendador.recomendar_destinos(usuario_id)
    for destino in recomendaciones:
        print(f"  - {destino} 🌍")

# prompt: create a form to input user id for consult
# Get user input for the user ID
usuario_id = int(input("Enter the user ID for consultation: "))

# Call the mostrar_recomendaciones function with the user ID
mostrar_recomendaciones(usuario_id)

# Visualización de las puntuaciones de un usuario específico
usuario_id = 5
preferencias_usuario = matriz_usuario_destino.loc[usuario_id]
preferencias_usuario = preferencias_usuario[preferencias_usuario > 0]
plt.figure(figsize=(10, 6))
sns.barplot(x=preferencias_usuario.index, y=preferencias_usuario.values, palette='viridis')
plt.title(f"Preferencias del Usuario {usuario_id}")
plt