Vocabulary for this course

The terms the chapters assume, in plain words. You can open this from any chapter.

cold start
The problem of recommending for a new user or a new item that has no interactions yet.
collaborative filtering
Recommending items by finding users with similar taste, or items that similar users liked, without reading item content.
explicit feedback
A signal where the user states a preference, such as a rating or a like, rather than one inferred from behaviour.
implicit feedback
A signal inferred from behaviour, such as a click, watch or purchase, that says something happened but not how much it was liked.
matrix factorisation
A method that gives each user and item a short list of learned numbers, so their match is the sum of products.
nDCG
A ranking score that gives more credit to relevant items near the top, then divides by the score of the best possible order.
popularity baseline
A list ordered by how many interactions each item has, used as the simple result every model must beat.
precision at k
The share of the first k items that are relevant, where k is the number of slots shown.
ranking
The second stage that orders a short list of candidates for one user, usually with a slower model.
recall at k
The share of all relevant items that appear in the first k positions.
relevance
How likely one user is to engage with one item; a ranking needs it per user, not as a global score.
retrieval
The first stage that cuts a large catalogue down to a few hundred candidates cheaply.
slot
One position on the screen that can hold an item; the fixed count of them limits how long a list can be.
two-tower retrieval
A design with one network for users and one for items, so the item side is computed before a request.

Recommender systems from the ground up

Collaborative filtering

Collaborative filtering needs no item features. It finds neighbours in the interaction matrix and lets the crowd stand in for the description.

Part 3 of 10

Intermediate16 min readBack to Courses

The matrix

Put users in rows and items in columns. Each cell is a rating or a count, and most cells are empty. Collaborative filtering (using the behaviour of other users) works from that matrix alone. Two users are similar if they rated the same items in a similar way. Two items are similar if the same users touched them.

The empty cells define the problem. A full matrix would make the job easy and pointless: if everyone had rated everything, sorting by rating would be enough. The recommender exists because the matrix is sparse (almost all of it is empty), and the empty cells are the ones the product wants to fill.

The values in the cells matter. A rating is a level. A count is an amount. A binary event is a fact. Mix them in one matrix, and the score becomes hard to read and easy to misuse. Comparing a cosine built on counts with one built on ratings has the same fault. Pick one meaning per matrix and say so.

User-based and item-based

User-based CF finds people like you and recommends what they liked. Item-based CF finds items like the ones you liked and recommends those. Item-based is usually more stable. Item neighbourhoods change more slowly than people do, and catalogues often hold fewer items than users.

Both are neighbourhood methods: pick k neighbours, weight what they say by similarity, and score the unseen items. The value of k is a trade between noise and over-smoothing. A handful of neighbours is noisy. Thousands of them turn every user into the global average.

The score is usually a weighted average, not a vote. For user-based CF, the score for an unseen item is the neighbours’ ratings weighted by similarity. Each user’s mean is often subtracted first, so a generous rater does not dominate. Mean-centring is the gap between “people like you rated this highly” and “people like you rate everything highly”.

Item-based neighbours with Surprise

from surprise import Dataset, KNNBasic

data = Dataset.load_builtin("ml-100k")
trainset = data.build_full_trainset()
algo = KNNBasic(k=40, sim_options={"name": "cosine", "user_based": False})
algo.fit(trainset)
print(algo.predict("196", "302").est)

Neighbours in a binary matrix

Run the item-item scorer and inspect the neighbours of each liked item. Then add a third liked item and see whether the recommendations become more or less diverse.

Output
Click "Run" to execute your code

Similarity, and what it hides

Cosine on the rating vectors, Jaccard on binary events, or Pearson correlation on centred ratings. Each answers a slightly different question. Jaccard ignores how much. Pearson ignores level and compares shape. Cosine sits in between and is the usual default.

All of them are inflated by popularity. Two items co-occur because both are popular, not because they belong together. Divide by the items’ base rates (how often each item appears at all). Without that step the ranking rediscovers the head of the catalogue and calls it a neighbourhood.

Shrinkage is the standard repair. Multiply a similarity by the number of shared users, divided by that number plus a constant. An overlap of one then counts for little, and an overlap of fifty counts for almost all of it. The constant is a prior: how much evidence you need before you trust a fluke.

A co-occurrence is not a cause. Two items bought together may simply both be cheap, both be promoted, or both be shown on the same page. Check the base rate before trusting the edge.

Sparsity is the real problem

A catalogue of a million items and a user with twenty interactions gives a matrix that is almost all empty. Only a tiny fraction of one percent is filled. Neighbourhoods computed on that little overlap are noisy. Many users have no usable neighbour at all, so the system quietly falls back to popularity.

The next chapter moves to latent factors for that reason. Latent factors (a short vector per user and per item) pool evidence across the whole matrix. They do not rely on direct overlap. Coverage — the share of users and items that can be scored at all — matters as much as accuracy. It is the number a neighbourhood model usually loses on.

Sparse data also makes evaluation noisy. A user with three test interactions can move the mean by a third. A single lucky hit can look like a breakthrough. Report the number of users behind a metric. Do not compare two models on a split where the gap is smaller than the variation between users. A confidence interval on the mean is cheap to compute. It is often wider than the gap between two candidates, which is a useful check before a release.

A weighted vote from neighbours

Run the prediction for the missing item, then lower k to one neighbour and see how much the estimate moves. A prediction built on one person is an anecdote.

Output
Click "Run" to execute your code

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

What does collaborative filtering use as its signal?