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:
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 0Now 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:
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 similarityWho is like Alice?
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.90The 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.