Before you start: review of the earlier sessions
The thread so far. Session 11 is the first industrial-scale application in the course: the link-prediction machinery of sessions 2 and 5 plus the simplified GNN of session 4, on a two-type graph from session 9.
What this session takes from earlier ones
Those sessions in one minute each
Lecture 10 · Knowledge Graph Embeddings
A KG embedding turns each relation into a geometric operation; the algebra of that operation (commutative or not, invertible or not, composable or not) decides which logical patterns of relations the model can represent.
Lecture 5 · GNN Augmentation and Training
Choose the computation graph deliberately (features, virtual nodes, sampling), pick the head that matches the task level, and split so that information from validation/test can never leak into training through message passing.
Define similarity by co-occurrence on short random walks, then learn one vector per node so that dot products reproduce it — fast with negative sampling, but just a lookup table.
\(N_R(u)\): multiset of nodes visited by walks from \(u\) under strategy \(R\) (uniform for DeepWalk, \(p,q\)-biased for node2vec); \(n_i\): negatives sampled ∝ degree; \(\sigma\): sigmoid.
Lecture 4 · A General Perspective on GNNs
A GNN layer is "message, then order-free aggregation (including yourself)"; architectures differ in how neighbours are weighted, and depth must be matched to the receptive field you need because too many layers smooth everything into one vector.
GCN is the special case \(\alpha_{vu}=1/|N(v)|\) (fixed); GAT learns \(e_{vu}=a(\mathbf{W}\mathbf{h}_u,\mathbf{W}\mathbf{h}_v)\).
Warm-up: answer these before you read on
What does "1-to-N" mean and which models handle it? from Lecture 10
One head and relation with many true tails (a person's students); TransE collapses all tails to one point, TransR and DistMult can keep them apart.
What is the difference between a transductive and an inductive split? from Lecture 5
Transductive: one graph, all nodes visible, only labels are split. Inductive: separate graphs (or subgraphs) for training and test, so test nodes are never seen.
Give the three limits of shallow embeddings. from Lecture 2
No parameter sharing (one vector per node), no use of node features, and no embedding for nodes unseen at training time (transductive).
Why add MLP layers before and after message passing? from Lecture 4
Pre-processing encodes rich input features (text, images); post-processing lets the model reason over the embedding, e.g. for graph classification, without adding more hops.
More questions from every session you have reached, with spaced repetition: the cumulative review.
In short
Netflix has 10K+ movies, Amazon hundreds of millions of products, Pinterest 200B+ pins. A recommender suggests a small number \(K\) of items per user. Model it as a bipartite graph (users, items, interaction edges with timestamps) and the task becomes link prediction: score \(f(u,v)\) for every user–item pair and recommend the top-\(K\) not yet interacted.
The metric is Recall@K, which isn't differentiable, so we train with a surrogate loss. The binary loss compares all positives against all negatives across users — too strict. BPR (Bayesian Personalized Ranking) only asks that, for each user, positives outrank negatives — matching the personalised metric.
Why embeddings work: collaborative filtering — similar users like similar items, and low-dimensional embeddings are forced to capture that similarity. NGCF runs a GNN over learnable embeddings to capture high-order paths; LightGCN discovers that the GNN's weights and non-linearities are unnecessary: just diffuse embeddings with the normalised adjacency and average the layers — simpler and better. PinSage shows how to do this with rich features at billion scale, using shared and curriculum-hardened negative samples.
The picture: LightGCN in one diagram
How to read it (hover a step)
- Users and items form a bipartite graph; its adjacency has the interaction matrix \(R\) in the off-diagonal blocks.
- Start from learnable shallow embeddings \(E^{(0)}\) (all the parameters are here). Diffuse: \(E^{(k+1)}=\tilde A E^{(k)}\) — each multiplication spreads embeddings one hop.
- Average the layers: \(E_{\text{final}}=\frac{1}{K+1}\sum_k E^{(k)}\) (multi-scale; \(E^{(0)}\) acts as a self-connection).
- Score with a dot product; train the shallow embeddings end-to-end with the BPR loss.
1 · The recommendation task and Recall@K
Given past user–item interactions, predict new items each user will interact with — link prediction on the bipartite graph. We need a real-valued score \(f(u,v)\) for \(u\in U, v\in V\).
Scoring every pair is impossible at scale, so production systems use a 2-stage process: candidate generation (cheap: nearest-neighbour search over item embeddings with the user embedding, e.g. \(f(u,v)=z_u\cdot z_v\) → ~1000 candidates) then ranking (slow, accurate model → top-10).
Recall@K for user \(u\): \(P_u\) = items the user will interact with in the future (positives), \(R_u\) = the \(K\) recommended items (excluding already-interacted ones). Recall@K \(=|P_u\cap R_u|/|P_u|\), averaged over users. \(K\) is typically 10–100, tiny compared with billions of items.
The slides also show H&M fashion recommendation: a GNN beats an LLM-based recommender by 2–40× on several metrics (slide 12) — structure matters even in the LLM era.
2 · Embedding models and surrogate losses
An embedding-based model has three kinds of parameters: a user encoder, an item encoder, and a score function \(f_\theta(\mathbf u,\mathbf v)\). Recall@K isn't differentiable, so train on a surrogate.
Binary loss
\[ -\frac{1}{|E|}\sum_{(u,v)\in E}\log\sigma(f_\theta(\mathbf u,\mathbf v))-\frac{1}{|E_{neg}|}\sum_{(u,v)\in E_{neg}}\log\big(1-\sigma(f_\theta(\mathbf u,\mathbf v))\big) \]It pushes all positive edges above all negative edges — across users. That's non-personalised, while recall is per user: the loss penalises models that already have perfect recall.
Two users, two items. Scores: \((u_0,v_0)=1.0\) ✓, \((u_0,v_1)=-1.0\), \((u_1,v_0)=2.0\), \((u_1,v_1)=4.0\) ✓. Recall@1? Does the binary loss complain?
Recall@1 = 1.0: \(u_0\)'s top item is \(v_0\) and \(u_1\)'s is \(v_1\), both positives. But the binary loss still penalises the model, because the negative \((u_1,v_0)\) with score 2.0 beats the positive \((u_0,v_0)\) with score 1.0. Cross-user comparisons are irrelevant for recommendation — which is why we need a personalised loss.
BPR loss (Rendle et al., 2009)
For each user \(u^*\), compare only that user's positives \(E(u^*)\) with that user's negatives \(E_{neg}(u^*)\):
Mini-batch: sample users; for each, one positive and a set of negatives; average. ("Bayesian" refers to a prior on parameters in the original paper — essentially regularisation — and isn't essential.)
Why embeddings work: collaborative filtering
Recommend items to a user by collecting preferences of similar users; similar users prefer similar items. Low-dimensional embeddings cannot memorise all interactions, so they are forced to capture similarity — which generalises to unseen interactions.
3 · NGCF: make embeddings explicitly graph-aware
Conventional collaborative filtering (matrix factorisation): shallow embeddings, score \(\mathbf z_u^\top\mathbf z_v\). The graph appears only implicitly, through the training objective, and only first-order structure (edges) is used — no multi-hop paths.
NGCF (Wang et al., 2019): use the shallow embeddings as initial features \(\mathbf h^{(0)}\), then a multi-layer GNN along the bipartite graph: \(\mathbf h_v^{(k+1)}=\text{COMBINE}(\mathbf h_v^{(k)},\text{AGGR}(\{\mathbf h_u^{(k)}\}_{u\in N(v)}))\) (e.g. AGGR = mean, COMBINE = ReLU(Linear(Concat))). After \(K\) rounds, score \(\mathbf u^\top\mathbf v\) with the final embeddings. Two parameter sets are learned jointly: shallow embeddings and GNN weights.
4 · LightGCN: simpler and better
Observation: with \(N\gg D\), almost all parameters are in the shallow embeddings (\(O(ND)\)) versus the GNN (\(O(D^2)\)). Maybe the GNN weights aren't essential. Simplify:
- Bipartite adjacency \(A=\begin{pmatrix}0&R\\R^\top&0\end{pmatrix}\); normalised \(\tilde A=D^{-1/2}AD^{-1/2}\) (no self-loop, unlike GCN).
- A GCN layer is \(E^{(k+1)}=\text{ReLU}(\tilde AE^{(k)}W^{(k)})\). Remove ReLU (idea from SGC, Wu et al. 2019): \(E^{(K)}=\tilde A^K E\,W^{(0)}\cdots W^{(K-1)}=\tilde A^KEW\).
- The \(W\) can be absorbed into the learnable \(E\) — drop it. Algorithm: apply \(E\leftarrow\tilde AE\) \(K\) times (never materialise the dense \(\tilde A^K\)).
- Multi-scale: \(E_{\text{final}}=\sum_k\alpha_kE^{(k)}\) with \(\alpha_k=\frac{1}{K+1}\).
Why does plain diffusion work? It directly makes similar users/items similar: users who share many items get averaged with the same neighbours. Compared with GCN, LightGCN uses the same \(1/\sqrt{d_ud_v}\) weights but no self-loop and averages layers. Compared with matrix factorisation, both learn one embedding per node, but LightGCN scores with diffused embeddings — better accuracy, more compute.
5 · PinSage: GNN recommendations at Pinterest scale
PinSage (Ying et al., 2018): the largest industrial GCN deployment at the time. It unifies visual, textual and graph information and embeds fresh pins seconds after creation. Graph: pins and boards, at the scale of billions of nodes and tens of billions of edges (the paper reports 3 billion nodes and 18 billion edges). Key idea: borrow information from nearby nodes — a bed rail pin may look like a garden fence, but gates and beds are rarely adjacent in the graph.
Task: related-pin recommendation — learn \(z_i\) with \(d(z_{cake1},z_{cake2})<d(z_{cake1},z_{sweater})\). Training data: 1+ billion repin pairs. Scaling tricks:
- Shared negative samples across all users in a mini-batch: only \(|V_{neg}|\) negative embeddings instead of \(|U_{mini}|\cdot|V_{neg}|\) — a \(|U_{mini}|\)-fold saving with similar accuracy.
- Hard negatives: random negatives are too easy when choosing 10 out of billions. Hard negatives = items close but not connected to the user: run random walk with restart from \(u\), rank by visit count, sample from ranks ~2000–5000.
- Curriculum learning: at epoch \(n\), add \(n-1\) hard negatives — negatives get gradually harder.
- Mini-batch training of GNNs on huge graphs (neighbour sampling, producer–consumer pipelines).
The mathematics, step by step
A recommender is link prediction on a bipartite graph of users and items, judged per user by what appears in the top \(K\). The formulas answer three questions in turn: what is measured, what is optimised instead (because the measure has no gradient), and how the graph enters the embeddings.
Symbols used in this session
| symbol | meaning | what kind of object |
|---|---|---|
| \(u,\ v\) | a user; an item | nodes of the two sides of the bipartite graph |
| \(P_u\) | the items user \(u\) will actually interact with (held-out positives) | set of items |
| \(R_u\) | the \(K\) items recommended to \(u\) | set of \(K\) items |
| \(f_\theta(\mathbf u,\mathbf v)\) | score of the pair; in this lecture the dot product \(\mathbf z_u^\top\mathbf z_v\) | real number |
| \(E,\ E_{neg}\) | observed user–item edges; sampled non-edges | sets of pairs |
| \(\mathbf e_u^{(k)},\ \mathbf e_i^{(k)}\) | embedding of user \(u\) / item \(i\) after \(k\) propagation steps; \(k=0\) is the learned table | vectors |
| \(d_u,\ d_i\) | degree: number of items of the user, number of users of the item | whole numbers |
| \(\tilde A\) | normalised adjacency matrix \(D^{-1/2}AD^{-1/2}\) of the user–item graph | symmetric matrix |
| \(\sigma\) | sigmoid, \(\sigma(x)=1/(1+e^{-x})\) | function |
1Recall@K
In words. For each user: of the items they really went on to interact with, what share is in the list of \(K\) recommendations? Average over users.
Why it has this form. Only the top \(K\) is shown to a user, so only membership in that list matters, not the exact scores. Dividing by \(|P_u|\) makes a user with 3 future items and one with 300 count equally. The quantity changes only when an item crosses the boundary of the top \(K\): it is piecewise constant in the model's parameters, its gradient is zero almost everywhere, and it cannot be trained on directly.
Watch out. Recall@K rises with \(K\) by construction, and it ignores the order inside the top \(K\); NDCG@K is the companion metric that rewards putting hits near the top.
2Two surrogate losses: binary and BPR
In words. Binary loss: push the scores of all observed pairs up and of all sampled non-pairs down, on one common scale. BPR: for one user, the score of an item they chose should exceed the score of an item they did not, and only the difference matters.
Why it has this form. The binary loss compares scores across users: it penalises user A's positive for scoring below user B's negative, although the two never appear in the same list. Recall@K is computed per user, so that effort is wasted. BPR looks at one user at a time. \(\sigma\) of the difference is the model's probability that the positive is ranked above the negative; minus its logarithm is small when the order is right by a wide margin. Averaging over a user's positive–negative pairs and then over users gives the full BPR loss.
Watch out. A 'negative' is only an item the user has not interacted with yet. Some of them are exactly the items a good recommender should suggest.
3LightGCN: propagation without weights
In words. A user's next embedding is the sum of its items' embeddings, each divided by the square roots of the two degrees; items are updated from their users in the same way. The final embedding is the average over all propagation depths, including depth 0.
Why it has this form. There is no weight matrix and no non-linearity: the only parameters are the starting table \(E^{(0)}\). The reason is that users and items have no input features, only identities, so transforming the embeddings adds nothing a different table could not provide, and it was found to hurt. The normalisation \(1/\sqrt{d_ud_i}\) keeps the scale stable and discounts very popular items. Averaging over depths is a fixed skip connection: depth 0 keeps the node's own identity, depth 1 its direct interactions, depth 2 users with similar taste, and the average resists over-smoothing.
Watch out. The score \(\mathbf z_u^\top\mathbf z_v\) uses the final, averaged embeddings; gradients flow through the fixed matrix powers back to \(E^{(0)}\), so the table is trained with the graph already built in.
4What NGCF had, and what LightGCN removed
In words. NGCF's layer is LightGCN's sum with three additions: a weight matrix on every message, an extra term that multiplies the item's and the user's embeddings coordinate by coordinate, and a non-linearity.
Why it has this form. Set \(W_1=I\), \(W_2=0\), drop the self term and the LeakyReLU, and the formula becomes card 3. LightGCN's authors removed these parts one at a time and the recommendation quality went up each time. With free embeddings as the only input, the matrices and the non-linearity mostly make optimisation harder. This is a statement about recommendation with ID embeddings, not about GNNs with real node features.
Watch out. The simplification is not free in every setting: when items have rich features (text, images), as in PinSage, transformations of those features are needed again.
Check yourself
Questions from the lecture, in order. Answer each one in your head (or on paper) before you open it. If one stumps you, follow the link to the walkthrough block it comes from.
Check yourself: a user will buy items \(\{a,b,c,d\}\) and you recommend \(\{a,x,c\}\) with \(K=3\). Recall@3 = 2/4 = 0.5. Why is recall, not precision, the natural choice here? show answer
Because \(K\) is fixed and small, while \(|P_u|\) varies; recall asks "how much of what the user wants did we catch?"
from Top-K recommendation and Recall@K
Check yourself: in matrix factorisation, two users who never share an item can still get similar embeddings. How? show answer
Through a chain: \(u_1\) shares items with \(u_2\), \(u_2\) shares items with \(u_3\). The loss sees only edges, so this multi-hop effect emerges slowly and indirectly through optimisation; a GNN builds it into the forward pass.
from Limits of shallow collaborative filtering
Check yourself: with \(K=0\), what is LightGCN? show answer
Plain matrix factorisation. With \(K=1\), the user embedding is \(\frac12(\mathbf e_u+\sum_{v\in N(u)}\mathbf e_v/\sqrt{d_ud_v})\): the user's own vector blended with a degree-normalised sum of its items.
Lecture walkthrough reference · slide by slide · opens on demand
The whole lecture in order, grouped by topic. Every drawing on the slides is redrawn here as a clean figure (click the step buttons where a figure has them), the heading of each block links to the matching pages of the official PDF, and the Review section after the walkthrough ties this session to the earlier ones. Read this and you do not need the deck.
- Recommendation as link prediction on a bipartite graph
- Top-K recommendation and Recall@K
- Embedding-based models: notation, score, parameters
- Surrogate losses and the binary loss
- Why the binary loss is too strict
- Bayesian Personalized Ranking (BPR) loss
- Why embeddings work: collaborative filtering
- Limits of shallow collaborative filtering
- Neural Graph Collaborative Filtering (NGCF)
- LightGCN: from GCN to linear diffusion
- LightGCN: the model, intuition and comparisons
- PinSAGE: graph embeddings at Pinterest
- PinSAGE training: task, data and shared negatives
- Hard negatives and curriculum learning
- PinSAGE results and summary
Recommendation as link prediction on a bipartite graph slides 5-8 ↗
Slide 5 motivates the topic with the information explosion of the Internet era: 10K+ movies on Netflix, 12M products on Amazon (350M on Marketplace), 70M+ music tracks on Spotify, 10B+ videos on YouTube, 200B+ pins (images) on Pinterest. No user can browse this. Personalized recommendation, which means suggesting a small number of interesting items to each user, is what lets users find the content they care about.
Slide 6: a recommender system is naturally a bipartite graph.
- Two node types: users and items.
- Edges connect users and items only. An edge means a user–item interaction (click, purchase, review, …).
- Edges often carry a timestamp (when the interaction happened).
Slide 7 states the task. Given the past user–item interactions, predict the new items each user will interact with in the future. This is a link prediction problem: predict new user–item edges from the past edges (the figure shows a bipartite graph with dashed "?" edges from one user). Concretely, for \(u\in U\) and \(v\in V\) we need a real-valued score \(f(u,v)\).
Slide 8 raises a practical problem: we cannot evaluate \(f(u,v)\) for every user–item pair (millions of users times millions of items). The solution is a 2-stage process:
- Candidate generation (cheap, fast). The user embedding is sent to a nearest-neighbour (NN) search engine over the embeddings of millions of items, which returns about 1000 candidate items. An example score here is \(f(u,v)=z_u\cdot z_v\).
- Ranking (slow, accurate). Score and rank only the candidates with \(f(u,v)\) and return the top-10 items as recommendations.
The diagram on slide 8 shows exactly this pipeline: user embedding → NN engine → candidate items → scoring box → top-10.
Why the dot product is useful in stage 1: maximum inner-product search can be done approximately in sub-linear time with index structures, so the dot product is chosen for its speed as much as for its accuracy. This lecture focuses on how to learn good embeddings.
Top-K recommendation and Recall@K slides 9-12 ↗
Slide 9: for each user we recommend \(K\) items. To be useful, \(K\) must be much smaller than the total number of items (up to billions); typically \(K\) is 10–100. The goal is to include as many positive items as possible in the top-\(K\) list, where positive items are the items the user will interact with in the future. The evaluation metric is Recall@K.
Slide 10 sets the notation for one user \(u\):
- \(P_u\): the set of positive items (future interactions).
- \(R_u\): the set of items recommended by the model. In top-\(K\) recommendation, \(|R_u|=K\).
- Items the user has already interacted with are excluded from \(R_u\).
Slide 11 defines the metric (the Venn diagram shows \(P_u\), \(R_u\) and their overlap):
\[ \text{Recall@}K(u)=\frac{|P_u\cap R_u|}{|P_u|}. \]A higher value means more of the user's future items made it into the top \(K\). The final Recall@K is the average over all users.
Check yourself: a user will buy items \(\{a,b,c,d\}\) and you recommend \(\{a,x,c\}\) with \(K=3\). Recall@3 = 2/4 = 0.5. Why is recall, not precision, the natural choice here? show answer
Because \(K\) is fixed and small, while \(|P_u|\) varies; recall asks "how much of what the user wants did we catch?"
Slide 12, "Recommendations with LLMs?", compares two ways to build the embeddings in the same NN-engine pipeline:
- GNN: embed users and products with a GNN on the interaction graph.
- LLM: turn each product into text ("textify") and embed it with an LLM; the user embedding is the average of the embeddings of the purchased products.
The table is for H&M fashion recommendation:
- MAP@12: LLM 0.00190, GNN 0.02856 (about 15× better).
- Precision@12: LLM 0.00329, GNN 0.01023 (about 3×).
- Recall@12: LLM 0.00119, GNN 0.05234 (about 40×).
- F1@12: LLM 0.0071, GNN 0.01564 (about 2×).
The lesson: knowing what a product is (text) is much weaker than knowing who bought it together with what (graph). The link points to the article "Do Large Language Models make accurate personalized recommendations?".
Embedding-based models: notation, score, parameters slides 14-17 ↗
Slide 14 fixes notation: \(U\) is the set of all users, \(V\) the set of all items, and \(E=\{(u,v)\mid u\in U, v\in V, u \text{ interacted with } v\}\) the set of observed interactions.
Slide 15: to get the top-\(K\) items we need a real-valued scalar score(u, v) for every user–item pair. The \(K\) items with the largest scores for user \(u\), excluding already-interacted items, are recommended. The figure shows user \(u\) with scores to items \(v_0,\dots,v_5\): \(\text{score}(u,v_0)=2.0\), \(v_1\): 3.0, \(v_2\): −2.3, \(v_3\): 4.0, \(v_4\): 0.7, and \(v_5\) is an already-interacted item (no score needed). For \(K=2\) the recommended items are the two highest, \(\{v_1,v_3\}\). The rule: rank by score, skip already-interacted items, take the top \(K\).
Slide 16 introduces embedding-based models:
- Each user \(u\in U\) has a \(D\)-dimensional embedding \(\mathbf u\in\mathbb R^D\).
- Each item \(v\in V\) has a \(D\)-dimensional embedding \(\mathbf v\in\mathbb R^D\).
- A parametrized function \(f_\theta(\cdot,\cdot):\mathbb R^D\times\mathbb R^D\to\mathbb R\) scores a pair: \(\text{score}(u,v)\equiv f_\theta(\mathbf u,\mathbf v)\).
Slide 17: so an embedding-based model has three kinds of parameters:
- an encoder that produces user embeddings \(\{\mathbf u\}_{u\in U}\);
- an encoder that produces item embeddings \(\{\mathbf v\}_{v\in V}\);
- the score function \(f_\theta(\cdot,\cdot)\).
Training objective: optimise the parameters to achieve high Recall@K on seen (training) interactions, hoping that this gives high Recall@K on unseen (test) interactions. This is the usual generalisation bet of machine learning.
Surrogate losses and the binary loss slides 18-20 ↗
Slide 18: Recall@K is not differentiable (it depends on a sorted top-\(K\) list, which changes in jumps as the scores move). So we cannot use efficient gradient-based optimisation on it directly. Two surrogate loss functions are widely used instead:
- the binary loss;
- the Bayesian Personalized Ranking (BPR) loss.
A good surrogate must be differentiable and align well with the original objective.
Slide 19 defines the ingredients. Positive edges are the observed training interactions \(E\). Negative edges are all other user–item pairs:
\[ E_{\text{neg}}=\{(u,v)\mid (u,v)\notin E,\ u\in U,\ v\in V\}. \]The sigmoid \(\sigma(x)=\frac{1}{1+\exp(-x)}\) maps a real score to a likelihood in \([0,1]\) (the small plot shows the S-shaped curve).
Slide 20, the binary loss: binary classification of positive vs negative edges using \(\sigma(f_\theta(\mathbf u,\mathbf v))\):
\[ -\frac{1}{|E|}\sum_{(u,v)\in E}\log\sigma\big(f_\theta(\mathbf u,\mathbf v)\big)\;-\;\frac{1}{|E_{\text{neg}}|}\sum_{(u,v)\in E_{\text{neg}}}\log\Big(1-\sigma\big(f_\theta(\mathbf u,\mathbf v)\big)\Big). \]During training, both sums are approximated with mini-batches of positive and negative edges (\(E_{\text{neg}}\) is far too large to enumerate). The binary loss pushes scores of positive edges up and scores of negative edges down. This matches the recall metric in spirit: positive edges must be recalled.
Why the binary loss is too strict slides 21-24 ↗
Slide 21 states the issue: in the binary loss, the scores of ALL positive edges are pushed higher than those of ALL negative edges. This can penalise the model even when the training recall is already perfect.
Slide 22 gives the smallest example: two users \(u_0,u_1\), two items \(v_0,v_1\), metric Recall@1. The model's scores (figure):
- \((u_0,v_0)=1.0\), positive edge; \((u_0,v_1)=-1.0\), negative.
- \((u_1,v_0)=2.0\), negative; \((u_1,v_1)=4.0\), positive edge.
Training Recall@1 is 1.0: \(v_0\) is correctly recommended to \(u_0\) and \(v_1\) to \(u_1\). But the binary loss still penalises the model, because the negative edge \((u_1,v_0)\) (score 2.0) has a higher score than the positive edge \((u_0,v_0)\) (score 1.0). The binary loss wants a single global threshold separating all positives from all negatives; no such threshold exists here, even though each user's ranking is perfect.
Slide 23, key insight: the binary loss is non-personalized: it considers positive and negative edges across all users at once. The recall metric is personalized: it is defined per user. So the binary loss is overly stringent for the metric we care about.
Slide 24, lesson learned: the surrogate loss should be personalized. For each user, positive items should score higher than that user's negative items; we do not care about the order of scores across users. The figure redraws the example with "observed" and "unobserved" interactions. The BPR loss does exactly this.
Check yourself: compute the binary-loss term of the negative edge \((u_1,v_0)\): \(-\log(1-\sigma(2))\approx 2.13\). It is the largest term in the loss, and it concerns a comparison that never affects any user's top-1 list.
Bayesian Personalized Ranking (BPR) loss slides 25-27 ↗
Slide 25: BPR is a personalized surrogate loss that aligns better with Recall@K. For each user \(u^*\in U\), define the rooted positive and negative edges:
\[ E(u^*)\equiv\{(u^*,v)\mid (u^*,v)\in E\},\qquad E_{\text{neg}}(u^*)\equiv\{(u^*,v)\mid (u^*,v)\in E_{\text{neg}}\}. \]The figure shows one user \(u^*\) with a few positive (solid) and many negative (dashed) edges to items. A note on the slide: the word "Bayesian" is not essential. The original paper [Rendle et al. 2009] puts a Bayesian prior on the parameters, which acts as parameter regularisation; the lecture omits it.
Slide 26: for each user \(u^*\), we want the scores of rooted positive edges to be higher than those of rooted negative edges. The loss for one user is
\[ \text{Loss}(u^*)=\frac{1}{|E(u^*)|\cdot|E_{\text{neg}}(u^*)|}\sum_{(u^*,v_{\text{pos}})\in E(u^*)}\ \sum_{(u^*,v_{\text{neg}})\in E_{\text{neg}}(u^*)} -\log\sigma\Big(f_\theta(\mathbf u^*,\mathbf v_{\text{pos}})-f_\theta(\mathbf u^*,\mathbf v_{\text{neg}})\Big). \]The difference inside \(\sigma\) is "encouraged to be positive", i.e. the positive edge score should exceed the negative edge score for the same user. The final BPR loss averages over users: \(\frac{1}{|U|}\sum_{u^*\in U}\text{Loss}(u^*)\). It can be approximated with a mini-batch.
Slide 27, mini-batch training:
- Sample a subset of users \(U_{\text{mini}}\subset U\).
- For each \(u^*\in U_{\text{mini}}\), sample one positive item \(v_{\text{pos}}\) and a set of sampled negative items \(V_{\text{neg}}=\{v_{\text{neg}}\}\).
- Compute
Intuition: \(-\log\sigma(x)\) is a smooth version of "penalise if \(x\lt 0\)". Each term is a small pairwise ranking problem inside one user's list. Back to the slide-22 example: for \(u_0\), \(-\log\sigma(1-(-1))=-\log\sigma(2)\approx0.13\); for \(u_1\), \(-\log\sigma(4-2)\approx0.13\). Both small, and the cross-user pair \((u_1,v_0)\) vs \((u_0,v_0)\) never appears.
Why embeddings work: collaborative filtering slides 28-31 ↗
Slide 28 summarises so far: Recall@K as the metric; embedding-based models with three kinds of parameters (user encoder, item encoder, score function); surrogate losses to reach high recall. Embedding-based models are state of the art in recommender systems. Why do they work so well?
Slide 29: the underlying idea is collaborative filtering. Recommend items to a user by collecting the preferences of many other similar users; similar users tend to prefer similar items. The figure: users \(u\) and \(u'\) share several items (they are "similar users"); an item that \(u'\) interacted with but \(u\) did not becomes a "likely edge" for \(u\). The key question is how to capture similarity between users and items.
Slide 30: embedding-based models capture this similarity automatically.
- Low-dimensional embeddings cannot simply memorize all user–item interaction data.
- So, to fit the data, the embeddings are forced to capture similarity between users and items.
- This lets the model predict unseen interactions well.
Think of the interaction matrix \(R\in\{0,1\}^{|U|\times|V|}\). A score \(\mathbf u^\top\mathbf v\) with \(D\)-dimensional vectors is a rank-\(D\) approximation of \(R\). Low rank is a compression; compression forces sharing; sharing is similarity.
Slide 31 lays out the rest of the lecture:
- (1) Neural Graph Collaborative Filtering (NGCF) [Wang et al. 2019] and (2) LightGCN [He et al. 2020]: improve conventional collaborative filtering (shallow encoders) by explicitly modelling graph structure with GNNs. They assume no user/item features.
- PinSAGE [Ying et al. 2018]: uses GNNs to produce high-quality embeddings that capture both rich node attributes (e.g., images) and graph structure.
Limits of shallow collaborative filtering slides 33-35 ↗
Slide 33: conventional collaborative filtering uses shallow encoders.
- No user or item features.
- For every \(u\in U\) and \(v\in V\), a shallow learnable embedding \(\mathbf u,\mathbf v\in\mathbb R^D\) (one free vector per node, as in Lecture 3).
- Score function \(f_\theta(\mathbf u,\mathbf v)\equiv\mathbf z_u^\top\mathbf z_v\).
This is classic matrix factorization.
Slide 34, its limitations:
- The model itself does not explicitly capture graph structure. The graph appears only implicitly, through which pairs are positives in the training objective.
- Only first-order structure (the edges themselves) enters the objective. High-order structure, such as \(K\)-hop paths between two nodes, is not explicitly captured.
Slide 35: we want a model that (a) captures graph structure explicitly, not only through the loss, and (b) captures high-order structure beyond single edges. GNNs do both. Two models follow: NGCF [Wang et al. 2019] and LightGCN [He et al. 2020], a simplified and improved version of NGCF.
Check yourself: in matrix factorisation, two users who never share an item can still get similar embeddings. How? show answer
Through a chain: \(u_1\) shares items with \(u_2\), \(u_2\) shares items with \(u_3\). The loss sees only edges, so this multi-hop effect emerges slowly and indirectly through optimisation; a GNN builds it into the forward pass.
Neural Graph Collaborative Filtering (NGCF) slides 36-41 ↗
Slide 36: NGCF explicitly uses high-order graph structure when it produces user and item embeddings. Key idea: use a GNN to produce graph-aware embeddings. The three-panel figure: initial shallow embeddings on the bipartite graph → a GNN propagates embeddings along the edges → NGCF's graph-aware embeddings.
Slide 37, the framework. Given the user–item bipartite graph:
- Prepare a shallow learnable embedding for each node.
- Use a multi-layer GNN to propagate embeddings along the bipartite graph. This captures high-order structure.
- The final embeddings are explicitly graph-aware.
Two kinds of parameters are learned jointly: the shallow user/item embeddings, and the GNN's parameters.
Slide 38, initial node embeddings: for every user \(u\), set \(\mathbf h_u^{(0)}\) to the user's shallow embedding; for every item \(v\), set \(\mathbf h_v^{(0)}\) to the item's shallow embedding. The learnable embeddings play the role of node features (there are no real features).
Slide 39, neighbor aggregation, done iteratively:
\[ \mathbf h_v^{(k+1)}=\text{COMBINE}\Big(\mathbf h_v^{(k)},\ \text{AGGR}\big(\{\mathbf h_u^{(k)}\}_{u\in N(v)}\big)\Big),\qquad \mathbf h_u^{(k+1)}=\text{COMBINE}\Big(\mathbf h_u^{(k)},\ \text{AGGR}\big(\{\mathbf h_v^{(k)}\}_{v\in N(u)}\big)\Big). \]Items aggregate from their users and users from their items. Iterating captures high-order structure. Many architecture choices are possible; for example \(\text{AGGR}(\cdot)=\text{MEAN}(\cdot)\) and \(\text{COMBINE}(\mathbf x,\mathbf y)=\text{ReLU}(\text{Linear}(\text{Concat}(\mathbf x,\mathbf y)))\). The figure highlights the edges used to update one user (green) and one item (blue).
Slide 40: after \(K\) rounds we have the final embeddings \(\mathbf h_u^{(K)},\mathbf h_v^{(K)}\). Set \(\mathbf u\leftarrow\mathbf h_u^{(K)}\), \(\mathbf v\leftarrow\mathbf h_v^{(K)}\), and score with the inner product \(\text{score}(u,v)=\mathbf u^\top\mathbf v\). Training uses the BPR loss from before.
Slide 41, summary: conventional CF uses shallow embeddings that do not explicitly model graph structure, and its objective does not model high-order structure. NGCF propagates the shallow embeddings with a GNN, so the embeddings are explicitly aware of high-order structure.
Intuition: after 2 layers, a user's embedding contains the items it bought; after 3 layers it also contains the users who bought those items. That 3-hop path user → item → user → item is exactly the collaborative-filtering signal "people like you also bought".
LightGCN: from GCN to linear diffusion slides 43-49 ↗
Slide 43, motivation. NGCF learns shallow embeddings and GNN parameters. Observation: shallow embeddings are already very expressive. They are learned per node, and when \(N\) (number of nodes) \(\gg D\) (embedding dimension), almost all parameters are in them: shallow embeddings are \(O(ND)\), the GNN is \(O(D^2)\). So the GNN parameters may not matter much.
Slide 44: can we simplify NGCF's GNN, for example remove its learnable parameters? Yes, and as a bonus, the simplification improves performance. The plan: adjacency matrix of a bipartite graph → matrix form of GCN → remove the non-linearity (related: SGC for scalable GNNs [Wu et al. 2019]).
Slide 45, the matrices. With interaction matrix \(R\) (\(R_{uv}=1\) if user \(u\) interacts with item \(v\), else 0), the adjacency matrix of the undirected bipartite graph and the shallow embedding matrix are
\[ A=\begin{pmatrix}0 & R\\ R^\top & 0\end{pmatrix},\qquad E=\begin{pmatrix}E_U\\ E_V\end{pmatrix}\ \ (\text{user rows, then item rows}). \]Slide 46, matrix form of GCN. Let \(D\) be the degree matrix of \(A\) and define the normalised adjacency (the diffusion matrix) \(\tilde A\equiv D^{-1/2}AD^{-1/2}\). Note: unlike the original GCN, the self-connection is omitted. With \(E^{(k)}\) the embedding matrix at layer \(k\) (each row is a node embedding), one GCN layer is
\[ E^{(k+1)}=\text{ReLU}\big(\tilde A E^{(k)}W^{(k)}\big), \]where \(\tilde AE^{(k)}\) is neighbour aggregation and \(W^{(k)}\) is a learnable linear transformation.
Slide 47, simplify by removing ReLU (idea from SGC): \(E^{(k+1)}=\tilde AE^{(k)}W^{(k)}\). Unrolling,
\[ E^{(K)}=\tilde A E^{(K-1)}W^{(K-1)}=\tilde A\big(\tilde AE^{(K-2)}W^{(K-2)}\big)W^{(K-1)}=\cdots=\tilde A^K E\,W^{(0)}\cdots W^{(K-1)}, \]with \(E^{(0)}=E\), the input embeddings.
Slide 48: so \(E^{(K)}=\tilde A^K E W\) with \(W\equiv W^{(0)}\cdots W^{(K-1)}\). The \(\tilde A^KE\) part is "diffusing node embeddings along the graph". The algorithm is just: apply \(E\leftarrow\tilde AE\) \(K\) times. Each multiplication spreads the current embeddings to one-hop neighbours. Note: \(\tilde A^K\) is dense and never materialised; we use repeated sparse matrix–matrix products instead.
Slide 49, multi-scale diffusion: \(\alpha_0E^{(0)}+\alpha_1E^{(1)}+\dots+\alpha_KE^{(K)}\) mixes embeddings diffused over different numbers of hops. The term \(\alpha_0E^{(0)}=\alpha_0\tilde A^0E^{(0)}\) acts as the self-connection that was dropped from \(\tilde A\). The \(\alpha_k\) are hyperparameters; LightGCN uses uniform weights \(\alpha_k=\frac{1}{K+1}\) for \(k=0,\dots,K\).
Why can \(W\) be dropped? \(E\) is itself a free learnable matrix, so \(EW\) is just another free matrix of the same shape: the product \(W\) adds no expressive power. LightGCN therefore keeps only \(E\).
LightGCN: the model, intuition and comparisons slides 50-57 ↗
Slides 50–53 show LightGCN as a picture of matrices.
- Slide 50, given: the adjacency matrix \(A\) (blocks \(0,R;R^\top,0\)) and the initial learnable embedding matrix \(E\) (user rows on top, item rows below). Normalise \(A\) to \(\tilde A\), with self-loops omitted.
- Slide 51, diffuse: for \(k=0,\dots,K-1\), \(E^{(k+1)}\leftarrow\tilde A\cdot E^{(k)}\), with \(E^{(0)}=E\). Because \(\tilde A\) has zero diagonal blocks, one step sends user embeddings to items and item embeddings to users.
- Slide 52, average across scales: \(E_{\text{final}}\leftarrow\frac{1}{K+1}\big(E^{(0)}+E^{(1)}+\dots+E^{(K)}\big)\).
- Slide 53, score: take user row \(\mathbf z_u\) and item row \(\mathbf z_v\) of \(E_{\text{final}}\) as the embeddings \(\mathbf u,\mathbf v\), and score with \(\mathbf z_u^\top\mathbf z_v\).
Slide 54, intuition. Why does simple diffusion work so well? Diffusion directly makes the embeddings of similar users (or items) similar. Similar users share many common neighbours (items), so after diffusion they are averages of largely the same vectors, and they are expected to have similar future preferences.
Slide 55, relation to GCN. GCN's aggregation is
\[ \mathbf h_v^{(k+1)}=\sum_{u\in N(v)}\frac{1}{\sqrt{d_u}\sqrt{d_v}}\,\mathbf h_u^{(k)}, \]with \(d_u,d_v\) the node degrees and a self-loop added to the neighbourhood. LightGCN uses the same equation except: (1) no self-loop in the neighbourhood; (2) the final embedding is the average over all layers, \(\mathbf h_v=\frac{1}{K+1}\sum_{k=0}^{K}\mathbf h_v^{(k)}\).
Slide 56, LightGCN vs matrix factorisation (shallow encoders). Both learn a unique embedding per user and item. The difference is that LightGCN scores with the diffused embeddings. LightGCN performs better but costs more compute, because of the diffusion step: the final embedding of a node aggregates the embeddings of its multi-hop neighbours.
Slide 57, summary: LightGCN simplifies NGCF by removing the GNN's learnable parameters. All learnable parameters are in the shallow input embeddings. Diffusion uses only matrix–vector multiplication. And the simplification gives better empirical performance than NGCF.
Check yourself: with \(K=0\), what is LightGCN? show answer
Plain matrix factorisation. With \(K=1\), the user embedding is \(\frac12(\mathbf e_u+\sum_{v\in N(u)}\mathbf e_v/\sqrt{d_ud_v})\): the user's own vector blended with a degree-normalised sum of its items.
Why "simpler is better" here: with no real input features, the GNN weights and ReLUs in NGCF have nothing meaningful to transform, and they make optimisation harder. The useful part of the GNN was the propagation, not the learned transformation.
PinSAGE: graph embeddings at Pinterest slides 59-63 ↗
Slide 59, the use case: P2P (pin-to-pin) recommendation. The picture shows a fashion pin on the left and, after the arrow, a grid of related pins that should be recommended next to it.
Slide 60, PinSAGE pin embeddings:
- They unify visual, textual and graph information.
- PinSAGE was the largest industry deployment of a graph convolutional network.
- Huge adoption across Pinterest.
- It works for fresh content: an embedding is available a few seconds after a pin is created (inductive, unlike shallow embeddings).
Reference: "Graph Convolutional Neural Networks for Web-Scale Recommender Systems", Ying et al., 2018.
Slide 61, application at Pinterest. Goal: produce embeddings for nodes in a Pinterest graph with billions of objects. Key idea: borrow information from nearby nodes. Example: a bed rail pin may look like a garden fence (the two photos look alike: dark wrought-iron bars), but gates and beds are rarely adjacent in the graph. So the graph neighbourhood disambiguates what images alone confuse. Pin embeddings feed many tasks: recommendation, classification, ranking; services like "Related Pins", "Search", "Shopping", "Ads".
Slide 62, "Harnessing pins and boards": three pins on top (a jacket, a Hans Wegner chair, a plant photo) are connected by lines to the boards below that contain them ("mid century modern", "Men Style", "Plants", …). Users save pins to boards, and this pin–board membership is the graph.
Slide 63: the graph has tens of billions of nodes and edges. The figure shows the bipartite pins–boards graph and, on the right, the GNN computation graph for one pin: it aggregates from its boards, which aggregate from their pins. Doing this "further resolves" the embeddings across the Pinterest graph.
PinSAGE training: task, data and shared negatives slides 64-68 ↗
Slide 64: beyond the GNN model, PinSAGE introduces methods to scale GNN training to a billion-scale recommender:
- shared negative samples across users in a mini-batch;
- hard negative samples;
- curriculum learning;
- mini-batch training of GNNs on a large graph (covered in a later lecture).
Slide 65, the task: recommend related pins. Learn node embeddings \(z_i\) such that
\[ d(z_{\text{cake1}},z_{\text{cake2}})\lt d(z_{\text{cake1}},z_{\text{sweater}}). \]The figure: from a cake source pin, another cake is a successful recommendation and a sweater is a bad one. On the right, two GNN computation trees produce \(z_1\) and \(z_2\), and the loss looks at their distance \(d(z_1,z_2)\).
Slide 66, training data: 1+B (over one billion) repin pairs from the Related Pins surface. They capture semantic relatedness. Goal: embed such pairs as "neighbours" (close). The example positive pairs \((Q,X)\) are pictures that belong together (two dog photos, two decorative items, and so on).
Slide 67 recalls BPR mini-batches: for each user \(u^*\in U_{\text{mini}}\), one positive item and a set of sampled negatives \(V_{\text{neg}}\). More negatives per user improve performance but are expensive:
- we must generate \(|U_{\text{mini}}|\cdot|V_{\text{neg}}|\) embeddings for negative nodes;
- we must run \(|U_{\text{mini}}|\cdot|V_{\text{neg}}|\) GNN computation graphs (the figure shows these trees), which is expensive.
Slide 68, key idea: share the same negative set \(V_{\text{neg}}\) across all users in the mini-batch. Then only \(|V_{\text{neg}}|\) negative embeddings are needed, a saving by a factor of \(|U_{\text{mini}}|\). Empirically, performance stays similar to the non-shared scheme.
Intuition: a random negative is "a random item"; it does not need to be specific to a user. Sharing them is like the in-batch negatives used in contrastive learning.
Hard negatives and curriculum learning slides 69-73 ↗
Slide 69, the challenge: industrial recommenders must make extremely fine-grained predictions. There are up to billions of items, and only 10–100 are recommended per user. Shared negatives are sampled at random from all items, so most of them are easy negatives: the model can tell them apart from positives without being fine-grained. We need hard negatives to force fine-grained distinctions.
Slide 70, the idea: use harder and harder negatives, including more hard negatives each epoch. The pictures: a source pin (a card with a leaf design), a positive (a similar leaf card), an easy negative (a photo of a rural house, obviously unrelated), and a hard negative (another greeting card, similar in style but not truly related).
Slide 71, curriculum learning: make the negatives gradually harder during training. At epoch \(n\), add \(n-1\) hard negative items. The number of hard negatives grows over training, and the model gradually learns finer-grained predictions. (Starting with hard negatives would make the problem too difficult early, when the embeddings are still random.)
Slide 72, how to find hard negatives. For each user node, hard negatives are item nodes that are close but not connected to the user in the graph. For user \(u\):
- Run random walk with restart from \(u\) and record visit counts for other items/nodes.
- Sort items in descending order of visit count.
- Randomly sample items ranked high but not too high, e.g., ranks 2000th–5000th.
These items are close to the user, but not so close that they are likely true positives. Hard negatives are used in addition to the shared negatives.
Slide 73, another way to pick negatives. Positive pairs \((q,p)\) are given; various methods sample a negative \(n\) to form a triple \((q,p,n)\). Distance Weighted Sampling (Wu et al., 2017): sample negatives so that the query–negative distance distribution is approximately uniform on \([0.5,1.4]\). The left diagram: \((q,p)\) and the negatives in the batch go into a sampling block that outputs \((q,p,n)\). The right plot (from the Wu et al. paper) shows where different strategies sample along "distance between examples": hard negative mining concentrates at small distances, semi-hard mining around 0.5, uniform sampling at large distances (around 1.4–1.8), and distance-weighted sampling spreads across the whole range.
PinSAGE results and summary slides 74-76 ↗
Slide 74, fine-grained object similarity. The query is a porcelain lace figurine. A visual-only model returns some figurines but also lamps and lampshades (similar colours and shapes). PinSAGE returns a row of porcelain figurines only: the graph tells it that people save these pins to the same boards.
Slide 75, compare against production. The query is a photo of a cat wearing a knitted lamb hat. The top row (the text extraction labels the systems Pixie, Pinterest's earlier random-walk recommender, and GraphSAGE) returns Shih Tzu posters, dog prints and a T-shirt: related words, wrong concept. The boxed row returns cats wearing knitted animal hats, which is what the user wants.
Slide 76, summary:
- PinSAGE uses GNNs to produce high-quality user/item embeddings that capture both rich node attributes and graph structure.
- It is trained effectively with sophisticated negative sampling strategies (shared, hard, curriculum).
- It is deployed at Pinterest, a billion-scale image recommendation service.
Contrast with LightGCN: LightGCN has no features and a free vector per node (transductive), so it cannot embed a brand-new pin. PinSAGE computes embeddings from features plus neighbourhood (inductive, GraphSAGE-style), which is why fresh pins get an embedding seconds after creation.
Not shown (no new content): slides 1,2,3,4,13,32,42,58 — title page, announcements and exam logistics, and section-divider title pages.
Review: what to keep from this session
Carried forward. Lecture 17 notices that the reward-model loss of RLHF has exactly the BPR form; Lecture 12 moves from a single user–item table to whole databases.
Quick self-check
Why is the binary cross-entropy loss a poor fit for Recall@K?
It compares every positive against every negative across all users, while the metric is per user; a user with easy positives can dominate the loss.
What does LightGCN keep from GCN and what does it drop?
It keeps neighbour averaging with symmetric degree normalisation and drops the weight matrices and non-linearities, then averages the per-layer embeddings.
Why does PinSage sample neighbours by random walks rather than uniformly?
Random walks rank neighbours by importance, so a fixed budget of neighbours captures the most relevant ones for a hub pin.
Key idea
Collaborative filtering is diffusion on the user–item graph: LightGCN keeps only learnable embeddings and parameter-free normalised propagation, and a personalised ranking loss (BPR) aligns training with per-user Recall@K.
Worked example: BPR fixes the binary loss
Same scores as the think-first box: \(s(u_0,v_0)=1\) (pos), \(s(u_0,v_1)=-1\), \(s(u_1,v_0)=2\), \(s(u_1,v_1)=4\) (pos).
- BPR for \(u_0\): \(-\log\sigma(1-(-1))=-\log\sigma(2)=0.127\).
- BPR for \(u_1\): \(-\log\sigma(4-2)=0.127\). Both users are already ranked correctly; the loss is small and only asks for larger within-user margins.
- Binary loss includes \(-\log(1-\sigma(2))=2.127\) for the negative \((u_1,v_0)\) — a big penalty for something irrelevant to recall.
- Recall@2 example: user's future positives \(P_u=\{a,b,c\}\); recommended \(R_u=\{a,d\}\) → Recall@2 = 1/3.
Strictly speaking: BPR is still a surrogate — it optimises AUC-like pairwise ordering, not top-K recall. Losses that focus on the top of the ranking (softmax/sampled-softmax, LambdaRank) are often better in practice.
In code (PyG)
from torch_geometric.nn import LightGCN
model = LightGCN(num_nodes=n_users + n_items, embedding_dim=64, num_layers=3)
# edge_index: user-item edges with items offset by n_users, made undirected
pos_rank = model(edge_index, edge_label_index=pos_pairs) # z_u . z_v for positives
neg_rank = model(edge_index, edge_label_index=neg_pairs) # sampled negatives (same users)
loss = model.recommendation_loss(pos_rank, neg_rank, lambda_reg=1e-4) # BPR + L2
topk = model.recommend(edge_index, src_index=users, dst_index=items, k=20)
Proof workshop: BPR upper-bounds the number of mis-ranked pairs
One problem in olympiad style. Give it fifteen minutes on paper before you open the first hint; the hints are graded, so open them one at a time.
Problem. For a user \(u\), let \(\mathcal P\) be pairs \((i,j)\) with \(i\) a positive and \(j\) a negative item, and \(x_{ij}=s_{ui}-s_{uj}\). Prove that \(\frac1{\log2}\sum_{(i,j)\in\mathcal P}-\log\sigma(x_{ij})\ \ge\ \#\{(i,j):x_{ij}\le0\}\). Deduce that minimising BPR minimises an upper bound on \(1-\mathrm{AUC}_u\).
Hint 1
Hint 2
Solution
Why it matters. Recall@K is a step function of the scores and has no useful gradient; BPR is a smooth, convex surrogate for the per-user ranking error. The bound also shows what BPR does not optimise: the top of the list. That is why hard negatives (PinSage) and top-heavy losses matter in practice.
Sharper lens: how little a recommender needs, and what bounds it
Not on the slides. Three or four points where the lecture rounds something off: the exact statement, a second way to see it, and where it stops being true. Each is short and has a pointer for going further.
LightGCN is a fixed low-pass filter; the end of that road has no training at all
\(E_{\text{final}}=\frac1{K+1}\sum_k\tilde A^kE=g(\tilde A)E\) for a fixed polynomial \(g\) that keeps the eigen-directions of \(\tilde A\) near eigenvalue 1 and damps the rest: the same low-pass filter as DeepWalk's window (Lecture 2) and SGC (Lecture 20). If the filter is doing the work, why learn anything?
- GF-CF (Shen et al., CIKM 2021) applies a normalised item–item filter plus an ideal low-pass filter built from the top singular vectors of the interaction matrix, with no training, and beats LightGCN on LightGCN's own benchmarks.
- EASE (Steck, WWW 2019) learns one item–item matrix \(B\) by ridge regression of the interaction matrix \(X\) on itself with \(\mathrm{diag}(B)=0\). It has a closed form: with \(P=(X^\top X+\lambda I)^{-1}\), \(B_{ij}=-P_{ij}/P_{jj}\) for \(i\ne j\). One matrix inversion, competitive with deep models on the standard datasets.
On pure interaction data the signal sits in the low-frequency spectrum of co-occurrence, and the loss and the filter matter more than the architecture. Learned weights earn their place when nodes have content (PinSage: images and text, new pins with no history).
A dot product of dimension d cannot produce every top-K list
Retrieval by \(\mathbf z_u^\top\mathbf z_v\) is fast because it is geometric, and for the same reason it is limited: with \(n\) items in \(d\) dimensions only some of the \(\binom nK\) possible top-\(K\) sets can be the nearest neighbours of any user vector, and the number of realisable ones grows polynomially in \(n\) with an exponent set by \(d\). Weller et al. (2025) turned this into a test: a dataset of trivially simple queries on which strong embedding models fail because the required combinations of relevant items exceed what their dimension can encode.
This is the structural reason for the two-stage design in section 1. Stage one accepts the rank limit in exchange for sub-linear search and is tuned for recall; stage two scores each candidate with a model that sees user and item together and has no such limit. It is also why "increase the embedding dimension" keeps helping longer than expected.
Two evaluation traps the leaderboards fell into
Sampled metrics. Ranking the true item against 100 random negatives instead of the whole catalogue is not a cheaper estimate of the same thing. Krichene and Rendle (KDD 2020) show it is inconsistent: it can reverse the order of two models, and as the sample shrinks every metric degenerates into AUC, which Lecture 5's Sharper lens showed is blind to the top of the list. Rank against all items; LightGCN's code does.
Learned similarity. Neural Collaborative Filtering replaced the dot product by an MLP on the concatenated embeddings and reported gains. With equal tuning the dot product wins, and an MLP needs a surprising amount of data even to imitate a dot product (Rendle et al., RecSys 2020). Together with Dacrema et al. (in Go deeper), this is why the lecture's "simpler and better" is the rule for collaborative filtering and not a curiosity.
From graph diffusion to sequence transformers, and a primary source for X
Industrial ranking has moved from "embed the graph, then score" towards sequence models over each user's action history. Generative retrieval (TIGER, Rajput et al., NeurIPS 2023) gives every item a short "semantic ID", a few codes from a residual quantiser, and a transformer generates the next item's codes token by token. In January 2026 X open-sourced the system behind its For You feed (xai-org/x-algorithm): the hand-engineered features of the 2023 release are replaced by a transformer that reads the user's engagement sequence and predicts the probabilities of many actions (like, reply, repost, block, …), with candidates drawn from followed accounts and from an embedding-similarity retrieval stage, the two-tower pattern of section 1. For work on amplification this repository, which is still being updated, is the document to read: it states what is predicted and how the predictions are combined. The graph has not left; it supplies the candidates and the engagement edges. What changed is which model does the scoring.
Lab: hands-on and practical tips
Try it live. In the Graph Explorer: train LightGCN on MovieLens and compare it with matrix factorisation, item k-NN and popularity. Each lesson has predict-then-check questions.
notebook · L11 recommender systems turns MovieLens into a bipartite graph, compares the binary and BPR losses, trains matrix factorisation vs LightGCN, and mines hard negatives PinSage-style.
Readings & lookup guide
lecture notes CS224W course notes (Leni Aniva, Autumn 2024 — in your course folder)
- Ch. 12 — GNNs for recommender systems (pp. 65–70)
Order: LightGCN first (short, clear, and it subsumes NGCF), then NGCF for the history, PinSage for engineering.
read first He et al. — LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation (SIGIR 2020)
- Read: §2 (ablation of NGCF: removing feature transformation and non-linearity improves results — Table 1, Fig. 1), §3.1 (model), §3.2 (relation to SGC & APPNP; layer combination as a self-connection).
- Lesson to keep: in ID-only collaborative filtering, the parameters belong in the embeddings, not in the propagation.
context Wang et al. — Neural Graph Collaborative Filtering (SIGIR 2019)
- Read: §2.2 (embedding propagation with the \(\mathbf e_i\odot\mathbf e_u\) affinity term) and Fig. 2 (high-order connectivity). Skim experiments.
engineering classic Ying et al. — Graph Convolutional Neural Networks for Web-Scale Recommender Systems (PinSage, KDD 2018)
- Read: §3.2 (importance-based neighbourhoods from random walks; importance pooling), §3.3 (max-margin loss, hard negatives, curriculum), §3.4 (MapReduce inference).
- Key numbers: 3B nodes, 18B edges, 7.5B training examples; A/B tests with large engagement gains.
origin Rendle et al. — BPR: Bayesian Personalized Ranking from Implicit Feedback (UAI 2009)
- §4 derivation of the BPR criterion and its link to AUC optimisation.
Homework & deadlines
Homework 2 due Thu 10/29 · Homework 3 out Thu 10/29 · due Thu 11/12
HW3 comes out with Lecture 12; it will likely cover Lectures 9–13 (heterogeneous graphs, KGs, recommender systems, relational deep learning). Download into the course folder when released.
Colab 3 due Thu 11/5 · Project milestone due Tue 11/10
Exam note from the slides: the exam (Wed 11/18) covers Lectures 1–16 with focus on 1–13; a practice exam and recitation are provided.
Self-check
Why is the binary loss a poor surrogate for Recall@K?
- It isn't differentiable
- It compares positives and negatives across different users
- It ignores negatives
- It requires item features
Recall is per user; cross-user score comparisons are irrelevant.
LightGCN differs from NGCF mainly by …
- adding attention
- using item features
- using a binary loss
- removing feature transformations and non-linearities in propagation
All learnable parameters are in the shallow input embeddings.
In LightGCN, the self-loop's role is played by …
- including \(E^{(0)}\) in the layer average
- adding I to A
- a separate weight matrix
- dropout
\(\alpha_0E^{(0)}=\alpha_0\tilde A^0E^{(0)}\).
PinSage's hard negatives are …
- random items
- items the user interacted with
- items close to the user in random-walk visit counts but not connected (ranks ~2000–5000)
- the most popular items
Close enough to be confusing, not so close to be actual positives.
Sharing negative samples across a mini-batch of users saves …
- nothing
- a factor of |U_mini| in negative-embedding computation
- memory for user embeddings
- the need for positives
Compute |V_neg| embeddings once instead of per user.
Flashcards (click to flip)
History & the bigger picture
- 1992 — Tapestry (Xerox PARC) coins "collaborative filtering"; 1994 — GroupLens; 2003 — Amazon item-to-item CF.
- 2006–2009 — the Netflix Prize: matrix factorisation (Koren, Bell, Volinsky) wins; 2009 — BPR for implicit feedback.
- 2016–2018 — deep recommenders (YouTube DNN two-tower, Wide&Deep); 2018 — PinSage; 2019–2020 — NGCF → LightGCN.
- 2023– — generative and LLM-based recommenders; GNNs remain strong on structure-heavy, ID-based data.
Recommenders are arguably the most socially consequential ML systems: they shape what billions read, watch and buy. Optimising Recall@K on past behaviour is a choice of values — engagement over diversity, exploitation over exploration. Debates on filter bubbles, polarisation and algorithmic amplification (and regulation like the EU Digital Services Act) are about exactly these objective functions. From an ethical standpoint rooted in care for the common good, "what should the system recommend?" is not a purely technical question.
Classic SNA bridge
| In this lecture | Classic SNA counterpart | What carried over, what changed |
|---|---|---|
| User–item bipartite graph | Affiliation networks (Breiger 1974); Galois lattices of people × events (Freeman & White 1993) | The Southern Women dataset (Davis, Gardner & Gardner 1941: 18 women × 14 events) is the original user–item matrix. Collaborative filtering is affiliation-network analysis with a prediction objective. |
| Collaborative filtering: similar users like similar items | Structural equivalence in two-mode data; "duality of persons and groups" | Two users are similar if they attend the same events; two events if they draw the same users. Breiger's duality is exactly the alternating propagation of NGCF/LightGCN. |
| Who-to-follow as user–user recommendation | Triadic closure (Simmel; Rapoport 1953); "friend of a friend" in the p* family | Twitter's WTF used random-walk SALSA; LightGCN on the follow graph is its modern form. Both are machines for triadic closure, which is why they homogenise. |
| Recall@K and surrogate losses | Network interventions and their evaluation (Valente 2012) | SNA evaluated interventions by outcomes in the population; recommender metrics evaluate per-user ranking. The gap between them is where the PNAS/Science results above live. |
| Hard negatives | Non-ties that "should" exist: structural holes (Burt 1992) | A high-scoring non-tie is a structural hole candidate. Burt saw brokerage opportunity; a recommender sees a hard negative or a recommendation. Same object, opposite valuation. |
Train LightGCN on engagement data from X and measure, as \(K\) grows, (a) Recall@K, (b) the Gini coefficient of item exposure and (c) embedding-space homophily by political camp. Then compute Musco et al.'s \(P+D\) on the implied user–user graph before and after applying the recommendations as edge reweighting. That is an amplification audit with a theory behind it, and a publishable intersection of GNNs and computational social science.
Go deeper in the SNA course. The twelve-unit course on social network analysis in this repository gives the classic side of this lecture in full, with labs and real-data analyses: Unit 5 · Heavy tails & the scale-free debate (popularity bias: preferential attachment inside a recommender); Unit 7 · Cascades, contagion & influence (recommenders: the feed that decides which cascades get a chance); Unit 11 · Polarization, algorithms & misinformation (recommender systems: where exposure is decided).
Connecting to your research
Running project. Section L11 · who-to-retweet of notebooks/project/retweet_thread.py applies this lecture to one synthetic X world with coordinated rings, the same graph across the whole course.
Research extension. experiments/recsys-amplification (hypotheses written before running): a popularity recommender gives ring targets 1.2–1.4× the exposure (2–3× for obscure targets); LightGCN-style normalisation does not amplify; Recall@20 cannot see the difference.
- Who-to-follow is user–user recommendation (Twitter's WTF system, 2013, used random-walk SALSA). LightGCN on the follow graph is a strong modern baseline.
- Amplification audits: train a LightGCN on engagement data and measure whether diffusion amplifies partisan content (embedding-space homophily). That's a publishable intersection of GNNs and computational social science.
- Echo chambers ↔ over-smoothing: deeper diffusion makes users within a community more similar — the model's inductive bias itself encodes homophily. Worth testing whether \(K\) controls recommendation diversity.
From the experiments: results and datasets
Generated by scripts/sync_guides.py from the experiments' committed results and the dataset catalogue; rerun it (make sync-guides) after an experiment changes.
recsys-amplification
Question. Does the recommender amplify coordinated rings, and which recommender? experiment folder ↗
Frontier 2025–26: what changed since the slides
Frontiers · a recommender is an edge-rewiring operator · polarisation plus disagreement is convex
Words & phrases
| Term | Simple meaning | Persian | In context |
|---|---|---|---|
| surrogate lossn. | an easier, differentiable objective used in place of the real metric | تابع زیان جانشین | "we train with a surrogate loss" |
| curriculum learningn. | training on easy examples first and harder ones later | یادگیری برنامهدرسی (تدریجی) | "Curriculum learning: at epoch n, add n − 1 hard negatives" |
| implicit feedbackn. | behaviour (clicks, views) rather than explicit ratings | بازخورد ضمنی | "a rating ≥ 4 counts as implicit feedback" |
| cold startn. | the problem of new users or items with no history | شروع سرد | "PinSage uses content features against cold start" |
| collaborative filteringn. | recommending from the behaviour of similar users rather than from item content | پالایش مشارکتی | "LightGCN is graph collaborative filtering" |
| popularity biasn. | a recommender's drift toward already popular items | سوگیری محبوبیت | "check Recall@K against a popularity baseline" |
Go deeper
- Next: Lecture 12 — Relational Deep Learning: the user–item graph generalises to an entire relational database.
- Evaluation: Dacrema et al. (RecSys 2019), "Are we really making much progress?" — many neural recommenders lose to tuned simple baselines.
- Open question: LightGCN removes parameters and improves. When do learnable propagation weights help? (Hint: when nodes have rich features, as in PinSage.)