17 · Capstone: an end-to-end recommender
Put the whole track together: build a rating matrix, leave-one-out split, train Funk-SVD, and beat the popularity baseline on precision@k and NDCG — then print real top-N recommendations for a user.
A real recommender is a pipeline, not a model: build the interaction matrix, split it honestly (leave-one-out per user so you test on a held-out item), train matrix factorization, evaluate ranking quality (precision@k, NDCG) against the popularity baseline you must beat, and only then serve top-N. The same four steps power every production system.
Without this:
Skip the held-out split and you 'evaluate' on data the model trained on — an inflated score that collapses in production. Skip the baseline and you can't tell whether your fancy model beats simply recommending whatever is popular.
This is the capstone — every piece of the track in one runnable pipeline. We will:
- Build a synthetic rating matrix with real latent structure (so there is a signal to learn) plus noise and sparsity.
- Split with leave-one-out: for each user, hide one observed rating as the test item, train on the rest. This is the honest way to test a recommender — you measure whether the held-out item lands near the top of the ranking.
- Train Funk-SVD (matrix factorization by SGD) on the training cells, learning user and item latent vectors plus biases.
- Evaluate ranking quality with precision@k (did the held-out item make the top-k?) and NDCG@k (did it land high?), and compare against the popularity baseline — the bar from Lesson 1. Matrix factorization should win, because it is personalized while popularity serves everyone the same list.
- Recommend the top-N unseen items for a sample user.
The cell below does all five in under ~55 lines. Read the printed numbers as a verdict: MF's precision@k and NDCG should exceed the popularity baseline's, proving personalization beats popularity.
Python (in browser)
The full pipeline in one cell: build → leave-one-out split → train Funk-SVD → evaluate precision@10 & NDCG@10 vs the popularity baseline (MF wins) → print top-5 recommendations.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Where to go next. You have built every recommender family from scratch — popularity, content-based, neighborhood and model-based collaborative filtering, matrix factorization, ranking evaluation, BPR for implicit feedback, and hybrids. To go further:
- Surprise — a scikit-style library for explicit-rating CF (SVD, SVD++, KNN) with built-in cross-validation; great for rating-prediction work.
- implicit — fast ALS / BPR for implicit feedback at scale (multithreaded, GPU).
- LightFM — hybrid factorization with WARP loss that ingests item/user features, directly attacking cold-start.
- Two-tower / deep recommenders — neural retrieval (a user tower and an item tower trained with a softmax/contrastive loss) power web-scale candidate generation at YouTube and friends; then a deep ranking model re-scores the shortlist.
- Sequential / session-based models (GRU4Rec, SASRec, BERT4Rec) model order, predicting the next item from a user's recent sequence.
- RecBole — a unified framework with 100+ recsys algorithms for benchmarking, so you can compare your ideas against the literature with a single config.
Every one of these still rests on the ideas you implemented by hand here: a sparse interaction matrix, latent factors, a sound train/test split, and ranking metrics. You now have the foundation to read their papers and use their code with understanding rather than as a black box.
The capstone done with Surprise (read-only): its SVD is the biased Funk-SVD you implemented by hand, wrapped in a clean train/test + RMSE API. Same math, production ergonomics.
In the capstone, why do we use a leave-one-out split AND compare matrix factorization against the popularity baseline?
- A recommender is a pipeline: build the matrix → leave-one-out split → train MF → evaluate ranking vs a baseline → serve top-N.
- Leave-one-out (hide one item per user) is the honest evaluation; precision@k and NDCG@k measure whether the held-out item ranks high.
- Matrix factorization beats the popularity baseline because it is personalized — and next steps (Surprise, implicit, LightFM, two-tower, RecBole) scale these same ideas.
Every production recommender — Netflix, Spotify, Amazon — is this exact pipeline scaled up: build interactions, split honestly, train, evaluate against baselines, serve top-N, then iterate.
If you remove it: Without the held-out split and baseline comparison, you ship a model with an inflated offline score that fails to beat 'just recommend popular' in production — the most common recsys failure.