sairika commited on
Commit
85af3f8
Β·
verified Β·
1 Parent(s): 8c1fa83

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +179 -0
app.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import gradio as gr
3
+ import pickle
4
+ import pandas as pd
5
+ import numpy as np
6
+ from surprise import SVD
7
+ import warnings
8
+ warnings.filterwarnings('ignore')
9
+
10
+ # Load models and data
11
+ print("Loading models...")
12
+ with open('svd_model.pkl', 'rb') as f:
13
+ svd_model = pickle.load(f)
14
+
15
+ with open('movies.pkl', 'rb') as f:
16
+ movies = pickle.load(f)
17
+
18
+ with open('ratings.pkl', 'rb') as f:
19
+ ratings = pickle.load(f)
20
+
21
+ print("Models loaded successfully!")
22
+
23
+ def recommend_movies(user_id, num_recommendations, min_rating):
24
+ """
25
+ Generate movie recommendations for a user
26
+ """
27
+ try:
28
+ user_id = int(user_id)
29
+ num_recommendations = int(num_recommendations)
30
+ min_rating = float(min_rating)
31
+
32
+ # Check if user exists
33
+ if user_id not in ratings['userId'].values:
34
+ return f"⚠️ User ID {user_id} not found in database. Please try a different user ID (1-{ratings['userId'].max()})."
35
+
36
+ # Get all movies
37
+ all_movie_ids = movies['movieId'].unique()
38
+
39
+ # Get movies the user has already rated
40
+ rated_movies = ratings[ratings['userId'] == user_id]['movieId'].values
41
+
42
+ # Get movies the user hasn't rated
43
+ movies_to_predict = [mid for mid in all_movie_ids if mid not in rated_movies]
44
+
45
+ # Predict ratings
46
+ predictions = []
47
+ for movie_id in movies_to_predict:
48
+ pred = svd_model.predict(user_id, movie_id)
49
+ if pred.est >= min_rating:
50
+ predictions.append({
51
+ 'movieId': movie_id,
52
+ 'predicted_rating': pred.est
53
+ })
54
+
55
+ if not predictions:
56
+ return f"No movies found with predicted rating >= {min_rating}. Try lowering the minimum rating."
57
+
58
+ # Sort and get top N
59
+ predictions_df = pd.DataFrame(predictions)
60
+ predictions_df = predictions_df.sort_values('predicted_rating', ascending=False)
61
+ top_recommendations = predictions_df.head(num_recommendations)
62
+
63
+ # Merge with movie details
64
+ recommendations = top_recommendations.merge(movies, on='movieId')
65
+ recommendations['predicted_rating'] = recommendations['predicted_rating'].round(2)
66
+
67
+ # Format output
68
+ output = f"🎬 Top {len(recommendations)} Movie Recommendations for User {user_id}\n\n"
69
+
70
+ for idx, row in recommendations.iterrows():
71
+ output += f"{idx + 1}. **{row['title']}**\n"
72
+ output += f" ⭐ Predicted Rating: {row['predicted_rating']}/5.0\n"
73
+ output += f" 🎭 Genres: {row['genres']}\n\n"
74
+
75
+ return output
76
+
77
+ except Exception as e:
78
+ return f"❌ Error: {str(e)}"
79
+
80
+ def get_user_history(user_id):
81
+ """
82
+ Get user's rating history
83
+ """
84
+ try:
85
+ user_id = int(user_id)
86
+
87
+ if user_id not in ratings['userId'].values:
88
+ return f"⚠️ User ID {user_id} not found."
89
+
90
+ user_ratings = ratings[ratings['userId'] == user_id].merge(movies, on='movieId')
91
+ user_ratings = user_ratings.sort_values('rating', ascending=False).head(10)
92
+
93
+ output = f"πŸ“Š User {user_id}'s Top Rated Movies:\n\n"
94
+
95
+ for idx, row in user_ratings.iterrows():
96
+ output += f"β€’ **{row['title']}** - ⭐ {row['rating']}/5.0\n"
97
+ output += f" Genres: {row['genres']}\n\n"
98
+
99
+ return output
100
+
101
+ except Exception as e:
102
+ return f"❌ Error: {str(e)}"
103
+
104
+ # Create Gradio interface
105
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
106
+ gr.Markdown(
107
+ """
108
+ # 🎬 MovieLens Recommendation System
109
+ ### Powered by SVD Matrix Factorization
110
+
111
+ Get personalized movie recommendations based on collaborative filtering!
112
+ """
113
+ )
114
+
115
+ with gr.Tab("🎯 Get Recommendations"):
116
+ with gr.Row():
117
+ with gr.Column():
118
+ user_id_input = gr.Number(
119
+ label="User ID",
120
+ value=1,
121
+ info=f"Enter a user ID (1 to {ratings['userId'].max()})"
122
+ )
123
+ num_rec_input = gr.Slider(
124
+ minimum=5,
125
+ maximum=20,
126
+ value=10,
127
+ step=1,
128
+ label="Number of Recommendations"
129
+ )
130
+ min_rating_input = gr.Slider(
131
+ minimum=1.0,
132
+ maximum=5.0,
133
+ value=3.5,
134
+ step=0.5,
135
+ label="Minimum Predicted Rating"
136
+ )
137
+ recommend_btn = gr.Button("🎬 Get Recommendations", variant="primary")
138
+
139
+ with gr.Column():
140
+ recommendations_output = gr.Markdown(label="Recommendations")
141
+
142
+ recommend_btn.click(
143
+ fn=recommend_movies,
144
+ inputs=[user_id_input, num_rec_input, min_rating_input],
145
+ outputs=recommendations_output
146
+ )
147
+
148
+ with gr.Tab("πŸ“Š User History"):
149
+ with gr.Row():
150
+ with gr.Column():
151
+ history_user_id = gr.Number(
152
+ label="User ID",
153
+ value=1,
154
+ info="Enter a user ID to see their rating history"
155
+ )
156
+ history_btn = gr.Button("πŸ“Š View History", variant="primary")
157
+
158
+ with gr.Column():
159
+ history_output = gr.Markdown(label="User History")
160
+
161
+ history_btn.click(
162
+ fn=get_user_history,
163
+ inputs=history_user_id,
164
+ outputs=history_output
165
+ )
166
+
167
+ gr.Markdown(
168
+ """
169
+ ---
170
+ ### πŸ“ˆ Model Information
171
+ - **Algorithm**: SVD (Singular Value Decomposition)
172
+ - **Dataset**: MovieLens Small (100K ratings)
173
+ - **Evaluation Metrics**: RMSE, Precision@K, Recall@K, NDCG@K
174
+ - **Best Performance**: Lowest RMSE and Highest NDCG among tested models
175
+ """
176
+ )
177
+
178
+ if __name__ == "__main__":
179
+ demo.launch()