Build a recommendation system using collaborative filtering and content-based approaches.
Build a system that recommends products or content based on user behavior and preferences.
Problem Overview
Objective: Recommend products users will likely purchase
Use Cases:
- Movie recommendations (Netflix)
- Product recommendations (Amazon)
- Song recommendations (Spotify)
- Article recommendations (Medium)
Approaches
1. Collaborative Filtering
Recommend based on similar users' preferences.
import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# User-Item ratings matrix
ratings = pd.DataFrame({
'user_id': [1, 1, 1, 2, 2, 2, 3, 3, 3],
'item_id': [1, 2, 3, 1, 3, 4, 2, 3, 4],
'rating': [5, 4, 2, 4, 5, 3, 3, 4, 5]
})
# Create matrix
matrix = ratings.pivot(index='user_id', columns='item_id', values='rating').fillna(0)
print(matrix)
# 1 2 3 4
# user_id
# 1 5.0 4.0 2.0 0.0
# 2 4.0 0.0 5.0 3.0
# 3 0.0 3.0 4.0 5.0
# Calculate user similarities
user_similarity = cosine_similarity(matrix)
def recommend_items(user_id, matrix, user_similarity, n_recommendations=3):
# Get similar users
similarities = user_similarity[user_id - 1]
similar_users = similarities.argsort()[-5:-1] # Top 4 similar (exclude self)
# Get items they rated highly but target user hasn't rated
target_user_rated = set(matrix.iloc[user_id - 1][matrix.iloc[user_id - 1] > 0].index)
# Score items based on similar users' ratings
item_scores = {}
for item_id in range(1, matrix.shape[1] + 1):
if item_id in target_user_rated:
continue
score = 0
for sim_user in similar_users:
if matrix.iloc[sim_user, item_id - 1] > 0:
score += user_similarity[user_id - 1, sim_user] * matrix.iloc[sim_user, item_id - 1]
item_scores[item_id] = score
# Return top items
recommendations = sorted(item_scores.items(), key=lambda x: x[1], reverse=True)[:n_recommendations]
return recommendations
# Usage
recs = recommend_items(1, matrix, user_similarity)
print(f"Recommendations for user 1: {recs}")
2. Content-Based Filtering
Recommend based on item similarity.
# Item features matrix
items = pd.DataFrame({
'item_id': [1, 2, 3, 4],
'genre_action': [1, 0, 1, 0],
'genre_comedy': [0, 1, 1, 1],
'director_A': [1, 0, 0, 1],
'rating': [8.5, 7.0, 8.0, 6.5]
})
# Calculate item similarity
item_features = items.drop(['item_id', 'rating'], axis=1)
item_similarity = cosine_similarity(item_features)
def recommend_similar_items(item_id, item_similarity, n_recommendations=3):
similarities = item_similarity[item_id - 1]
similar_items = similarities.argsort()[-n_recommendations-1:-1]
return [(i + 1, similarities[i]) for i in similar_items]
# Usage
similar = recommend_similar_items(1, item_similarity)
print(f"Items similar to item 1: {similar}")
3. Matrix Factorization
from sklearn.decomposition import NMF
# Non-negative matrix factorization
model = NMF(n_components=5, random_state=42, max_iter=500)
W = model.fit_transform(matrix) # User factors
H = model.components_ # Item factors
# Predict ratings
predicted_ratings = np.dot(W, H)
def recommend_from_factorization(user_id, predicted_ratings, matrix, n=3):
# Get items not rated by user
unrated = matrix.iloc[user_id - 1] == 0
# Score unrated items
scores = predicted_ratings[user_id - 1][unrated]
recommendations = np.argsort(scores)[-n:][::-1]
return [(i + 1, scores[i]) for i in recommendations]
# Usage
recs = recommend_from_factorization(1, predicted_ratings, matrix)
print(f"Recommendations using MF: {recs}")
Complete Recommender System
class RecommendationSystem:
def __init__(self, ratings_df):
self.ratings = ratings_df
self.matrix = ratings_df.pivot(index='user_id', columns='item_id', values='rating').fillna(0)
self.user_similarity = cosine_similarity(self.matrix)
def recommend_collaborative(self, user_id, n=5):
"""Collaborative filtering recommendations"""
similarities = self.user_similarity[user_id - 1]
similar_users = similarities.argsort()[-6:-1]
# Score items
user_rated = set(self.matrix.iloc[user_id - 1][self.matrix.iloc[user_id - 1] > 0].index)
item_scores = {}
for item_id in range(1, self.matrix.shape[1] + 1):
if item_id in user_rated:
continue
score = sum(
self.user_similarity[user_id - 1, sim] * self.matrix.iloc[sim, item_id - 1]
for sim in similar_users
)
if score > 0:
item_scores[item_id] = score
return sorted(item_scores.items(), key=lambda x: x[1], reverse=True)[:n]
def evaluate(self, test_ratings, k=5):
"""Evaluate recommendation quality"""
from sklearn.metrics import mean_squared_error
predictions = []
actuals = []
for _, row in test_ratings.iterrows():
user_id, item_id, actual_rating = row['user_id'], row['item_id'], row['rating']
# Get prediction
pred = np.dot(self.user_similarity[user_id - 1],
self.matrix[:, item_id - 1])
predictions.append(pred)
actuals.append(actual_rating)
rmse = np.sqrt(mean_squared_error(actuals, predictions))
print(f"RMSE: {rmse:.3f}")
# Usage
rs = RecommendationSystem(ratings)
recs = rs.recommend_collaborative(1, n=5)
print(f"Top 5 recommendations: {recs}")
Flask API
from flask import Flask, request, jsonify
app = Flask(__name__)
rs = RecommendationSystem(ratings)
@app.route('/recommend/<int:user_id>', methods=['GET'])
def get_recommendations(user_id):
n = request.args.get('n', 5, type=int)
recommendations = rs.recommend_collaborative(user_id, n=n)
return jsonify({
'user_id': user_id,
'recommendations': [
{'item_id': item_id, 'score': float(score)}
for item_id, score in recommendations
]
})
if __name__ == '__main__':
app.run()
Evaluation Metrics
def evaluate_recommendations(true_items, predicted_items, k=5):
"""Calculate recommendation metrics"""
from sklearn.metrics import precision_score, recall_score
# Precision@K: % of top-k recommendations that are relevant
pred_set = set(predicted_items[:k])
true_set = set(true_items)
precision = len(pred_set & true_set) / len(pred_set)
# Recall@K: % of relevant items in top-k
recall = len(pred_set & true_set) / len(true_set)
# NDCG@K: penalizes errors at top
ndcg = calculate_ndcg(predicted_items, true_items, k)
return {'precision': precision, 'recall': recall, 'ndcg': ndcg}
Summary
This project teaches:
- Collaborative filtering
- Content-based filtering
- Matrix factorization
- Recommendation evaluation metrics
- Production recommendation system