Rijeet commited on
Commit
842bb52
Β·
verified Β·
1 Parent(s): 806afe8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +566 -0
app.py ADDED
@@ -0,0 +1,566 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import numpy as np
4
+ import pickle
5
+ import os
6
+ from comprehensive_recommendation_system import ComprehensiveRecommendationSystem
7
+ import warnings
8
+
9
+ warnings.filterwarnings('ignore')
10
+
11
+
12
+ rec_system = None
13
+
14
+ def load_recommendation_system():
15
+ """Load the trained recommendation system"""
16
+ global rec_system
17
+
18
+ if rec_system is None:
19
+ print("Loading comprehensive recommendation system...")
20
+ rec_system = ComprehensiveRecommendationSystem()
21
+
22
+
23
+ rec_system.load_data("MovieLensDataset_small/ml-100k/u.data", "MovieLensDataset_small/ml-100k/u.item")
24
+
25
+
26
+ if os.path.exists("comprehensive_recommendation_model.pkl"):
27
+ print("Loading pre-trained model...")
28
+ rec_system.load_model("comprehensive_recommendation_model.pkl")
29
+ else:
30
+ print("Training models...")
31
+ rec_system.train_all_models()
32
+ rec_system.save_model("comprehensive_recommendation_model.pkl")
33
+
34
+ print("Recommendation system loaded successfully!")
35
+
36
+ return rec_system
37
+
38
+ def get_available_users():
39
+ """Get list of available users"""
40
+ if rec_system is None:
41
+ return []
42
+ return sorted(rec_system.ratings['user_id'].unique().tolist())
43
+
44
+ def get_user_stats():
45
+ """Get user statistics"""
46
+ if rec_system is None:
47
+ return "System not loaded"
48
+
49
+ total_users = rec_system.ratings['user_id'].nunique()
50
+ total_movies = rec_system.movies['movie_id'].nunique()
51
+ total_ratings = len(rec_system.ratings)
52
+ avg_rating = rec_system.ratings['rating'].mean()
53
+
54
+ return f"""
55
+ **Dataset Statistics:**
56
+ - **Users:** {total_users:,}
57
+ - **Movies:** {total_movies:,}
58
+ - **Ratings:** {total_ratings:,}
59
+ - **Average Rating:** {avg_rating:.2f}/5.0
60
+ - **Sparsity:** 93.70%
61
+ """
62
+
63
+ def get_user_info(user_id):
64
+ """Get detailed information about a user"""
65
+ if rec_system is None:
66
+ return "System not loaded"
67
+
68
+ if user_id is None:
69
+ return "Please select a user"
70
+
71
+ user_ratings = rec_system.ratings[rec_system.ratings['user_id'] == user_id]
72
+
73
+ if len(user_ratings) == 0:
74
+ return f"User {user_id} not found in dataset"
75
+
76
+ # Get user's rating statistics
77
+ avg_rating = user_ratings['rating'].mean()
78
+ num_ratings = len(user_ratings)
79
+ rating_range = f"{user_ratings['rating'].min()} - {user_ratings['rating'].max()}"
80
+
81
+ # Get rating distribution
82
+ rating_dist = user_ratings['rating'].value_counts().sort_index()
83
+
84
+ # Get user's top-rated movies
85
+ top_movies = user_ratings.merge(
86
+ rec_system.movies[['movie_id', 'title']],
87
+ on='movie_id'
88
+ ).sort_values('rating', ascending=False).head(10)
89
+
90
+ info = f"""
91
+ ## πŸ‘€ User {user_id} Profile
92
+
93
+ ### πŸ“Š Rating Statistics
94
+ - **Total Ratings:** {num_ratings:,}
95
+ - **Average Rating:** {avg_rating:.2f}/5.0
96
+ - **Rating Range:** {rating_range}
97
+
98
+ ### πŸ“ˆ Rating Distribution
99
+ """
100
+
101
+ for rating, count in rating_dist.items():
102
+ percentage = (count / num_ratings) * 100
103
+ info += f"- **{rating} stars:** {count} ratings ({percentage:.1f}%)\n"
104
+
105
+ info += f"""
106
+ ### 🎬 Top 10 Rated Movies
107
+ """
108
+
109
+ for i, (_, movie) in enumerate(top_movies.iterrows(), 1):
110
+ stars = "⭐" * int(movie['rating'])
111
+ info += f"{i:2d}. {movie['title']} {stars} ({movie['rating']})\n"
112
+
113
+ return info
114
+
115
+ def recommend_movies(user_id, num_recommendations, method):
116
+ """Generate movie recommendations"""
117
+ if rec_system is None:
118
+ return "Error: Recommendation system not loaded"
119
+
120
+ if user_id is None:
121
+ return "Please select a user"
122
+
123
+ try:
124
+
125
+ recommendations = rec_system.recommend_movies(
126
+ user_id=int(user_id),
127
+ N=int(num_recommendations),
128
+ method=method
129
+ )
130
+
131
+ if len(recommendations) == 0:
132
+ return "No recommendations available for this user"
133
+
134
+
135
+ method_names = {
136
+ "user_based": "πŸ‘₯ User-based Collaborative Filtering",
137
+ "item_based": "🎬 Item-based Collaborative Filtering",
138
+ "svd": "πŸ“Š SVD Matrix Factorization",
139
+ "neural": "🧠 Neural Embeddings",
140
+ "ensemble": "🎯 Ensemble Method"
141
+ }
142
+
143
+ result = f"## 🎬 Top {len(recommendations)} Movie Recommendations\n\n"
144
+ result += f"**Method:** {method_names.get(method, method.upper())}\n"
145
+ result += f"**User:** {user_id}\n\n"
146
+
147
+ for i, (_, rec) in enumerate(recommendations.iterrows(), 1):
148
+ rating_emoji = "⭐" * int(round(rec['predicted_rating']))
149
+ result += f"**{i:2d}.** {rec['title']}\n"
150
+ result += f" {rating_emoji} Predicted Rating: {rec['predicted_rating']:.3f}\n\n"
151
+
152
+ return result
153
+
154
+ except Exception as e:
155
+ return f"❌ Error generating recommendations: {str(e)}"
156
+
157
+ def compare_all_methods(user_id, num_recommendations):
158
+ """Compare all recommendation methods"""
159
+ if rec_system is None:
160
+ return "Error: Recommendation system not loaded"
161
+
162
+ if user_id is None:
163
+ return "Please select a user"
164
+
165
+ methods = ["user_based", "item_based", "svd", "neural", "ensemble"]
166
+ results = {}
167
+
168
+ try:
169
+ for method in methods:
170
+ recommendations = rec_system.recommend_movies(
171
+ user_id=int(user_id),
172
+ N=int(num_recommendations),
173
+ method=method
174
+ )
175
+ results[method] = recommendations
176
+
177
+
178
+ result = f"## βš–οΈ Method Comparison for User {user_id}\n\n"
179
+ result += f"**Number of recommendations:** {num_recommendations}\n\n"
180
+
181
+ method_names = {
182
+ "user_based": "πŸ‘₯ User-based CF",
183
+ "item_based": "🎬 Item-based CF",
184
+ "svd": "πŸ“Š SVD",
185
+ "neural": "🧠 Neural",
186
+ "ensemble": "🎯 Ensemble"
187
+ }
188
+
189
+ for method, recs in results.items():
190
+ result += f"### {method_names[method]}\n"
191
+ if len(recs) == 0:
192
+ result += "No recommendations available\n\n"
193
+ else:
194
+ for i, (_, rec) in enumerate(recs.iterrows(), 1):
195
+ rating_emoji = "⭐" * int(round(rec['predicted_rating']))
196
+ result += f"{i:2d}. {rec['title']} {rating_emoji} ({rec['predicted_rating']:.3f})\n"
197
+ result += "\n"
198
+
199
+ return result
200
+
201
+ except Exception as e:
202
+ return f"❌ Error comparing methods: {str(e)}"
203
+
204
+ def evaluate_system_performance():
205
+ """Evaluate the recommendation system performance"""
206
+ if rec_system is None:
207
+ return "Error: Recommendation system not loaded"
208
+
209
+ try:
210
+
211
+ all_users = rec_system.ratings['user_id'].unique()
212
+ test_users = np.random.choice(all_users, min(15, len(all_users)), replace=False)
213
+
214
+ methods = ["user_based", "item_based", "svd", "neural", "ensemble"]
215
+ results = {}
216
+
217
+ for method in methods:
218
+ eval_results = rec_system.evaluate_model(test_users, method=method, N=10)
219
+ results[method] = eval_results
220
+
221
+
222
+ result = "## πŸ“Š System Performance Evaluation\n\n"
223
+ result += f"**Evaluated on:** {len(test_users)} users\n"
224
+ result += f"**Recommendations per user:** 10\n\n"
225
+
226
+ result += "| Method | Precision@10 | Recall@10 | NDCG@10 |\n"
227
+ result += "|--------|--------------|-----------|----------|\n"
228
+
229
+ for method, eval_results in results.items():
230
+ method_emoji = {"user_based": "πŸ‘₯", "item_based": "🎬", "svd": "πŸ“Š", "neural": "🧠", "ensemble": "🎯"}
231
+ emoji = method_emoji.get(method, "πŸ“ˆ")
232
+ result += f"| {emoji} {method:12} | {eval_results['precision']:.4f} | {eval_results['recall']:.4f} | {eval_results['ndcg']:.4f} |\n"
233
+
234
+
235
+ best_method = max(results.keys(), key=lambda x: results[x]['ndcg'])
236
+ best_emoji = {"user_based": "πŸ‘₯", "item_based": "🎬", "svd": "πŸ“Š", "neural": "🧠", "ensemble": "🎯"}.get(best_method, "πŸ“ˆ")
237
+
238
+ result += f"\n### πŸ† Best Performing Method\n"
239
+ result += f"**{best_emoji} {best_method.upper()}** with NDCG@10: {results[best_method]['ndcg']:.4f}\n\n"
240
+
241
+ result += "### πŸ“ˆ Metric Explanations\n"
242
+ result += "- **Precision@10:** Fraction of recommended items that are relevant\n"
243
+ result += "- **Recall@10:** Fraction of relevant items that are recommended\n"
244
+ result += "- **NDCG@10:** Normalized Discounted Cumulative Gain (ranking quality)\n"
245
+
246
+ return result
247
+
248
+ except Exception as e:
249
+ return f"❌ Error evaluating system: {str(e)}"
250
+
251
+ def get_method_explanations():
252
+ """Get detailed explanations of each recommendation method"""
253
+ return """
254
+ ## πŸ”¬ Recommendation Methods Explained
255
+
256
+ ### πŸ‘₯ User-based Collaborative Filtering
257
+ **How it works:** Finds users with similar rating patterns and recommends movies they liked.
258
+
259
+ **Strengths:**
260
+ - Intuitive approach that mimics human behavior
261
+ - Good for finding diverse recommendations
262
+ - Effective when user base is large
263
+
264
+ **Best for:** Users who want to discover new genres and diverse content
265
+
266
+ ---
267
+
268
+ ### 🎬 Item-based Collaborative Filtering
269
+ **How it works:** Finds movies with similar rating patterns and recommends items similar to those a user has liked.
270
+
271
+ **Strengths:**
272
+ - More stable than user-based approach
273
+ - Computationally efficient
274
+ - Good for popular items
275
+
276
+ **Best for:** Users who want recommendations similar to movies they already like
277
+
278
+ ---
279
+
280
+ ### πŸ“Š SVD Matrix Factorization
281
+ **How it works:** Decomposes the user-item matrix into latent factors representing user preferences and item characteristics.
282
+
283
+ **Strengths:**
284
+ - Handles sparsity well
285
+ - Captures implicit relationships
286
+ - Computationally efficient
287
+
288
+ **Best for:** Balanced performance with good generalization
289
+
290
+ ---
291
+
292
+ ### 🧠 Neural Embeddings
293
+ **How it works:** Uses deep learning to learn complex non-linear relationships between users and items.
294
+
295
+ **Strengths:**
296
+ - Can capture complex patterns
297
+ - Flexible architecture
298
+ - Good for non-linear relationships
299
+
300
+ **Best for:** Advanced pattern recognition and complex user behaviors
301
+
302
+ ---
303
+
304
+ ### 🎯 Ensemble Method
305
+ **How it works:** Combines predictions from all four approaches by averaging their recommendation scores.
306
+
307
+ **Strengths:**
308
+ - Reduces individual method biases
309
+ - More robust predictions
310
+ - Better coverage of different patterns
311
+
312
+ **Best for:** Optimal overall performance and reliability
313
+ """
314
+
315
+ def create_interface():
316
+ """Create the enhanced Gradio interface"""
317
+
318
+
319
+ load_recommendation_system()
320
+
321
+ with gr.Blocks(
322
+ title="🎬 Comprehensive Movie Recommendation System",
323
+ theme=gr.themes.Soft(
324
+ primary_hue="blue",
325
+ secondary_hue="purple",
326
+ neutral_hue="slate"
327
+ ),
328
+ css="""
329
+ .main-header {
330
+ text-align: center;
331
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
332
+ -webkit-background-clip: text;
333
+ -webkit-text-fill-color: transparent;
334
+ font-size: 2.5em;
335
+ font-weight: bold;
336
+ margin-bottom: 20px;
337
+ }
338
+ .method-card {
339
+ border: 2px solid #333333;
340
+ border-radius: 12px;
341
+ padding: 20px;
342
+ margin: 15px 0;
343
+ background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
344
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
345
+ color: white;
346
+ }
347
+ .stats-card {
348
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
349
+ color: white;
350
+ padding: 20px;
351
+ border-radius: 12px;
352
+ margin: 10px 0;
353
+ }
354
+ .footer-text {
355
+ color: white !important;
356
+ }
357
+ .footer-text h2, .footer-text h3 {
358
+ color: white !important;
359
+ }
360
+ .footer-text p, .footer-text li {
361
+ color: #e0e0e0 !important;
362
+ }
363
+ """
364
+ ) as app:
365
+
366
+
367
+ gr.Markdown(
368
+ """
369
+ # 🎬 Comprehensive Movie Recommendation System
370
+
371
+ **Advanced ML Approaches for Personalized Recommendations**
372
+
373
+ This system implements multiple state-of-the-art recommendation approaches including collaborative filtering,
374
+ matrix factorization, and neural embeddings using the MovieLens 100K dataset.
375
+ """,
376
+ elem_classes="main-header"
377
+ )
378
+
379
+ # Stats overview
380
+ with gr.Row():
381
+ with gr.Column():
382
+ stats_display = gr.Markdown(
383
+ get_user_stats(),
384
+ elem_classes="stats-card"
385
+ )
386
+
387
+ # Main tabs
388
+ with gr.Tabs():
389
+
390
+ # Recommendation Tab
391
+ with gr.Tab("🎯 Get Recommendations", id="recommendations"):
392
+ gr.Markdown("### Generate personalized movie recommendations using different ML approaches")
393
+
394
+ with gr.Row():
395
+ with gr.Column(scale=1):
396
+ user_dropdown = gr.Dropdown(
397
+ choices=get_available_users(),
398
+ label="πŸ‘€ Select User ID",
399
+ value=get_available_users()[0] if get_available_users() else None,
400
+ info="Choose from 943 available users"
401
+ )
402
+
403
+ num_recommendations = gr.Slider(
404
+ minimum=5,
405
+ maximum=20,
406
+ value=10,
407
+ step=1,
408
+ label="πŸ“Š Number of Recommendations",
409
+ info="How many movies to recommend"
410
+ )
411
+
412
+ method_dropdown = gr.Dropdown(
413
+ choices=[
414
+ ("🎯 Ensemble Method (Recommended)", "ensemble"),
415
+ ("πŸ‘₯ User-based Collaborative Filtering", "user_based"),
416
+ ("🎬 Item-based Collaborative Filtering", "item_based"),
417
+ ("πŸ“Š SVD Matrix Factorization", "svd"),
418
+ ("🧠 Neural Embeddings", "neural")
419
+ ],
420
+ value="ensemble",
421
+ label="πŸ”¬ Recommendation Method",
422
+ info="Choose the ML approach for recommendations"
423
+ )
424
+
425
+ recommend_btn = gr.Button("πŸš€ Get Recommendations", variant="primary", size="lg")
426
+
427
+ with gr.Column(scale=2):
428
+ recommendations_output = gr.Markdown(
429
+ "πŸ‘† Select a user and method to get personalized movie recommendations...",
430
+ label="🎬 Recommendations"
431
+ )
432
+
433
+ recommend_btn.click(
434
+ fn=recommend_movies,
435
+ inputs=[user_dropdown, num_recommendations, method_dropdown],
436
+ outputs=recommendations_output
437
+ )
438
+
439
+ # User Analysis Tab
440
+ with gr.Tab("πŸ‘€ User Analysis", id="analysis"):
441
+ gr.Markdown("### Analyze user preferences, rating patterns, and movie tastes")
442
+
443
+ with gr.Row():
444
+ with gr.Column(scale=1):
445
+ user_analysis_dropdown = gr.Dropdown(
446
+ choices=get_available_users(),
447
+ label="πŸ‘€ Select User ID",
448
+ value=get_available_users()[0] if get_available_users() else None,
449
+ info="Choose a user to analyze"
450
+ )
451
+
452
+ analyze_user_btn = gr.Button("πŸ” Analyze User", variant="primary", size="lg")
453
+
454
+ with gr.Column(scale=2):
455
+ user_info_output = gr.Markdown(
456
+ "πŸ‘† Select a user to analyze their preferences and rating patterns...",
457
+ label="πŸ“Š User Profile"
458
+ )
459
+
460
+ analyze_user_btn.click(
461
+ fn=get_user_info,
462
+ inputs=[user_analysis_dropdown],
463
+ outputs=user_info_output
464
+ )
465
+
466
+ # Method Comparison Tab
467
+ with gr.Tab("βš–οΈ Compare Methods", id="comparison"):
468
+ gr.Markdown("### Compare all recommendation methods side-by-side for a user")
469
+
470
+ with gr.Row():
471
+ with gr.Column(scale=1):
472
+ compare_user_dropdown = gr.Dropdown(
473
+ choices=get_available_users(),
474
+ label="πŸ‘€ Select User ID",
475
+ value=get_available_users()[0] if get_available_users() else None,
476
+ info="Choose a user to compare methods for"
477
+ )
478
+
479
+ compare_num_recs = gr.Slider(
480
+ minimum=5,
481
+ maximum=15,
482
+ value=10,
483
+ step=1,
484
+ label="πŸ“Š Number of Recommendations",
485
+ info="How many recommendations per method"
486
+ )
487
+
488
+ compare_btn = gr.Button("βš–οΈ Compare All Methods", variant="primary", size="lg")
489
+
490
+ with gr.Column(scale=2):
491
+ comparison_output = gr.Markdown(
492
+ "πŸ‘† Select a user to compare all recommendation methods...",
493
+ label="πŸ“ˆ Method Comparison"
494
+ )
495
+
496
+ compare_btn.click(
497
+ fn=compare_all_methods,
498
+ inputs=[compare_user_dropdown, compare_num_recs],
499
+ outputs=comparison_output
500
+ )
501
+
502
+
503
+ with gr.Tab("πŸ“Š System Evaluation", id="evaluation"):
504
+ gr.Markdown("### Evaluate system performance with comprehensive metrics")
505
+
506
+ with gr.Row():
507
+ with gr.Column(scale=1):
508
+ evaluate_btn = gr.Button("πŸ“Š Evaluate System Performance", variant="primary", size="lg")
509
+
510
+ with gr.Column(scale=2):
511
+ evaluation_output = gr.Markdown(
512
+ "πŸ‘† Click 'Evaluate System Performance' to see detailed metrics...",
513
+ label="πŸ“ˆ Performance Results"
514
+ )
515
+
516
+ evaluate_btn.click(
517
+ fn=evaluate_system_performance,
518
+ inputs=[],
519
+ outputs=evaluation_output
520
+ )
521
+
522
+ # Method Explanations Tab
523
+ with gr.Tab("πŸ”¬ Method Explanations", id="explanations"):
524
+ gr.Markdown("### Learn about each recommendation method and when to use them")
525
+
526
+ explanations_output = gr.Markdown(
527
+ get_method_explanations(),
528
+ label="πŸ“š Method Details"
529
+ )
530
+
531
+
532
+ gr.Markdown(
533
+ """
534
+ ---
535
+ ## πŸš€ About This System
536
+
537
+ This comprehensive recommendation system demonstrates multiple state-of-the-art approaches:
538
+
539
+ - **πŸ‘₯ Collaborative Filtering**: Both user-based and item-based methods
540
+ - **πŸ“Š Matrix Factorization**: SVD for dimensionality reduction
541
+ - **🧠 Neural Networks**: Deep learning embeddings for complex patterns
542
+ - **🎯 Ensemble Methods**: Combining multiple approaches for optimal performance
543
+
544
+ ### πŸ“ˆ Evaluation Metrics
545
+ - **Precision@K**: Fraction of recommended items that are relevant
546
+ - **Recall@K**: Fraction of relevant items that are recommended
547
+ - **NDCG@K**: Normalized Discounted Cumulative Gain for ranking quality
548
+
549
+ ### πŸŽ“ Educational Value
550
+ Perfect for learning about recommendation systems, machine learning approaches,
551
+ and interactive web application development.
552
+ """,
553
+ elem_classes="method-card footer-text"
554
+ )
555
+
556
+ return app
557
+
558
+
559
+ if __name__ == "__main__":
560
+ app = create_interface()
561
+ app.launch(
562
+ server_name="0.0.0.0",
563
+ server_port=7860,
564
+ share=True,
565
+ show_error=True
566
+ )