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) |