import streamlit as st import pandas as pd import numpy as np import tensorflow as tf import joblib @st.cache_resource def load_model(): return tf.keras.models.load_model("recommender_model.keras") @st.cache_data def load_assets(): df_movies = pd.read_csv("movies.csv") user_map, movie_map = joblib.load("encodings.pkl") return df_movies, user_map, movie_map model = load_model() movies_df, user2idx, movie2idx = load_assets() reverse_movie_map = {v: k for k, v in movie2idx.items()} st.title("TensorFlow Movie Recommender") st.write("Select some movies you've liked to get recommendations:") movie_titles = movies_df.set_index("movieId")["title"].to_dict() movie_choices = [movie_titles[mid] for mid in movie2idx.keys() if mid in movie_titles] selected_titles = st.multiselect("Liked movies", sorted(movie_choices)) user_ratings = {} for title in selected_titles: movie_id = [k for k, v in movie_titles.items() if v == title][0] user_ratings[movie_id] = 5.0 if st.button("Get Recommendations"): if not user_ratings: st.warning("Please select at least one movie.") else: liked_indices = [movie2idx[m] for m in user_ratings if m in movie2idx] avg_embedding = tf.reduce_mean(model.layers[2](tf.constant(liked_indices)), axis=0, keepdims=True) all_movie_indices = tf.range(len(movie2idx)) movie_embeddings = model.layers[3](all_movie_indices) scores = tf.reduce_sum(avg_embedding * movie_embeddings, axis=1).numpy() top_indices = np.argsort(scores)[::-1] recommended = [] for idx in top_indices: mid = reverse_movie_map[idx] if mid not in user_ratings and mid in movie_titles: recommended.append((movie_titles[mid], scores[idx])) if len(recommended) >= 10: break st.subheader("Top Recommendations") for title, score in recommended: st.write(f"{title} — Score: {score:.3f}")