Chapter 2 · Part 1

Finding similar tastes

Collaborative filtering hinges on one question: how alike are two people's tastes? Once we can score that, recommending is easy — just borrow opinions from the people most like you. We'll measure it with cosine similarity, the same tool from the NumPy and semantic-search courses, with one important fix first.

Fix the "harsh vs generous" problem

Raw ratings lie a little. A generous rater gives everything 4s and 5s; a harsh one tops out at 3. That difference isn't taste — it's personality. So before comparing, we mean-center each user: subtract their own average, leaving only how much they liked each film relative to their own baseline. We center only over movies they actually rated:

recommender.py (continued)
seen = R > 0
means = R.sum(axis=1) / seen.sum(axis=1)     # each user's average, over rated movies
centered = np.where(seen, R - means[:, None], 0.0)   # subtract it; leave blanks at 0

Now a +2 means "loved it, for me" and a −2 means "disliked it, for me", no matter whether someone rates high or low overall.

Cosine similarity between users

Two users are similar if their centered rating vectors point the same way. Cosine similarity measures exactly that — the angle between two vectors — giving +1 for identical taste, 0 for unrelated, and −1 for opposite taste. Normalize each row to length 1, and a matrix multiply gives every pair at once:

recommender.py (continued)
norms = np.linalg.norm(centered, axis=1, keepdims=True)
unit = centered / np.where(norms == 0, 1, norms)   # length-1 rows (avoid /0)
similarity = unit @ unit.T                          # (6, 6) user-user similarity

Who is like Alice?

recommender.py (temporary test)
for j, name in enumerate(users):
  print(f"Alice vs {name:6s}: {similarity[0, j]:+.2f}")
Alice vs Alice : +1.00
Alice vs Bob   : +0.66
Alice vs Carol : +0.40
Alice vs Dave  : -0.80
Alice vs Eve   : -0.43
Alice vs Frank : -0.90

The algorithm found the two camps on its own. Alice lines up with Bob (+0.66) and Carol (+0.40) — her fellow sci-fi fans — and points away from the rom-com crowd (Frank at −0.90). Nobody labeled anyone a "sci-fi fan"; it fell out of the ratings. Those similarity scores are the weights we'll use to predict what Alice would think of a movie she hasn't seen.