Recommendation Systems
Recommendation systems suggest relevant items to users — powering Netflix, Spotify, and Amazon. They fall into two families: content-based filtering (recommend items similar to what you liked) and collaborative filtering (recommend what users like you enjoyed).
Content-Based
Uses item features (genres, keywords) to find similar items. No data from other users required.
Collaborative Filtering
Uses user–item ratings. Finds users with similar taste and recommends what they liked.
Content-Based Filtering
Using the MovieLens dataset (9,742 movies), each movie is represented as a binary genre vector. Movies with similar genre vectors are considered similar.
One-Hot Encode Genres
import pandas as pd
movies = pd.read_csv('movies.csv') # columns: movieId, title, genres
# Collect all unique genres
all_genres = set()
for g in movies['genres']:
all_genres.update(g.split('|'))
# Create a binary column for each genre
for genre in all_genres:
movies[genre] = movies['genres'].apply(
lambda x: 1 if genre in x.split('|') else 0
)
print(movies[['title', 'Action', 'Comedy', 'Drama']].head())
Recommend Similar Movies
from sklearn.metrics.pairwise import cosine_similarity
genre_cols = list(all_genres)
sim_matrix = cosine_similarity(movies[genre_cols])
def get_recommendations(title, n=5):
idx = movies[movies['title'] == title].index[0]
scores = sorted(enumerate(sim_matrix[idx]), key=lambda x: x[1], reverse=True)[1:n+1]
return movies.iloc[[i for i, _ in scores]]['title'].tolist()
print(get_recommendations('Toy Story (1995)'))
Cosine Similarity
NotebookCosine similarity measures the angle between two vectors. A value of 1 = identical, 0 = no overlap, -1 = opposite.
// Formula
cos(θ) = (A · B) / (‖A‖ × ‖B‖)
import numpy as np
def cosine_sim(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
# Genre vectors: [Action, Animation, Children, Comedy, Fantasy]
toy_story = [0, 1, 1, 1, 1]
shrek = [0, 1, 1, 1, 1]
die_hard = [1, 0, 0, 0, 0]
print(cosine_sim(toy_story, shrek)) # 1.0 — identical genres
print(cosine_sim(toy_story, die_hard)) # 0.0 — no overlap
Collaborative Filtering
Collaborative filtering uses a user–item rating matrix. We use KNN on 100,836 ratings from 610 users with cosine distance to find similar movies.
Build the Rating Matrix
from scipy.sparse import csr_matrix
ratings = pd.read_csv('ratings.csv') # userId, movieId, rating
def create_matrix(df):
user_mapper = {u: i for i, u in enumerate(df['userId'].unique())}
movie_mapper = {m: i for i, m in enumerate(df['movieId'].unique())}
movie_inv = {v: k for k, v in movie_mapper.items()}
user_idx = [user_mapper[u] for u in df['userId']]
movie_idx = [movie_mapper[m] for m in df['movieId']]
X = csr_matrix((df['rating'], (movie_idx, user_idx)))
return X, movie_mapper, movie_inv
X, movie_mapper, movie_inv = create_matrix(ratings)
KNN Movie Recommendations
from sklearn.neighbors import NearestNeighbors
knn = NearestNeighbors(n_neighbors=6, algorithm='brute', metric='cosine')
knn.fit(X)
def similar_movies(movie_id, k=5):
idx = movie_mapper[movie_id]
_, indices = knn.kneighbors(X[idx], n_neighbors=k+1)
return [movie_inv[i] for i in indices.flatten()[1:]]
print(similar_movies(1)) # Movies similar to Toy Story
Cold Start Problem
Collaborative filtering fails for new users (no ratings) or new items. Content-based filtering handles this — real systems combine both (hybrid recommenders).
Live Demo — Genre-Based Recommender
Select the genres you enjoy and click Find Movies. The recommender builds your preference vector and returns the top matches using cosine similarity — exactly like a real content-based system.
Your Genre Preferences
Knowledge Check
Test your understanding — pick the best answer, then click Check.
1. What does cosine similarity measure?
2. What is the cold start problem?
3. What is the key difference between content-based and collaborative filtering?