Spaces:
Sleeping
Sleeping
Download comprehensive_recommendation_system.py from Rijeet/DataSynthis_ML_JobTask: direct link, hf CLI and curl.
- Browser
- Download file 28.8 kB
-
https://huggingface.co/spaces/Rijeet/DataSynthis_ML_JobTask/resolve/main/comprehensive_recommendation_system.py
- Command line
-
hf download hf://spaces/Rijeet/DataSynthis_ML_JobTask/comprehensive_recommendation_system.py
-
curl -L -o comprehensive_recommendation_system.py https://huggingface.co/spaces/Rijeet/DataSynthis_ML_JobTask/resolve/main/comprehensive_recommendation_system.py
28.8 kB
| """ | |
| Comprehensive Movie Recommendation System | |
| ======================================== | |
| This system implements multiple recommendation approaches: | |
| 1. User-based Collaborative Filtering | |
| 2. Item-based Collaborative Filtering | |
| 3. Matrix Factorization (SVD) | |
| 4. Neural Embeddings (Deep Learning) | |
| Author: DataSynthis ML Team | |
| Date: 2024 | |
| """ | |
| import pandas as pd | |
| import numpy as np | |
| import pickle | |
| import os | |
| from typing import List, Tuple, Dict, Optional | |
| from sklearn.metrics.pairwise import cosine_similarity | |
| from sklearn.decomposition import TruncatedSVD | |
| from sklearn.neural_network import MLPRegressor | |
| from sklearn.preprocessing import StandardScaler | |
| from sklearn.model_selection import train_test_split | |
| from sklearn.metrics import mean_squared_error, mean_absolute_error | |
| import matplotlib.pyplot as plt | |
| import seaborn as sns | |
| import warnings | |
| warnings.filterwarnings('ignore') | |
| class ComprehensiveRecommendationSystem: | |
| """ | |
| Comprehensive recommendation system implementing multiple approaches | |
| """ | |
| def __init__(self, data_path: str = None): | |
| """ | |
| Initialize the recommendation system | |
| Args: | |
| data_path: Path to the MovieLens dataset directory | |
| """ | |
| self.data_path = data_path | |
| self.ratings = None | |
| self.movies = None | |
| self.user_item_matrix = None | |
| self.user_similarity_matrix = None | |
| self.item_similarity_matrix = None | |
| self.svd_model = None | |
| self.neural_model = None | |
| self.scaler = None | |
| self.user_means = None | |
| self.item_means = None | |
| def load_data(self, ratings_file: str, movies_file: str): | |
| """ | |
| Load and preprocess the MovieLens dataset | |
| Args: | |
| ratings_file: Path to ratings file | |
| movies_file: Path to movies file | |
| """ | |
| print("Loading MovieLens dataset...") | |
| # Load ratings data - handle both CSV and tab-separated formats | |
| if ratings_file.endswith('.csv'): | |
| self.ratings = pd.read_csv(ratings_file) | |
| # Rename columns to standard format | |
| if 'userId' in self.ratings.columns: | |
| self.ratings = self.ratings.rename(columns={'userId': 'user_id', 'movieId': 'movie_id'}) | |
| else: | |
| # Handle tab-separated format (ml-100k) | |
| self.ratings = pd.read_csv( | |
| ratings_file, | |
| sep="\t", | |
| names=["user_id", "movie_id", "rating", "timestamp"] | |
| ) | |
| # Load movies data - handle both CSV and pipe-separated formats | |
| if movies_file.endswith('.csv'): | |
| self.movies = pd.read_csv(movies_file) | |
| # Rename columns to standard format | |
| if 'movieId' in self.movies.columns: | |
| self.movies = self.movies.rename(columns={'movieId': 'movie_id'}) | |
| # Select relevant columns for movies | |
| if 'title' in self.movies.columns: | |
| self.movies = self.movies[['movie_id', 'title']] | |
| else: | |
| # Fallback to first two columns if title column not found | |
| self.movies = self.movies.iloc[:, [0, 1]] | |
| self.movies.columns = ["movie_id", "title"] | |
| else: | |
| # Handle pipe-separated format (ml-100k) | |
| self.movies = pd.read_csv( | |
| movies_file, | |
| sep="|", | |
| encoding="latin-1", | |
| header=None | |
| ) | |
| # Select relevant columns for movies | |
| self.movies = self.movies[[0, 1]] | |
| self.movies.columns = ["movie_id", "title"] | |
| print(f"Ratings shape: {self.ratings.shape}") | |
| print(f"Movies shape: {self.movies.shape}") | |
| print(f"Unique users: {self.ratings['user_id'].nunique()}") | |
| print(f"Unique movies: {self.movies['movie_id'].nunique()}") | |
| print(f"Rating range: {self.ratings['rating'].min()} - {self.ratings['rating'].max()}") | |
| # Create user-item matrix | |
| self._create_user_item_matrix() | |
| def _create_user_item_matrix(self): | |
| """Create user-item rating matrix""" | |
| print("Creating user-item matrix...") | |
| self.user_item_matrix = self.ratings.pivot_table( | |
| index="user_id", | |
| columns="movie_id", | |
| values="rating" | |
| ).fillna(0) | |
| print(f"User-Item Matrix shape: {self.user_item_matrix.shape}") | |
| print(f"Sparsity: {(1 - (self.user_item_matrix != 0).sum().sum() / self.user_item_matrix.size) * 100:.2f}%") | |
| def train_user_based_cf(self): | |
| """Train user-based collaborative filtering""" | |
| print("Training user-based collaborative filtering...") | |
| # Compute user similarity matrix | |
| self.user_similarity_matrix = cosine_similarity(self.user_item_matrix) | |
| # Calculate user means for bias correction | |
| self.user_means = self.user_item_matrix.mean(axis=1) | |
| print("User-based CF trained successfully!") | |
| def train_item_based_cf(self): | |
| """Train item-based collaborative filtering""" | |
| print("Training item-based collaborative filtering...") | |
| # Compute item similarity matrix | |
| self.item_similarity_matrix = cosine_similarity(self.user_item_matrix.T) | |
| # Calculate item means for bias correction | |
| self.item_means = self.user_item_matrix.mean(axis=0) | |
| print("Item-based CF trained successfully!") | |
| def train_svd(self, n_components: int = 50): | |
| """Train SVD matrix factorization""" | |
| print(f"Training SVD with {n_components} components...") | |
| # Create a copy of the matrix for SVD | |
| matrix_for_svd = self.user_item_matrix.copy() | |
| # Replace 0s with user means for proper SVD | |
| user_means = matrix_for_svd.mean(axis=1) | |
| for user_id in matrix_for_svd.index: | |
| user_ratings = matrix_for_svd.loc[user_id] | |
| zero_mask = user_ratings == 0 | |
| matrix_for_svd.loc[user_id, zero_mask] = user_means[user_id] | |
| # Apply SVD | |
| self.svd_model = TruncatedSVD(n_components=n_components, random_state=42) | |
| self.svd_model.fit(matrix_for_svd) | |
| print("SVD trained successfully!") | |
| def train_neural_embeddings(self, hidden_layers: Tuple = (100, 50), max_iter: int = 100): | |
| """Train neural network for embeddings""" | |
| print("Training neural embeddings...") | |
| # Prepare data for neural network | |
| X = [] | |
| y = [] | |
| for user_id in self.user_item_matrix.index: | |
| for movie_id in self.user_item_matrix.columns: | |
| rating = self.user_item_matrix.loc[user_id, movie_id] | |
| if rating > 0: # Only use actual ratings | |
| X.append([user_id, movie_id]) | |
| y.append(rating) | |
| X = np.array(X) | |
| y = np.array(y) | |
| # Scale features | |
| self.scaler = StandardScaler() | |
| X_scaled = self.scaler.fit_transform(X) | |
| # Train neural network | |
| self.neural_model = MLPRegressor( | |
| hidden_layer_sizes=hidden_layers, | |
| max_iter=max_iter, | |
| random_state=42 | |
| ) | |
| self.neural_model.fit(X_scaled, y) | |
| print("Neural embeddings trained successfully!") | |
| def recommend_movies_user_based(self, user_id: int, N: int = 10, top_k: int = 10) -> pd.DataFrame: | |
| """ | |
| Generate recommendations using user-based collaborative filtering | |
| Args: | |
| user_id: ID of the user to recommend for | |
| N: Number of movies to recommend | |
| top_k: Number of similar users to consider | |
| Returns: | |
| DataFrame with recommended movies | |
| """ | |
| if user_id not in self.user_item_matrix.index: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Get user's ratings | |
| user_ratings = self.user_item_matrix.loc[user_id] | |
| rated_movies = set(user_ratings[user_ratings > 0].index) | |
| # Get all movies | |
| all_movies = set(self.user_item_matrix.columns) | |
| unrated_movies = all_movies - rated_movies | |
| if not unrated_movies: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Get similar users | |
| user_idx = list(self.user_item_matrix.index).index(user_id) | |
| similarities = self.user_similarity_matrix[user_idx] | |
| similar_users_idx = np.argsort(similarities)[::-1][1:top_k+1] | |
| # Predict ratings for unrated movies | |
| predictions = [] | |
| for movie_id in unrated_movies: | |
| predicted_rating = self._predict_rating_user_based(user_id, movie_id, similar_users_idx) | |
| if predicted_rating > 0: | |
| predictions.append({ | |
| 'movie_id': movie_id, | |
| 'predicted_rating': predicted_rating | |
| }) | |
| if not predictions: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Sort by predicted rating and get top-N | |
| predictions_df = pd.DataFrame(predictions) | |
| predictions_df = predictions_df.sort_values('predicted_rating', ascending=False).head(N) | |
| # Merge with movie information | |
| recommendations = predictions_df.merge( | |
| self.movies[['movie_id', 'title']], | |
| on='movie_id', | |
| how='left' | |
| ) | |
| return recommendations[['movie_id', 'title', 'predicted_rating']] | |
| def recommend_movies_item_based(self, user_id: int, N: int = 10, top_k: int = 10) -> pd.DataFrame: | |
| """ | |
| Generate recommendations using item-based collaborative filtering | |
| Args: | |
| user_id: ID of the user to recommend for | |
| N: Number of movies to recommend | |
| top_k: Number of similar items to consider | |
| Returns: | |
| DataFrame with recommended movies | |
| """ | |
| if user_id not in self.user_item_matrix.index: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Get user's ratings | |
| user_ratings = self.user_item_matrix.loc[user_id] | |
| rated_movies = set(user_ratings[user_ratings > 0].index) | |
| # Get all movies | |
| all_movies = set(self.user_item_matrix.columns) | |
| unrated_movies = all_movies - rated_movies | |
| if not unrated_movies: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Predict ratings for unrated movies | |
| predictions = [] | |
| for movie_id in unrated_movies: | |
| predicted_rating = self._predict_rating_item_based(user_id, movie_id, top_k) | |
| if predicted_rating > 0: | |
| predictions.append({ | |
| 'movie_id': movie_id, | |
| 'predicted_rating': predicted_rating | |
| }) | |
| if not predictions: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Sort by predicted rating and get top-N | |
| predictions_df = pd.DataFrame(predictions) | |
| predictions_df = predictions_df.sort_values('predicted_rating', ascending=False).head(N) | |
| # Merge with movie information | |
| recommendations = predictions_df.merge( | |
| self.movies[['movie_id', 'title']], | |
| on='movie_id', | |
| how='left' | |
| ) | |
| return recommendations[['movie_id', 'title', 'predicted_rating']] | |
| def recommend_movies_svd(self, user_id: int, N: int = 10) -> pd.DataFrame: | |
| """ | |
| Generate recommendations using SVD matrix factorization | |
| Args: | |
| user_id: ID of the user to recommend for | |
| N: Number of movies to recommend | |
| Returns: | |
| DataFrame with recommended movies | |
| """ | |
| if user_id not in self.user_item_matrix.index: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Get user's ratings | |
| user_ratings = self.user_item_matrix.loc[user_id] | |
| rated_movies = set(user_ratings[user_ratings > 0].index) | |
| # Get all movies | |
| all_movies = set(self.user_item_matrix.columns) | |
| unrated_movies = all_movies - rated_movies | |
| if not unrated_movies: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Predict ratings for unrated movies | |
| predictions = [] | |
| for movie_id in unrated_movies: | |
| predicted_rating = self._predict_rating_svd(user_id, movie_id) | |
| if predicted_rating > 0: | |
| predictions.append({ | |
| 'movie_id': movie_id, | |
| 'predicted_rating': predicted_rating | |
| }) | |
| if not predictions: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Sort by predicted rating and get top-N | |
| predictions_df = pd.DataFrame(predictions) | |
| predictions_df = predictions_df.sort_values('predicted_rating', ascending=False).head(N) | |
| # Merge with movie information | |
| recommendations = predictions_df.merge( | |
| self.movies[['movie_id', 'title']], | |
| on='movie_id', | |
| how='left' | |
| ) | |
| return recommendations[['movie_id', 'title', 'predicted_rating']] | |
| def recommend_movies_neural(self, user_id: int, N: int = 10) -> pd.DataFrame: | |
| """ | |
| Generate recommendations using neural embeddings | |
| Args: | |
| user_id: ID of the user to recommend for | |
| N: Number of movies to recommend | |
| Returns: | |
| DataFrame with recommended movies | |
| """ | |
| if user_id not in self.user_item_matrix.index: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Get user's ratings | |
| user_ratings = self.user_item_matrix.loc[user_id] | |
| rated_movies = set(user_ratings[user_ratings > 0].index) | |
| # Get all movies | |
| all_movies = set(self.user_item_matrix.columns) | |
| unrated_movies = all_movies - rated_movies | |
| if not unrated_movies: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Predict ratings for unrated movies | |
| predictions = [] | |
| for movie_id in unrated_movies: | |
| predicted_rating = self._predict_rating_neural(user_id, movie_id) | |
| if predicted_rating > 0: | |
| predictions.append({ | |
| 'movie_id': movie_id, | |
| 'predicted_rating': predicted_rating | |
| }) | |
| if not predictions: | |
| return pd.DataFrame(columns=['movie_id', 'title', 'predicted_rating']) | |
| # Sort by predicted rating and get top-N | |
| predictions_df = pd.DataFrame(predictions) | |
| predictions_df = predictions_df.sort_values('predicted_rating', ascending=False).head(N) | |
| # Merge with movie information | |
| recommendations = predictions_df.merge( | |
| self.movies[['movie_id', 'title']], | |
| on='movie_id', | |
| how='left' | |
| ) | |
| return recommendations[['movie_id', 'title', 'predicted_rating']] | |
| def recommend_movies(self, user_id: int, N: int = 10, method: str = "ensemble") -> pd.DataFrame: | |
| """ | |
| Main recommendation function with the required signature | |
| Args: | |
| user_id: ID of the user to recommend for | |
| N: Number of movies to recommend | |
| method: Recommendation method ('user_based', 'item_based', 'svd', 'neural', 'ensemble') | |
| Returns: | |
| DataFrame with recommended movies | |
| """ | |
| if method == "user_based": | |
| return self.recommend_movies_user_based(user_id, N) | |
| elif method == "item_based": | |
| return self.recommend_movies_item_based(user_id, N) | |
| elif method == "svd": | |
| return self.recommend_movies_svd(user_id, N) | |
| elif method == "neural": | |
| return self.recommend_movies_neural(user_id, N) | |
| elif method == "ensemble": | |
| return self._ensemble_recommendations(user_id, N) | |
| else: | |
| raise ValueError("Method must be 'user_based', 'item_based', 'svd', 'neural', or 'ensemble'") | |
| def _ensemble_recommendations(self, user_id: int, N: int) -> pd.DataFrame: | |
| """Combine recommendations from all methods""" | |
| # Get recommendations from all methods | |
| user_recs = self.recommend_movies_user_based(user_id, N*2) | |
| item_recs = self.recommend_movies_item_based(user_id, N*2) | |
| svd_recs = self.recommend_movies_svd(user_id, N*2) | |
| neural_recs = self.recommend_movies_neural(user_id, N*2) | |
| # Combine and average scores | |
| all_recs = [] | |
| movie_scores = {} | |
| for recs in [user_recs, item_recs, svd_recs, neural_recs]: | |
| for _, rec in recs.iterrows(): | |
| movie_id = rec['movie_id'] | |
| score = rec['predicted_rating'] | |
| if movie_id not in movie_scores: | |
| movie_scores[movie_id] = [] | |
| movie_scores[movie_id].append(score) | |
| # Average scores for each movie | |
| for movie_id, scores in movie_scores.items(): | |
| avg_score = np.mean(scores) | |
| all_recs.append({ | |
| 'movie_id': movie_id, | |
| 'predicted_rating': avg_score | |
| }) | |
| # Sort by average score and get top-N | |
| all_recs_df = pd.DataFrame(all_recs) | |
| all_recs_df = all_recs_df.sort_values('predicted_rating', ascending=False).head(N) | |
| # Merge with movie information | |
| recommendations = all_recs_df.merge( | |
| self.movies[['movie_id', 'title']], | |
| on='movie_id', | |
| how='left' | |
| ) | |
| return recommendations[['movie_id', 'title', 'predicted_rating']] | |
| def _predict_rating_user_based(self, user_id: int, movie_id: int, similar_users_idx: np.ndarray) -> float: | |
| """Predict rating using user-based collaborative filtering""" | |
| user_idx = list(self.user_item_matrix.index).index(user_id) | |
| movie_idx = list(self.user_item_matrix.columns).index(movie_id) | |
| numerator = 0.0 | |
| denominator = 0.0 | |
| for similar_user_idx in similar_users_idx: | |
| similar_user_id = self.user_item_matrix.index[similar_user_idx] | |
| rating = self.user_item_matrix.iloc[similar_user_idx, movie_idx] | |
| if rating > 0: | |
| similarity = self.user_similarity_matrix[user_idx, similar_user_idx] | |
| user_mean = self.user_means[similar_user_id] | |
| numerator += similarity * (rating - user_mean) | |
| denominator += abs(similarity) | |
| if denominator == 0: | |
| return 0.0 | |
| user_mean = self.user_means[user_id] | |
| predicted_rating = user_mean + (numerator / denominator) | |
| return max(0.0, min(5.0, predicted_rating)) | |
| def _predict_rating_item_based(self, user_id: int, movie_id: int, top_k: int) -> float: | |
| """Predict rating using item-based collaborative filtering""" | |
| user_ratings = self.user_item_matrix.loc[user_id] | |
| movie_idx = list(self.user_item_matrix.columns).index(movie_id) | |
| # Get similar items | |
| similarities = self.item_similarity_matrix[movie_idx] | |
| similar_items_idx = np.argsort(similarities)[::-1][1:top_k+1] | |
| numerator = 0.0 | |
| denominator = 0.0 | |
| for similar_item_idx in similar_items_idx: | |
| similar_movie_id = self.user_item_matrix.columns[similar_item_idx] | |
| rating = user_ratings[similar_movie_id] | |
| if rating > 0: | |
| similarity = similarities[similar_item_idx] | |
| item_mean = self.item_means[similar_movie_id] | |
| numerator += similarity * (rating - item_mean) | |
| denominator += abs(similarity) | |
| if denominator == 0: | |
| return 0.0 | |
| item_mean = self.item_means[movie_id] | |
| predicted_rating = item_mean + (numerator / denominator) | |
| return max(0.0, min(5.0, predicted_rating)) | |
| def _predict_rating_svd(self, user_id: int, movie_id: int) -> float: | |
| """Predict rating using SVD""" | |
| user_idx = list(self.user_item_matrix.index).index(user_id) | |
| movie_idx = list(self.user_item_matrix.columns).index(movie_id) | |
| # Transform user and movie to latent space | |
| user_latent = self.svd_model.transform(self.user_item_matrix.iloc[user_idx:user_idx+1])[0] | |
| movie_latent = self.svd_model.components_[:, movie_idx] | |
| # Predict rating | |
| predicted_rating = np.dot(user_latent, movie_latent) | |
| return max(0.0, min(5.0, predicted_rating)) | |
| def _predict_rating_neural(self, user_id: int, movie_id: int) -> float: | |
| """Predict rating using neural network""" | |
| # Prepare input | |
| X = np.array([[user_id, movie_id]]) | |
| X_scaled = self.scaler.transform(X) | |
| # Predict | |
| predicted_rating = self.neural_model.predict(X_scaled)[0] | |
| return max(0.0, min(5.0, predicted_rating)) | |
| def evaluate_model(self, test_users: List[int], method: str = "ensemble", N: int = 10) -> Dict: | |
| """ | |
| Evaluate model performance using precision@K, recall@K, and NDCG@K | |
| Args: | |
| test_users: List of user IDs to evaluate | |
| method: Recommendation method to evaluate | |
| N: Number of recommendations to generate | |
| Returns: | |
| Dictionary with evaluation metrics | |
| """ | |
| print(f"Evaluating {method} method on {len(test_users)} users...") | |
| precision_scores = [] | |
| recall_scores = [] | |
| ndcg_scores = [] | |
| for user_id in test_users: | |
| try: | |
| # Get recommendations | |
| recommendations = self.recommend_movies(user_id, N=N, method=method) | |
| recommended_movies = set(recommendations['movie_id'].values) | |
| # Get actual liked movies (rating >= 4) | |
| user_ratings = self.ratings[ | |
| (self.ratings['user_id'] == user_id) & | |
| (self.ratings['rating'] >= 4) | |
| ] | |
| liked_movies = set(user_ratings['movie_id'].values) | |
| if len(recommended_movies) == 0: | |
| precision_scores.append(0.0) | |
| recall_scores.append(0.0) | |
| ndcg_scores.append(0.0) | |
| continue | |
| # Calculate precision@K | |
| precision = len(recommended_movies & liked_movies) / len(recommended_movies) | |
| precision_scores.append(precision) | |
| # Calculate recall@K | |
| if len(liked_movies) > 0: | |
| recall = len(recommended_movies & liked_movies) / len(liked_movies) | |
| else: | |
| recall = 0.0 | |
| recall_scores.append(recall) | |
| # Calculate NDCG@K | |
| ndcg = self._calculate_ndcg(list(recommendations['movie_id']), liked_movies, N) | |
| ndcg_scores.append(ndcg) | |
| except Exception as e: | |
| print(f"Error evaluating user {user_id}: {str(e)}") | |
| precision_scores.append(0.0) | |
| recall_scores.append(0.0) | |
| ndcg_scores.append(0.0) | |
| return { | |
| 'precision': np.mean(precision_scores), | |
| 'recall': np.mean(recall_scores), | |
| 'ndcg': np.mean(ndcg_scores), | |
| 'std_precision': np.std(precision_scores), | |
| 'std_recall': np.std(recall_scores), | |
| 'std_ndcg': np.std(ndcg_scores), | |
| 'num_users': len(test_users) | |
| } | |
| def _calculate_ndcg(self, recommended: List[int], relevant: set, k: int = None) -> float: | |
| """Calculate Normalized Discounted Cumulative Gain""" | |
| if k is None: | |
| k = len(recommended) | |
| recommended = recommended[:k] | |
| if len(relevant) == 0: | |
| return 0.0 | |
| # Calculate DCG | |
| dcg = 0.0 | |
| for i, movie_id in enumerate(recommended): | |
| if movie_id in relevant: | |
| dcg += 1.0 / np.log2(i + 2) | |
| # Calculate IDCG | |
| idcg = 0.0 | |
| for i in range(min(len(relevant), len(recommended))): | |
| idcg += 1.0 / np.log2(i + 2) | |
| if idcg == 0: | |
| return 0.0 | |
| return dcg / idcg | |
| def train_all_models(self): | |
| """Train all recommendation models""" | |
| print("Training all recommendation models...") | |
| # Train user-based CF | |
| self.train_user_based_cf() | |
| # Train item-based CF | |
| self.train_item_based_cf() | |
| # Train SVD | |
| self.train_svd(n_components=50) | |
| # Train neural embeddings | |
| self.train_neural_embeddings(hidden_layers=(100, 50), max_iter=50) | |
| print("All models trained successfully!") | |
| def save_model(self, filepath: str): | |
| """Save the trained model""" | |
| model_data = { | |
| 'user_item_matrix': self.user_item_matrix, | |
| 'user_similarity_matrix': self.user_similarity_matrix, | |
| 'item_similarity_matrix': self.item_similarity_matrix, | |
| 'svd_model': self.svd_model, | |
| 'neural_model': self.neural_model, | |
| 'scaler': self.scaler, | |
| 'user_means': self.user_means, | |
| 'item_means': self.item_means, | |
| 'movies': self.movies, | |
| 'ratings': self.ratings | |
| } | |
| with open(filepath, 'wb') as f: | |
| pickle.dump(model_data, f) | |
| print(f"Model saved to {filepath}") | |
| def load_model(self, filepath: str): | |
| """Load a trained model""" | |
| with open(filepath, 'rb') as f: | |
| model_data = pickle.load(f) | |
| self.user_item_matrix = model_data['user_item_matrix'] | |
| self.user_similarity_matrix = model_data['user_similarity_matrix'] | |
| self.item_similarity_matrix = model_data['item_similarity_matrix'] | |
| self.svd_model = model_data['svd_model'] | |
| self.neural_model = model_data['neural_model'] | |
| self.scaler = model_data['scaler'] | |
| self.user_means = model_data['user_means'] | |
| self.item_means = model_data['item_means'] | |
| self.movies = model_data['movies'] | |
| self.ratings = model_data['ratings'] | |
| print(f"Model loaded from {filepath}") | |
| def main(): | |
| """Main function to demonstrate the comprehensive recommendation system""" | |
| print("Comprehensive Movie Recommendation System") | |
| print("=" * 50) | |
| # Initialize the system | |
| rec_system = ComprehensiveRecommendationSystem() | |
| # Load data | |
| rec_system.load_data("u.data", "u.item") | |
| # Train all models | |
| rec_system.train_all_models() | |
| # Test recommendations for a specific user | |
| test_user = 1 | |
| print(f"\nRecommendations for User {test_user}:") | |
| print("-" * 40) | |
| # Test different methods | |
| methods = ["user_based", "item_based", "svd", "neural", "ensemble"] | |
| for method in methods: | |
| print(f"\n{method.upper()} Method:") | |
| recommendations = rec_system.recommend_movies(test_user, N=5, method=method) | |
| print(recommendations) | |
| # Evaluate models | |
| print("\nEvaluating models...") | |
| print("-" * 40) | |
| # Select a sample of users for evaluation | |
| all_users = rec_system.ratings['user_id'].unique() | |
| test_users = np.random.choice(all_users, min(20, len(all_users)), replace=False) | |
| for method in methods: | |
| results = rec_system.evaluate_model(test_users, method=method, N=10) | |
| print(f"{method:12} | Precision: {results['precision']:.4f} | Recall: {results['recall']:.4f} | NDCG: {results['ndcg']:.4f}") | |
| # Save model | |
| rec_system.save_model("comprehensive_recommendation_model.pkl") | |
| return rec_system | |
| if __name__ == "__main__": | |
| rec_system = main() | |