File size: 2,763 Bytes
f1b7ffb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cf85b4c
f1b7ffb
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

import gradio as gr
import pandas as pd
import pickle
import numpy as np
from collections import defaultdict

with open('best_svd.pkl', 'rb') as f:
    best_svd = pickle.load(f)
with open('model_metadata.pkl', 'rb') as f:
    metadata = pickle.load(f)

movies = metadata['movies_df']
ratings_filtered = metadata['ratings_filtered_df']
popular_movies = metadata['popular_movies']

def recommend_movies_gradio(user_id, n_recommendations):
    try:
        user_id = int(user_id)
        n_recommendations = int(n_recommendations)
    except:
        return "Error: Please enter valid numbers"

    if user_id not in ratings_filtered['userId'].values:
        popular_recs = popular_movies.head(n_recommendations).merge(
            movies[['movieId', 'title_clean', 'year']],
            on='movieId'
        )
        output = f"User {user_id} not found. Showing popular movies:\n\n"
        for i, row in enumerate(popular_recs.itertuples(), 1):
            output += f"{i}. {row.title_clean} ({row.year})\n"
        return output

    user_ratings = ratings_filtered[ratings_filtered['userId'] == user_id]['movieId'].values
    all_movies = ratings_filtered['movieId'].unique()
    unseen_movies = [m for m in all_movies if m not in user_ratings]

    predictions = []
    for movie_id in unseen_movies:
        pred = best_svd.predict(user_id, movie_id)
        predictions.append({
            'movieId': movie_id,
            'score': pred.est
        })

    predictions_df = pd.DataFrame(predictions)
    top_n = predictions_df.nlargest(n_recommendations, 'score')
    top_n = top_n.merge(movies[['movieId', 'title_clean', 'year']], on='movieId')

    output = f"Recommendations for User {user_id}:\n\n"
    for i, row in enumerate(top_n.itertuples(), 1):
        output += f"{i}. {row.title_clean} ({row.year}) - Rating: {row.score:.2f}\n"

    return output

iface = gr.Interface(
    fn=recommend_movies_gradio,
    inputs=[
        gr.Textbox(label="User ID", placeholder="Enter user ID (e.g., 1, 100, 500)"),
        gr.Slider(minimum=5, maximum=50, value=10, step=5, label="Number of Recommendations")
    ],
    outputs=gr.Textbox(label="Recommendations", lines=20),
    title="🎬 Movie Recommendation System - MovieLens",
    description="""
    Get personalized movie recommendations using SVD (Singular Value Decomposition).

    **Model Performance:**
    - **RMSE**: 0.9338 (best prediction accuracy)
    - **Precision@10**: 0.7968 (79.68% relevant recommendations)
    - **NDCG@10**: 0.8514 (85.14% ranking quality)
    - **Recall@10**: 0.2245 (22.46% of ALL relevant items in just 10 recommendations)
    """,
    examples=[
        ["1", 10],
        ["100", 15],
        ["500", 20]
    ]
)

if __name__ == "__main__":
    iface.launch()