The data: feedback & the user-item matrix
Recommenders are only as good as the signal they learn from. This short chapter covers the two kinds of feedback and the data structure everything is built on — including a subtle point that trips up newcomers and experts alike.
Explicit vs. implicit feedback
Explicit feedback is when the user deliberately rates something: 5-star reviews, thumbs up/down, likes. It's clear but rare — most people never rate anything.
Implicit feedback is the user's behavior: clicks, views, watch time, purchases, dwell time. It's abundant (every interaction is a signal) but noisy and one-sided:
- A click isn't a guarantee of "like" (maybe a misleading title).
- No click is not a dislike. The user probably just never saw the item.
This asymmetry is the single most important fact about recommender data. With explicit ratings, a blank means "unknown". With implicit data, a
1means "some positive signal" and a blank means "no information" — not a negative. Algorithms must treat "missing" as "unknown", not "disliked". It's why implicit models use ideas like confidence weighting (Chapter 7) and negative sampling (Chapter 8) instead of pretending blanks are zeros-meaning-dislike.
Most real systems run on implicit feedback, so this book focuses there.
The user-item matrix
We organize interactions into a matrix R: rows = users, columns = items.
import numpy as np
def build_matrix(interactions, n_users, n_items):
"""interactions: list of (user, item, time). Returns a binary matrix R."""
R = np.zeros((n_users, n_items))
for u, i, t in interactions:
R[u, i] = 1.0 # 1 = interacted; 0 = no data (NOT 'disliked')
return R
R = build_matrix([(0, 0, 0), (0, 2, 1), (1, 1, 2), (2, 0, 3), (2, 1, 4)], 3, 4)
print(R)
Output:
[[1. 0. 1. 0.]
[0. 1. 0. 1.]
[1. 1. 0. 0.]]
User 0 interacted with items 0 and 2; user 1 with items 1 and 3; etc.
Sparsity
Real matrices are enormous and almost entirely empty. A site with 1M users and
1M items where each user touches 100 items has a matrix that is
$100 / 1{,}000{,}000 = 0.01%$ full. We never store it as a dense grid (that would
be a trillion cells) — we store only the interactions (the (user, item) pairs)
and use sparse math. This sparsity is also why recommendation is hard: we must
generalize from a vanishingly small set of observed cells.
Time matters
Interactions have timestamps, and they're gold:
- Recency: what you watched yesterday predicts tomorrow better than what you watched a year ago. We'll weight recent interactions more with time decay (Chapters 4 and 5).
- Evaluation: to imitate reality, we train on the past and test on the future. Throughout this book we hold out each user's chronologically last interaction as the test target (called leave-last-out) — never a random one, which would let the model "peek" at the future.
Other signals (briefly)
Beyond the interaction matrix, production systems fold in side features: item metadata (category, price, author), user attributes, and context (time of day, device, location). These are crucial for the ranking stage and for cold start, and we'll use item features directly in content-based filtering next.
With the data understood, the next question is how we judge whether a recommender is any good. 👉