Spaces:
Sleeping
Sleeping
import gradio as gr | |
import pickle | |
import numpy as np | |
import pandas as pd | |
# model weights pickled after training from scratch | |
with open('final_02_model_biases_factors.pkl', 'rb') as file: | |
model_state = pickle.load(file) | |
user_bias = model_state["user_bias"] | |
movie_bias = model_state["movie_bias"] | |
user_factors = model_state["user_factors"] | |
movie_factors = model_state["movie_factors"] | |
movies = pd.read_csv("movies.csv") | |
with open('map_movie_to_idx.pkl', 'rb') as file: | |
map_movie_to_idx = pickle.load(file) | |
with open('map_idx_to_movie.pkl', 'rb') as file: | |
map_idx_to_movie = pickle.load(file) | |
def get_movie_id(title): | |
movie = movies[movies['title'].str.contains(title, case=False, na=False)] | |
if not movie.empty: | |
return movie.iloc[0]['movieId'], movie.iloc[0]['title'], movie.iloc[0]['genres'] | |
return None, None, None | |
def recommend_movies(movie_title, rating, latent_dim=10, lambda_param=0.1, tau=0.1): | |
movie_id, title, genres = get_movie_id(movie_title) | |
if movie_id is None: | |
return f"Movie '{movie_title}' not found." | |
# Map the dummy movie id to its index | |
dummy_movie_index = map_movie_to_idx[movie_id] | |
# Get the movie factors and bias for the dummy movie | |
dummy_movie_factors = movie_factors[:, dummy_movie_index] | |
dummy_movie_bias = movie_bias[dummy_movie_index] | |
# Initialize dummy user factors | |
dummy_user_factors = np.zeros(latent_dim) | |
# Calculate the dummy user factor | |
dummy_user_factor = np.linalg.inv(lambda_param * np.outer(dummy_movie_factors, dummy_movie_factors) + | |
tau * np.eye(latent_dim)) @ (lambda_param * dummy_movie_factors * (rating - dummy_movie_bias)) | |
# Calculate the score for each movie | |
score = dummy_user_factor @ movie_factors + 0.05 * movie_bias | |
# Get the top 10 recommendations | |
recommend_movies_indices = np.argsort(score)[-10:] | |
# Map the indices back to movie titles | |
recommended_movies = [movies.loc[movies["movieId"] == map_idx_to_movie[movie]] for movie in recommend_movies_indices] | |
# Format the output as HTML | |
html_output = "<div style='font-family: Arial, sans-serif;'>" | |
html_output += f"<div style='margin-bottom: 20px;'><strong>Selected Movie:</strong><br>Title: {title}<br>Genres: {genres}</div>" | |
html_output += "<div style='margin-bottom: 20px;'><strong>Recommended Movies:</strong></div>" | |
for i, movie in enumerate(recommended_movies): | |
title = movie["title"].values[0] | |
genres = movie["genres"].values[0] | |
html_output += f"<div style='margin-bottom: 10px;'><strong>{i+1}. {title}</strong><br>Genres: {genres}</div>" | |
html_output += "</div>" | |
return html_output | |
# Define the Gradio interface | |
iface = gr.Interface( | |
fn=recommend_movies, | |
inputs=[ | |
gr.Textbox(label="Movie Title"), | |
gr.Slider(0, 5, step=0.1, label="Rating") | |
], | |
outputs="html", | |
title="Movie Recommendation System", | |
description=""" | |
Enter a movie title and rating to get top 10 movie recommendations. | |
I made this demo as part of a machine learning class taught by Prof. Ulich Paquet at AIMS South Africa. | |
Here are some sample movies you can try out of a database of over 62,000 movies: | |
- Toy Story | |
- Incredibles | |
- Lord of the rings | |
- Star Wars | |
- Terminator | |
""" | |
) | |
iface.launch(share=True) |