Before you start: review of the earlier sessions
The thread so far. Session 1 said what a graph is; session 2 shows the first learned representation of a node, borrowed from word2vec. The limits listed at the end are precisely what motivates the GNN of session 3.
What this session takes from earlier ones
Those sessions in one minute each
Lecture 1 · Introduction — Machine Learning with Graphs
A graph model must work for any number of nodes and give the same answer no matter how the nodes are numbered — everything else is a design choice about what the nodes and edges mean.
A homogeneous graph is the special case \(|R| = |T| = 1\). Permutation: relabelling nodes with a permutation matrix \(P\) turns \(A\) into \(PAP^\top\); a graph-level model \(f\) must satisfy \(f(PAP^\top, PX) = f(A, X)\).
Warm-up: answer these before you read on
What is the difference between a directed and an undirected graph in the adjacency matrix? from Lecture 1
An undirected graph has a symmetric adjacency matrix; a directed graph does not.
Name the three task levels and one concrete example of each. from Lecture 1
Node level (classify a protein's function), link level (recommend a product to a user), graph level (predict a molecule's toxicity).
Why does a convolution on an image not transfer directly to a graph? from Lecture 1
A pixel has a fixed set of neighbours in a fixed order (a 3×3 window); a graph node has a variable number of neighbours and no canonical order, so a fixed filter cannot be slid over it.
More questions from every session you have reached, with spaced repetition: the cumulative review.
In short
Classic graph ML meant hand-crafting features (degree, centrality, graphlet counts) for each new task. Representation learning replaces that with a learned map \(f: u \mapsto \mathbf{z}_u \in \mathbb{R}^d\).
Everything in this lecture fits one template: an encoder gives each node a vector, a decoder scores a pair of vectors (here the dot product \(\mathbf{z}_u^\top \mathbf{z}_v\)), and we train so that the score matches a chosen notion of node similarity.
The clever part is the similarity: two nodes are similar if they tend to co-occur on short random walks — exactly the way two words are similar if they appear in the same sentences (word2vec). DeepWalk uses unbiased walks; node2vec biases them with two knobs \(p, q\) that slide between a local (BFS-like) and an exploratory (DFS-like) view.
The catch: these "shallow" embeddings are a lookup table — one free vector per node, no features, no new nodes. That is the cliff-hanger that GNNs (Lecture 3) resolve.
The picture: encoder → decoder → similarity
How to read it (hover a step)
- Encoder = embedding lookup. \(\mathbf{Z}\in\mathbb{R}^{d\times|V|}\) has one column per node; \(\text{ENC}(u)=\mathbf{Z}\mathbf{1}_u\). These columns are the only parameters.
- Decoder = dot product (≈ cosine of the angle θ). Training pushes \(\mathbf{z}_u^\top\mathbf{z}_v\) up for similar pairs and down for others.
- Similarity = "\(v\) shows up on short random walks from \(u\)". This is the design choice that distinguishes DeepWalk, node2vec, LINE, …
1 · From feature engineering to embeddings
The traditional pipeline was graph → hand-engineered features → classifier. Every new task meant inventing new features. Representation learning makes the features themselves learnable and task-independent: we learn \(\mathbf{z}_u\) once, without labels and without node attributes, and reuse it for classification, link prediction, clustering, anomaly detection.
The recipe has four steps (slide 16):
- An encoder maps nodes to vectors.
- A node similarity function says what "similar" means in the graph.
- A decoder maps two vectors to a score.
- Optimise the encoder so that \(\text{DEC}(\mathbf{z}_u,\mathbf{z}_v)\approx \text{similarity}(u,v)\).
Should two nodes be similar if they are linked? share neighbours? play the same "role"? Which one does a random walk capture?
Random walks capture proximity / community (being reachable in a few hops, with many paths). They do not capture structural role: two hub nodes in different corners of the graph are never on the same short walk. Keep this question; it is the reason for struc2vec (Homework 1, Q2.5–2.8) and, later, for GNNs with structural features.
2 · Random-walk embeddings (DeepWalk)
Pick a start node, hop to a random neighbour, repeat. The visited sequence is a random walk. The model's job:
Why random walks? Expressivity — the walk mixes local and multi-hop information stochastically. Efficiency — we only train on pairs that actually co-occur, not all \(|V|^2\) pairs.
The objective, step by step
- Run short fixed-length walks from every node with strategy \(R\).
- Collect \(N_R(u)\), the multiset of nodes visited from \(u\) (repeats allowed).
- Maximise the likelihood of seeing those neighbours: \(\max_{\mathbf{z}} \sum_u \log P(N_R(u)\mid \mathbf{z}_u)\), i.e. minimise
The bottleneck and the trick: negative sampling
The softmax denominator sums over all nodes, so the loss is \(O(|V|^2)\). Negative sampling replaces "compare against everyone" with "compare against \(k\) random nodes":
\[ \log\frac{\exp(\mathbf{z}_u^\top\mathbf{z}_v)}{\sum_{n}\exp(\mathbf{z}_u^\top\mathbf{z}_n)} \;\approx\; \log\sigma(\mathbf{z}_u^\top\mathbf{z}_v)+\sum_{i=1}^{k}\log\sigma(-\mathbf{z}_u^\top\mathbf{z}_{n_i}),\quad n_i\sim P_V \]Negatives are drawn with probability proportional to degree (word2vec uses frequency3/4). Typical \(k=5\)–\(20\): larger \(k\) gives more robust estimates but biases toward negatives. Strictly, this is a different objective — a logistic regression separating real context nodes from noise, a form of Noise-Contrastive Estimation — but it approximately maximises the softmax log-likelihood.
Why the sigmoid of a negative dot product for negatives?
\(\sigma(-x)=1-\sigma(x)\). So \(\log\sigma(-\mathbf{z}_u^\top\mathbf{z}_n)\) is the log-probability that the pair \((u,n)\) is labelled "not a co-occurrence". The objective is binary cross-entropy with label 1 for the walk pair and label 0 for each sampled pair.
Optimise with SGD: sample a node \(u\), compute the gradient of its own loss term \(\mathcal{L}^{(u)}\), update the involved embeddings. That's DeepWalk (Perozzi et al., 2014) — unbiased, fixed-length walks.
3 · node2vec: biased walks between BFS and DFS
DeepWalk's notion of neighbourhood is rigid. node2vec (Grover & Leskovec, 2016) frames neighbourhood generation as a search strategy: BFS stays close and gives a micro view; DFS wanders away and gives a macro view. A 2nd-order (remembers the previous node) biased walk interpolates between them.
The walker just came from \(t\) to \(w\). Every neighbour \(x\) of \(w\) is at distance 0, 1 or 2 from \(t\) — no other option exists. So two parameters are enough:
- Return parameter \(p\): weight \(1/p\) to go straight back to \(t\). Low \(p\) → the walk hovers locally (BFS-like).
- A neighbour that is also a neighbour of \(t\) (distance 1 from \(t\)) gets weight 1.
- In–out parameter \(q\): weight \(1/q\) for nodes farther from \(t\). Low \(q\) → the walk pushes outward (DFS-like). Intuitively \(q\) is the "ratio" of BFS vs DFS.
Weights are unnormalised; divide by their sum. DeepWalk is the special case \(p=q=1\). The algorithm: (1) precompute transition probabilities per edge, (2) simulate \(r\) walks of length \(l\) from each node, (3) optimise with SGD — linear time, every step parallelisable.
Which setting gives "communities" and which gives "roles"? In the node2vec paper: \(q<1\) (outward, DFS-like) recovers homophily/communities; \(q>1\) (BFS-like) leans toward structural equivalence. But BFS only sees 2 hops, so "role" similarity is captured only weakly — the lecture's limitation slide (node 1 vs node 11) still applies.
Other ideas on slide 52: walks biased by attributes or learned weights; LINE (directly fit 1- and 2-hop probabilities); struc2vec and HARP (walk on a modified graph). The practical verdict (slide 54): no method wins everywhere — pick the similarity that matches your application.
4 · Embedding whole graphs
To embed a (sub)graph \(G\) — e.g. to classify toxic vs non-toxic molecules:
- Sum or average its node embeddings: \(\mathbf{z}_G=\sum_{v\in G}\mathbf{z}_v\) (Duvenaud et al., 2016, molecules).
- Virtual node: add a super-node connected to every node of the subgraph and embed it (Li et al., 2016).
- Hierarchical pooling (DiffPool, preview of Lecture 5): cluster nodes, pool per cluster, repeat.
Using embeddings downstream (slide 67): cluster \(\mathbf{z}_i\) for communities; classify from \(\mathbf{z}_i\); for links, combine the pair by concatenation \(g([\mathbf{z}_i,\mathbf{z}_j])\), Hadamard product \(g(\mathbf{z}_i\odot\mathbf{z}_j)\), sum/average, or distance \(g(\|\mathbf{z}_i-\mathbf{z}_j\|)\). Note that concatenation is not symmetric — a problem for undirected links.
5 · It was matrix factorisation all along
Take the simplest similarity: \(u,v\) similar iff they are linked. Then we want \(\mathbf{z}_v^\top\mathbf{z}_u=A_{u,v}\), i.e. \(\mathbf{Z}^\top\mathbf{Z}=A\). Since \(d\ll n\), exact factorisation is impossible, so we solve
\[ \min_{\mathbf{Z}}\;\|A-\mathbf{Z}^\top\mathbf{Z}\|_F \]Inner-product decoder + edge similarity = matrix factorisation of \(A\). More surprisingly, DeepWalk with negative sampling is also matrix factorisation (Qiu et al., 2018), of
\(\mathrm{vol}(G)=\sum_{ij}A_{ij}=2|E|\); \(D\) = degree matrix; \(D^{-1}A\) = random-walk transition matrix, so \((D^{-1}A)^r\) = \(r\)-step walk probabilities; \(T\) = context window; \(b\) = number of negative samples. With \(T=1\) you get LINE.
The "random walk + word2vec" story looked like a new kind of representation. NetMF showed the novelty was largely computational: sampling made a spectral quantity tractable at scale. A good habit for reading papers: ask whether a contribution is expressive (can represent new things) or computational (computes an old thing faster). Your project notes on DeepWalk/node2vec develop this further.
6 · Limitations → why we need GNNs
- Transductive, not inductive. A new user joins the network → no embedding; you must retrain. Different runs give different (rotated) embeddings, because the loss only sees dot products.
- No structural similarity. Nodes 1 and 11 both sit in a triangle with degree 2, but no short walk connects them, so their embeddings differ.
- No features. Protein properties, user profiles, text — all ignored.
- \(O(|V|\,d)\) parameters, no sharing between nodes.
Why does running DeepWalk twice on the same graph give different embeddings?
The loss depends only on inner products \(\mathbf{z}_u^\top\mathbf{z}_v\). For any orthogonal \(Q\), \((Q\mathbf{z}_u)^\top(Q\mathbf{z}_v)=\mathbf{z}_u^\top\mathbf{z}_v\), so all rotations/reflections are equally optimal — plus random initialisation and random walks. Only the geometry (relative positions) is meaningful, never individual coordinates.
The mathematics, step by step
Everything in this session follows from one sentence: choose a notion of similarity between nodes, then learn vectors whose dot products reproduce it. The cards go through that sentence piece by piece: the lookup table, the similarity, the exact loss, the cheap loss that replaces it, the biased walk of node2vec, and the matrix that the whole procedure secretly factorises.
Symbols used in this session
| symbol | meaning | what kind of object |
|---|---|---|
| \(\mathbf z_v\) | embedding of node \(v\): the vector we learn for it | vector in \(\mathbb R^d\) (typically \(d\) = 64 to 1000) |
| \(\mathbf Z\) | the embedding table; column \(v\) is \(\mathbf z_v\) | \(d\times|V|\) matrix; these are all the parameters |
| \(\mathbf z_u^\top\mathbf z_v\) | dot product \(\sum_{i=1}^{d}z_{u,i}z_{v,i}\): the decoder's similarity score | a real number |
| \(N_R(u)\) | nodes visited by short random walks that start at \(u\), under walk strategy \(R\) | a multiset (a node can appear several times) |
| \(\sigma(x)\) | sigmoid \(1/(1+e^{-x})\): squeezes a score into \((0,1)\) | function |
| \(k,\ n_i\) | number of negative samples, and the \(i\)-th sampled negative node | whole number; node drawn from \(P_V\) |
| \(P_V\) | distribution negatives are drawn from: probability proportional to degree (to the power ¾ in word2vec) | probability distribution over nodes |
| \(p,\ q\) | node2vec's return and in–out parameters | positive real numbers |
| \(D,\ \mathrm{vol}(G)\) | diagonal matrix of degrees; \(\mathrm{vol}(G)=\sum_v d_v=2m\) | matrix; number |
1Encoder and decoder
In words. The encoder is a lookup: it returns the column of the table that belongs to the node. The decoder scores a pair of nodes by the dot product of their vectors. Training moves the vectors until the scores match a chosen similarity.
Why it has this form. \(\mathbf e_v\) is the indicator vector with a single 1 at position \(v\), so \(\mathbf Z\mathbf e_v\) picks out column \(v\): nothing is computed from the graph or from features. The dot product is large when two vectors point the same way and are long, zero when they are perpendicular, negative when they point opposite ways, which makes it a natural similarity that is also cheap to compute.
Watch out. The number of parameters is \(d\cdot|V|\): it grows with the graph, and a node that was not in the training graph has no column. Lecture 3 removes exactly this limit.
2The random-walk objective (exact form)
In words. For every start node \(u\) and every node \(v\) that a walk from \(u\) visited, pay a penalty that is small when the model gives \(v\) a high probability among all nodes.
Why it has this form. Model the probability that a walk from \(u\) visits \(v\) by a softmax over all nodes, \(P(v\mid\mathbf z_u)=\exp(\mathbf z_u^\top\mathbf z_v)/\sum_n\exp(\mathbf z_u^\top\mathbf z_n)\). Assume the visits are independent; then the probability of everything the walks observed is the product of these terms. Maximising a product is the same as minimising the sum of the negative logarithms, which is \(\mathcal L\) (maximum likelihood).
Watch out. The denominator sums over all nodes for every pair, so one pass costs on the order of \(|V|^2\). This is why nobody optimises this form directly.
3Negative sampling (the form that is actually used)
In words. Replace 'give \(v\) a high probability among all nodes' by a yes/no task: say yes to the true pair \((u,v)\) and no to \(k\) randomly drawn pairs \((u,n_i)\).
Why it has this form. \(\sigma(\mathbf z_u^\top\mathbf z_v)\) is the model's probability that the pair is real, and \(\sigma(-x)=1-\sigma(x)\) is its probability that a pair is fake. The right-hand side is the log-likelihood of classifying one real pair and \(k\) fake pairs correctly (noise-contrastive estimation). It is not equal to the softmax, but its maximiser has the same useful property: real pairs get high scores, random pairs low ones. The cost per pair drops from \(|V|\) terms to \(k+1\), with \(k\) between 5 and 20.
Watch out. The minus sign inside \(\sigma(-\mathbf z_u^\top\mathbf z_{n_i})\) is the whole point: it rewards a low score for the negative. Negatives are drawn by degree, so a few of them are true neighbours by accident; that noise is tolerated.
4node2vec: the biased second-order walk
In words. The walk has just moved from \(t\) to \(v\). Each neighbour \(x\) of \(v\) gets a weight that depends on how far \(x\) is from the previous node \(t\); the next node is drawn with probability proportional to the weight.
Why it has this form. A neighbour of \(v\) can only be at distance 0, 1 or 2 from \(t\), so three weights cover every case. A small \(p\) makes returning likely and a large \(q\) makes moving away unlikely: the walk stays local, like breadth-first search, and the embeddings capture who plays a similar local role. A small \(q\) pushes the walk outward, like depth-first search, and the embeddings capture communities. With \(p=q=1\) all weights are 1 and the walk is DeepWalk's uniform walk.
Watch out. The weights are not probabilities until they are divided by their sum, and the sum is different at every step. The walk needs to remember one previous node, which is why it is called second-order.
5What is being factorised
In words. DeepWalk with window size \(T\) and \(b\) negatives behaves like factorising one fixed matrix: the logarithm of how much more often two nodes co-occur on walks than their degrees alone would predict.
Why it has this form. \(D^{-1}A\) is the transition matrix of the random walk: entry \((u,v)\) is the probability of stepping from \(u\) to \(v\). Its \(r\)-th power gives \(r\)-step probabilities, and the average over \(r=1..T\) covers every distance inside the window. The factor \(\mathrm{vol}(G)\) and the trailing \(D^{-1}\) divide by the chance of meeting \(v\) at random, which turns the entry into pointwise mutual information; \(-\log b\) is a shift caused by the negatives. The simplest relative, \(\min_{\mathbf Z}\lVert A-\mathbf Z^\top\mathbf Z\rVert_F\), factorises the adjacency matrix itself: similarity = being linked.
Watch out. The equivalence holds in the limit of many walks and enough dimensions. For pairs that never co-occur the entry is \(\log 0\); practical factorisation methods clip the matrix at zero.
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: what is "task-independent" about these embeddings? show answer
They are learned without any labels, so the same vectors can be reused for any task afterwards.
from From feature engineering to representation learning
Check yourself: where does the "supervision signal" come from if there are no labels? show answer
From the graph itself: the similarity function, computed from structure, plays the role of the target.
from What does 'similar' mean? Self-supervised and task-independent
Check yourself: what does sum-pooling lose? show answer
Two graphs with the same multiset of node embeddings get the same \(z_G\), even if they are wired differently. Lecture 6 on GNN expressiveness returns to this.
Check yourself: which of the three limitations does node2vec's BFS-like setting (low \(p\)) partly address, and why only partly? show answer
Structural similarity: low \(p\) makes neighbourhoods describe local surroundings, but two nodes still need to share actual neighbours to co-occur on walks, so distant look-alikes stay apart.
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.
- From feature engineering to representation learning
- Setup and the encoder–decoder framework
- The shallow encoder: an embedding lookup
- What does 'similar' mean? Self-supervised and task-independent
- Notation, and what a random walk is
- Random-walk embeddings: the idea and why it works
- Turning it into an optimization problem
- Negative sampling
- Optimizing with stochastic gradient descent
- Which walks? From DeepWalk to node2vec
- The biased random walk: parameters p and q
- The node2vec algorithm, other walk ideas, and which to use
- Embedding entire graphs
- Node embeddings as matrix factorization
- Using embeddings, and the lecture summary
- Limitations of shallow embeddings
From feature engineering to representation learning slides 7-11 ↗
Slide 7 recaps the traditional ML pipeline on graphs: given an input graph, a human designs structured features (node-level, edge-level and graph-level features such as degree, centrality or graphlet counts), and then a learning algorithm (SVM, neural network, etc.) maps these features to labels for the downstream prediction task. The weak point is the feature-engineering step: it must be redone, by hand, for every new task and domain.
Slide 8 shows the alternative. Graph representation learning removes the need to do feature engineering every single time: the "feature engineering" box is crossed out and replaced by representation learning, which learns the features automatically.
Slide 9 states the goal: efficient, task-independent feature learning for machine learning with graphs. We want a map
\[ f: u \to \mathbb{R}^d \]that sends each node \(u\) to a \(d\)-dimensional vector, its feature representation or embedding.
Slide 10 says what a good embedding should do:
- Similarity of embeddings indicates similarity in the network. For example, two nodes connected by an edge should get nearby vectors.
- Encode network information in the vector.
- Be usable for many downstream predictions: node classification, link prediction, graph classification, anomalous node detection, clustering, and more. The same vectors feed all these tasks.
Slide 11 shows an example from the DeepWalk paper (Perozzi et al., KDD 2014): Zachary's Karate Club network (left, nodes coloured by community) and its 2D embedding (right). Nodes of the same colour land close together in the plane, and the four communities become four visible clusters. So the embedding, learned only from the graph structure, has recovered the community structure.
Check yourself: what is "task-independent" about these embeddings? show answer
They are learned without any labels, so the same vectors can be reused for any task afterwards.
Setup and the encoder–decoder framework slides 13-17 ↗
Slide 13 fixes the setup. We have an undirected graph \(G\) with vertex set \(V\) and binary adjacency matrix \(A\). For simplicity, no node features or extra information are used; only the structure. The example graph has \(V = \{1, 2, 3, 4\}\) and edges 1–2, 1–4, 2–4, 3–4, so
\[ A = \begin{pmatrix} 0&1&0&1\\ 1&0&0&1\\ 0&0&0&1\\ 1&1&1&0 \end{pmatrix}. \]Slide 14 states the goal: encode nodes so that similarity in the embedding space (e.g., dot product) approximates similarity in the graph. The figure shows an encoder ENC mapping node \(u\) to \(z_u\) and node \(v\) to \(z_v\) in the embedding space. Slide 15 writes the goal as
\[ \text{similarity}(u, v) \approx z_v^\top z_u , \]where the left side is similarity in the original network (which we still need to define) and the right side is similarity of the embeddings.
Slide 16 lists the four steps of learning node embeddings:
- An encoder maps nodes to embeddings.
- Define a node similarity function, i.e., a measure of similarity in the original network.
- A decoder DEC maps a pair of embeddings to a similarity score.
- Optimize the encoder's parameters so that \(\text{DEC}(z_v^\top z_u) \approx \text{similarity}(u, v)\).
Slide 17 names the two key components. The encoder maps each node to a low-dimensional vector: \(\text{ENC}(v) = z_v\), a \(d\)-dimensional embedding of node \(v\). The similarity function says how relations in vector space map to relations in the network. Here the decoder is simply the dot product between node embeddings.
The shallow encoder: an embedding lookup slides 18-21 ↗
Slides 18–20 give the simplest encoder: the encoder is just an embedding lookup.
\[ \text{ENC}(v) = z_v = Z \cdot v, \qquad Z \in \mathbb{R}^{d \times |V|}, \quad v \in \mathbb{I}^{|V|}. \]- \(Z\) is a matrix with one column per node; each column is that node's embedding. This matrix is what we learn and optimize.
- \(v\) is an indicator (one-hot) vector: all zeros except a one in the position of node \(v\). Multiplying \(Z\) by it simply picks out column \(v\).
- The number of rows \(d\) is the dimension (size) of the embeddings (slide 19's picture: a \(d \times |V|\) box with one highlighted column).
Slide 20 summarises: each node is assigned a unique embedding vector, i.e., we directly optimize the embedding of each node. Many methods work this way, including DeepWalk and node2vec.
Slide 21 summarises the whole framework:
- Shallow encoder: embedding lookup. Parameters to optimize: \(Z\), which contains the embeddings \(z_u\) for all \(u \in V\). Deep encoders (GNNs) come in later lectures.
- Decoder: based on node similarity.
- Objective: maximize \(z_v^\top z_u\) for node pairs \((u, v)\) that are similar.
"Shallow" means there is no function that computes an embedding from inputs; there is just a table. The number of parameters is \(d \cdot |V|\), which grows with the graph, and nothing is shared between nodes. This is the root of the limitations at the end of the lecture.
What does 'similar' mean? Self-supervised and task-independent slides 22-23 ↗
Slide 22: the key choice that distinguishes methods is how they define node similarity. Should two nodes have similar embeddings if they
- are linked?
- share neighbours?
- have similar "structural roles" (e.g., both are hubs, or both are bridges)?
These are genuinely different notions. Two hubs at opposite ends of a network are similar by role but far apart by distance. The lecture now builds a similarity defined by random walks, and shows how to optimize embeddings for it.
Slide 23 stresses the nature of this learning:
- It is an unsupervised / self-supervised way of learning node embeddings. We use no node labels and no node features.
- The goal is to directly estimate a set of coordinates (the embedding) for each node so that some aspect of the network structure, the one captured by DEC, is preserved.
- The embeddings are task independent: they are not trained for a specific task, but can be used for any task.
Check yourself: where does the "supervision signal" come from if there are no labels? show answer
From the graph itself: the similarity function, computed from structure, plays the role of the target.
Notation, and what a random walk is slides 25-27 ↗
Slide 25 fixes notation used in the rest of the lecture:
- \(z_u\): the embedding of node \(u\), which we want to find.
- \(P(v \mid z_u)\): the model's predicted probability of visiting node \(v\) on random walks starting from node \(u\).
- Softmax turns a vector of \(K\) real numbers into \(K\) probabilities that sum to 1: \[ S(z)[i] = \frac{e^{z[i]}}{\sum_{j=1}^{K} e^{z[j]}}. \]
- Sigmoid is an S-shaped function that maps a real number into \((0, 1)\): \[ \sigma(x) = \frac{1}{1 + e^{-x}}. \]
Slide 26 defines a random walk: given a graph and a starting point, select a neighbour at random and move to it; then select a neighbour of this point at random and move to it; and so on. The random sequence of nodes visited is a random walk on the graph. The figure shows a 5-step walk on a 12-node graph, starting at the highlighted (smiley-face) node and moving to 5, then 8, 9, back to 8, and 11 (steps 1–5 marked by red arrows). Note that a walk may revisit nodes.
Slide 27 states the core idea in one line:
\[ z_u^\top z_v \approx \text{probability that } u \text{ and } v \text{ co-occur on a random walk over the graph.} \]This is the similarity function we were missing on slide 15. It is defined by a random process, not by a fixed formula.
Random-walk embeddings: the idea and why it works slides 28-30 ↗
Slide 28 gives the two-step recipe:
- Estimate the probability of visiting node \(v\) on a random walk starting from node \(u\), using some random walk strategy \(R\). Call it \(P_R(v \mid u)\).
- Optimize embeddings to encode these random-walk statistics. The figure shows two vectors \(z_i, z_j\) with angle \(\theta\) between them: similarity in the embedding space (here the dot product, which equals \(\cos\theta\) for unit vectors) should be proportional to \(P_R(v \mid u)\).
Slide 29 explains why random walks:
- Expressivity. They give a flexible, stochastic definition of node similarity that includes both local and higher-order (multi-hop) neighbourhood information. Idea: if a random walk from \(u\) visits \(v\) with high probability, then \(u\) and \(v\) are similar.
- Efficiency. Training does not need all \(|V|^2\) node pairs; it only needs the pairs that co-occur on random walks.
Slide 30 restates the setting as unsupervised feature learning. Intuition: find embeddings in \(d\)-dimensional space that preserve similarity. Idea: learn embeddings so that nodes that are nearby in the network are close together in embedding space. How do we define "nearby"? With \(N_R(u)\), the neighbourhood of \(u\) obtained by some random walk strategy \(R\).
This is the analogy that DeepWalk took from word2vec: a random walk is a "sentence" of nodes, and nodes that appear in the same context should get similar vectors, just as words that appear in similar contexts do.
Turning it into an optimization problem slides 31-34 ↗
Slide 31: given \(G = (V, E)\), we want a mapping \(f: u \to \mathbb{R}^d\), \(f(u) = z_u\). The log-likelihood objective is
\[ \max_{z} \sum_{u \in V} \log P\big(N_R(u) \mid z_u\big), \]where \(N_R(u)\) is the neighbourhood of \(u\) under strategy \(R\). In words: given node \(u\), learn a representation that is predictive of the nodes in its random-walk neighbourhood.
Slide 32 gives the procedure:
- Run short fixed-length random walks from each node \(u\) using strategy \(R\).
- For each \(u\), collect \(N_R(u)\), the multiset of nodes visited on walks from \(u\). It is a multiset because a node can be visited many times, and repeated visits should count more.
- Optimize embeddings by maximum likelihood: given node \(u\), predict its neighbours \(N_R(u)\).
Slide 33 writes the equivalent minimization, assuming the neighbours are predicted independently given \(z_u\):
\[ \min_{z} \mathcal{L} = \sum_{u \in V} \sum_{v \in N_R(u)} -\log P(v \mid z_u). \]Intuition: minimize the negative log-likelihood of the random-walk neighbourhoods. The probability is parameterized with a softmax:
\[ P(v \mid z_u) = \frac{\exp(z_u^\top z_v)}{\sum_{n \in V} \exp(z_u^\top z_n)}. \]Why softmax? We want node \(v\) to be the most similar to \(u\) out of all nodes \(n\); since \(\sum_i \exp(x_i) \approx \max_i \exp(x_i)\), the softmax is a smooth version of picking the maximum.
Slide 34 puts it together:
\[ \mathcal{L} = \sum_{u \in V} \; \sum_{v \in N_R(u)} -\log\left( \frac{\exp(z_u^\top z_v)}{\sum_{n \in V} \exp(z_u^\top z_n)} \right). \]The outer sum runs over all nodes \(u\); the inner sum over nodes \(v\) seen on walks from \(u\); the fraction is the predicted probability that \(u\) and \(v\) co-occur. Optimizing random-walk embeddings = finding embeddings \(z_u\) that minimize \(\mathcal{L}\).
Negative sampling slides 35-38 ↗
Slides 35–36: doing this naively is too expensive. The outer sum over \(u \in V\) and the softmax denominator's sum over \(n \in V\) are nested, giving \(O(|V|^2)\) complexity. The culprit is the normalization term of the softmax. Can we approximate it?
Slide 37 gives the solution, negative sampling:
\[ \log\left( \frac{\exp(z_u^\top z_v)}{\sum_{n \in V} \exp(z_u^\top z_n)} \right) \approx \log \sigma(z_u^\top z_v) + \sum_{i=1}^{k} \log \sigma(-z_u^\top z_{n_i}), \qquad n_i \sim P_V. \]- \(\sigma\) is the sigmoid; it makes each term a "probability" between 0 and 1.
- Instead of normalizing against all nodes, we only compare against \(k\) random "negative samples" \(n_i\), drawn from a background distribution \(P_V\) over nodes.
- Why is this valid? Technically it is a different objective. But negative sampling is a form of Noise Contrastive Estimation (NCE), which approximately maximizes the log-probability of the softmax. The new form is a logistic regression that distinguishes the true target \(v\) from the noise nodes \(n_i\). (Reference on the slide: arXiv 1402.3722.)
- Negative sampling makes the likelihood quick to compute: \(k+1\) dot products instead of \(|V|\).
Slide 38 adds practical details. Sample the \(k\) negative nodes with probability proportional to their degree. Two considerations for \(k\): (1) higher \(k\) gives more robust estimates; (2) higher \(k\) puts more bias on negative events. In practice \(k = 5\)–\(20\). Can a negative sample be any node, or only nodes not on the walk? People often sample any node, for efficiency.
Optimizing with stochastic gradient descent slides 39-41 ↗
Slide 39: once we have the objective \(\mathcal{L} = \sum_{u}\sum_{v \in N_R(u)} -\log P(v \mid z_u)\), how do we minimize it? Gradient descent:
- Initialize \(z_u\) at random for all nodes \(u\).
- Iterate until convergence: for all \(u\), compute the derivative \(\partial\mathcal{L}/\partial z_u\); then for all \(u\), step in the reverse direction: \(z_u \leftarrow z_u - \eta\, \partial\mathcal{L}/\partial z_u\), where \(\eta\) is the learning rate.
Slide 40: stochastic gradient descent (SGD) evaluates the gradient on individual training examples instead of all of them. Define the per-node loss
\[ \mathcal{L}^{(u)} = \sum_{v \in N_R(u)} -\log P(v \mid z_u). \]- Initialize \(z_u\) at random for all \(u\).
- Iterate until convergence: sample a node \(u\); for all \(v\), compute \(\partial\mathcal{L}^{(u)}/\partial z_v\) and update \(z_v \leftarrow z_v - \eta\, \partial\mathcal{L}^{(u)}/\partial z_v\).
Each step is cheap and noisy, but on average it moves in the right direction; this is what makes training on millions of nodes possible.
Slide 41 summarises random-walk embeddings in three steps:
- Run short fixed-length random walks from each node.
- For each node \(u\), collect \(N_R(u)\), the multiset of nodes visited on walks from \(u\).
- Optimize the embeddings \(Z\) with SGD on \(\mathcal{L} = \sum_u \sum_{v \in N_R(u)} -\log P(v \mid z_u)\), approximated efficiently with negative sampling.
Which walks? From DeepWalk to node2vec slides 42-46 ↗
Slide 42: so far we optimized embeddings for a given walk strategy \(R\). Which strategy should we use? The simplest idea is to run fixed-length, unbiased random walks from each node. This is DeepWalk (Perozzi et al., KDD 2014). The issue: this notion of similarity is too constrained. How can we generalize it?
Slide 43 gives the overview of node2vec (Grover & Leskovec, KDD 2016):
- Goal: embed nodes with similar network neighbourhoods close together in feature space.
- Framed as maximum-likelihood optimization, independent of the downstream task.
- Key observation: a flexible notion of network neighbourhood \(N_R(u)\) leads to richer node embeddings.
- Method: a biased 2nd-order random walk \(R\) to generate \(N_R(u)\). "2nd-order" means the next step depends on the current node and the previous one.
Slide 44: the idea is to use flexible, biased walks that can trade off between local and global views of the network.
Slide 45 shows the two classic strategies on a graph where \(u\) has neighbours \(s_1, s_2, s_3, s_4\), and a path \(u \to s_4 \to s_5 \to s_6\) leads into a second cluster (\(s_6\)–\(s_9\)). With a neighbourhood of size 3:
\[ N_{BFS}(u) = \{s_1, s_2, s_3\} \quad \text{(local, microscopic view)}, \qquad N_{DFS}(u) = \{s_4, s_5, s_6\} \quad \text{(global, macroscopic view)}. \]Slide 46 summarises with two pictures: BFS stays among the immediate neighbours and gives a micro-view of the neighbourhood; DFS runs away along a path and gives a macro-view.
Intuition: BFS-like neighbourhoods describe a node's immediate surroundings (good for detecting structural roles, e.g., hub vs. periphery); DFS-like neighbourhoods describe which region of the graph a node lives in (good for communities, i.e., homophily).
The biased random walk: parameters p and q slides 47-50 ↗
Slide 47 defines the biased fixed-length walk \(R\) that generates \(N_R(u)\). It has two parameters:
- Return parameter \(p\): controls returning back to the previous node.
- In-out parameter \(q\): controls moving outwards (DFS) versus inwards (BFS). Intuitively, \(q\) is the "ratio" of BFS vs. DFS.
We specify one step of the walk; a walk is just a sequence of such steps.
Slide 48: the walk has just traversed edge \((t, w)\) and is now at \(w\). We set transition probabilities on the edges out of \(w\). Insight: every neighbour of \(w\) is at distance 0, 1 or 2 from \(t\): it is \(t\) itself (distance 0), a common neighbour of \(t\) and \(w\) (distance 1), or a node farther from \(t\) (distance 2). In the figure, \(s_1\) is at distance 1 from \(t\) and \(s_2\) is at distance 2.
Slides 49–50 assign the unnormalized transition probabilities:
| Target \(x\) | Distance \(d(t, x)\) | Weight |
|---|---|---|
| \(t\) (go back) | 0 | \(1/p\) |
| \(s_1\) (stay near \(t\)) | 1 | \(1\) |
| \(s_2\) (move away) | 2 | \(1/q\) |
| \(s_3\) (move away) | 2 | \(1/q\) |
Normalize by the sum to get probabilities. A BFS-like walk uses a low \(p\) (it keeps returning to \(t\), so it stays close to the start). A DFS-like walk uses a low \(q\) (moving outward is cheap). \(N_R(u)\) is the multiset of nodes visited by this biased walk. With \(p = q = 1\) all weights are 1 and we get DeepWalk's uniform walk.
Worked example (our numbers, for practice): with \(p = 0.5, q = 2\) the weights are \(2, 1, 0.5, 0.5\), sum 4, so the probabilities are \(0.5, 0.25, 0.125, 0.125\): a strongly local, BFS-like walk.
Slide 50's heading says the walker "came over edge \((s_1, w)\)", but its figure and table treat \(t\) as the previous node. Read it as edge \((t, w)\), as on slides 48–49.
The node2vec algorithm, other walk ideas, and which to use slides 51-54 ↗
Slide 51 gives the node2vec algorithm:
- Compute edge transition probabilities: for each edge \((t, w)\), compute the walk probabilities (from \(p, q\)) of the edges \((w, \cdot)\).
- Simulate \(r\) random walks of length \(l\) starting from each node \(u\).
- Optimize the node2vec objective with stochastic gradient descent (the same objective as before, with negative sampling).
It has linear-time complexity, and all three steps are individually parallelizable.
Slide 52 lists other random-walk ideas:
- Other kinds of biased walks: based on node attributes (Dong et al.) or on learned weights (Abu-El-Haija et al.).
- Alternative optimization: directly optimize based on 1-hop and 2-hop random-walk probabilities (LINE, Tang et al.).
- Network preprocessing: run random walks on modified versions of the network (Ribeiro et al., struc2vec; Chen et al., HARP).
Slide 53 summarises so far. Core idea: embed nodes so that distances in embedding space reflect node similarities in the original network. Different notions of similarity: naïve (similar if connected), and random-walk approaches (today).
Slide 54: which method should you use? No method wins in all cases. For example, node2vec does better on node classification while other methods do better on link prediction (Goyal and Ferrara, survey). Random-walk approaches are generally more efficient. In general: choose the definition of node similarity that matches your application.
Embedding entire graphs slides 56-60 ↗
Slide 56: sometimes we want to embed a subgraph or an entire graph \(G\) as a vector \(z_G\). Tasks: classifying toxic vs. non-toxic molecules, identifying anomalous graphs.
Slide 57, approach 1 (simple but effective): run a standard node-embedding technique on the (sub)graph \(G\), then sum (or average) the node embeddings:
\[ z_G = \sum_{v \in G} z_v . \]Duvenaud et al. used this to classify molecules by their graph structure.
Slide 58, approach 2: introduce a "virtual node" that represents the (sub)graph, connect it to the nodes of the (sub)graph, and run a standard node-embedding technique. The virtual node's embedding is \(z_G\). Proposed by Li et al. as a general technique for subgraph embedding.
Slide 59 recaps the two ideas: (1) embed nodes and sum/average them; (2) create a super-node that spans the (sub)graph and embed that node.
Slide 60 previews hierarchical embeddings with DiffPool: hierarchically cluster the nodes, sum/average the node embeddings within clusters, and repeat. The figure shows the original network pooled into a smaller network at level 1, then level 2, then a single node at level 3, which feeds a graph classifier.
Check yourself: what does sum-pooling lose? show answer
Two graphs with the same multiset of node embeddings get the same \(z_G\), even if they are wired differently. Lecture 6 on GNN expressiveness returns to this.
Node embeddings as matrix factorization slides 62-66 ↗
Slide 62 recalls that the encoder is an embedding lookup into \(Z\) (one column per node), with the objective "maximize \(z_v^\top z_u\) for similar pairs".
Slide 63 takes the simplest similarity: \(u\) and \(v\) are similar if they are connected by an edge. Then we want
\[ z_v^\top z_u = A_{u,v}, \]the \((u, v)\) entry of the adjacency matrix. Stacking all pairs: \(Z^\top Z = A\). The figure shows the 4-node graph from slide 13, its matrix \(A\), and \(A\) written as the product \(Z^\top Z\): entry \((u,v)\) is the dot product of columns \(z_u\) and \(z_v\).
Slide 64: the dimension \(d\) (rows of \(Z\)) is much smaller than the number of nodes \(n\), so an exact factorization \(A = Z^\top Z\) is generally impossible (the rank of \(Z^\top Z\) is at most \(d\)). We learn \(Z\) approximately:
\[ \min_{Z} \lVert A - Z^\top Z \rVert_2 , \]minimizing the L2 (Frobenius) norm. Today's random-walk methods used softmax instead of L2, but the goal of approximating a similarity matrix with \(Z^\top Z\) is the same. Conclusion: an inner-product decoder with edge-connectivity similarity is equivalent to matrix factorization of \(A\).
Slides 65–66: DeepWalk and node2vec use a more complex, random-walk-based similarity, but they too are matrix factorizations. DeepWalk is equivalent to factorizing
\[ \log\left( \mathrm{vol}(G) \left( \frac{1}{T} \sum_{r=1}^{T} (D^{-1}A)^r \right) D^{-1} \right) - \log b , \]where (slide 66):
- \(\mathrm{vol}(G) = \sum_i \sum_j A_{i,j}\) is the volume of the graph (twice the number of edges);
- \(D\) is the diagonal degree matrix, \(D_{u,u} = \deg(u)\);
- \((D^{-1}A)^r\) is the \(r\)-th power of the normalized adjacency matrix;
- \(T = |N_R(u)|\) is the context window size;
- \(b\) is the number of negative samples.
node2vec can also be written as a matrix factorization, of a more complex matrix. Reference: Qiu et al., "Network Embedding as Matrix Factorization: Unifying DeepWalk, LINE, PTE, and node2vec" (WSDM 2018).
Using embeddings, and the lecture summary slides 67-68 ↗
Slide 67: how to use the embeddings \(z_i\):
- Clustering / community detection: cluster the points \(z_i\).
- Node classification: predict the label of node \(i\) from \(z_i\).
- Link prediction: predict edge \((i, j)\) from \((z_i, z_j)\). Combine the two vectors with a function \(f\) and feed it to a classifier \(g\):
- Concatenate: \(f(z_i, z_j) = g([z_i, z_j])\)
- Hadamard (per-coordinate product): \(f(z_i, z_j) = g(z_i * z_j)\)
- Sum/average: \(f(z_i, z_j) = g(z_i + z_j)\)
- Distance: \(f(z_i, z_j) = g(\lVert z_i - z_j \rVert_2)\)
- Graph classification: get a graph embedding \(z_G\) by aggregating node embeddings or with a virtual node, then predict the label from \(z_G\).
For an undirected edge, sum, Hadamard and distance are symmetric in \(i, j\); concatenation is not, so it suits directed links.
Slide 68 summarises the lecture: graph representation learning learns node and graph embeddings for downstream tasks without feature engineering. The encoder–decoder framework: encoder = embedding lookup; decoder = a score from the embeddings that matches node similarity. Node similarity measure: (biased) random walks, e.g., DeepWalk and node2vec. Extension to graph embedding: aggregate node embeddings.
Limitations of shallow embeddings slides 69-71 ↗
Slides 69–71 list the limitations of node embeddings via matrix factorization and random walks.
1. Transductive, not inductive (slide 69).
- We cannot obtain embeddings for nodes not in the training set. The figure adds a new node 5 at test time (e.g., a new user in a social network) attached to node 2; DeepWalk/node2vec cannot compute its embedding, and all node embeddings must be recomputed.
- We cannot apply the model to new graphs.
- If you run DeepWalk on the same graph several times, you get a different embedding each time. Why? The walks and the initialization are random, and the objective only depends on dot products \(z_u^\top z_v\), which do not change under any rotation of all embeddings. So the solution is defined only up to such transformations.
2. No structural similarity (slide 70). In the figure, nodes 1 and 11 are structurally similar: each is in a triangle (1–2–3 and 11–12–13) with degree 2, and the two triangles are joined by a long path 3–4–5–…–10–13. Yet they get very different embeddings, because a random walk from node 1 is unlikely to reach node 11. DeepWalk and node2vec do not capture structural similarity; they capture proximity.
3. No features (slide 71). They cannot use node, edge or graph features, e.g., protein properties in a protein–protein interaction graph (the green bars in the figure). The embeddings ignore them.
The solution to all three: deep representation learning and graph neural networks, covered next. A GNN computes an embedding as a function of a node's features and neighbourhood, so it works for new nodes, sees local structure and uses features.
Check yourself: which of the three limitations does node2vec's BFS-like setting (low \(p\)) partly address, and why only partly? show answer
Structural similarity: low \(p\) makes neighbourhoods describe local surroundings, but two nodes still need to share actual neighbours to co-occur on walks, so distant look-alikes stay apart.
Not shown (no new content): slides 1-6,12,24,55,61 — title slide, announcements (Colabs, project partners), section dividers.
Review: what to keep from this session
Carried forward. Lecture 3 keeps the decoder and the idea of "similar nodes, similar vectors" but replaces the lookup-table encoder by a neural network that uses the neighbourhood and the features. Lecture 10 reuses the same shallow-embedding style for knowledge graphs, and Lecture 11 reuses the dot-product decoder for recommendation.
Quick self-check
Why is a random walk a sensible definition of node similarity?
It mixes local and higher-order neighbourhood information and is cheap: only the pairs that co-occur on walks need to be considered, not all |V|² pairs.
What do p and q control in node2vec?
The return parameter p penalises stepping back to the previous node; the in-out parameter q biases towards staying close (BFS, small q favours DFS). They trade off local versus structural similarity.
Give the three limits of shallow embeddings.
No parameter sharing (one vector per node), no use of node features, and no embedding for nodes unseen at training time (transductive).
Key idea
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.
Worked example: one node2vec step
The walker came from \(t\) to \(w\). Neighbours of \(w\): \(t\) (distance 0 from \(t\)), \(s_1\) (also adjacent to \(t\): distance 1), \(s_2, s_3\) (distance 2). Take \(p=4,\ q=0.5\).
- Unnormalised weights: \(t:1/p=0.25\); \(s_1: 1\); \(s_2: 1/q=2\); \(s_3: 2\).
- Sum = 5.25. Probabilities: \(t: 0.048\), \(s_1: 0.19\), \(s_2: 0.38\), \(s_3: 0.38\).
- Interpretation: rarely go back (\(p\) large), strongly prefer to move away (\(q\) small) → a DFS-like, exploratory walk → embeddings reflect communities / homophily.
- Swap to \(p=0.5,\ q=4\): weights \(2, 1, 0.25, 0.25\) → probabilities \(0.57, 0.29, 0.07, 0.07\): the walk stays local (BFS-like).
Strictly speaking: on weighted graphs the weight is \(\alpha_{pq}(t,x)\cdot w_{wx}\). DeepWalk (the 2014 paper) used hierarchical softmax, not negative sampling; the matrix-factorisation result assumes negative sampling.
In code (PyG)
from torch_geometric.nn import Node2Vec
model = Node2Vec(data.edge_index, embedding_dim=128, walk_length=20,
context_size=10, walks_per_node=10, num_negative_samples=1,
p=1.0, q=0.5, sparse=True)
loader = model.loader(batch_size=128, shuffle=True)
opt = torch.optim.SparseAdam(model.parameters(), lr=0.01)
for pos_rw, neg_rw in loader: # positive & negative walks
opt.zero_grad(); loss = model.loss(pos_rw, neg_rw); loss.backward(); opt.step()
z = model() # |V| x 128 embedding table
Proof workshop: Where a random walk spends its time
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. Let \(G\) be a connected, non-bipartite, undirected graph with \(|E|\) edges, and \(P=D^{-1}A\) the simple random walk. Prove that \(\pi_v=d_v/2|E|\) is a stationary distribution, and that it is the unique one.
Hint 1
Hint 2
Solution
Why it matters. A walk visits nodes in proportion to degree, so DeepWalk's co-occurrence counts are degree-weighted. That is why NetMF's closed form has \(\mathrm{vol}(G)\) and \(D^{-1}\) in it, and why word2vec-style negative sampling uses \(d^{3/4}\): to damp the hubs. On X, hubs are celebrities and news accounts; a walk-based embedding of "the average user" is mostly about them unless you correct for it.
Sharper lens: what the dot product can and cannot hold
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.
What skip-gram with negative sampling converges to
Levy and Goldberg (2014) solved the objective pointwise: with \(b\) negatives per positive, the loss is minimised when
\[ \mathbf z_u^\top\mathbf c_v=\log\frac{\#(u,v)\,|D|}{\#(u)\,\#(v)}-\log b=\mathrm{PMI}(u,v)-\log b, \]
the pointwise mutual information of the pair in the walk corpus \(D\), shifted by \(\log b\). NetMF's formula in section 5 is this PMI written in closed form for DeepWalk's corpus. Read spectrally, \(\frac1T\sum_{r=1}^{T}P^r\) multiplies each eigenvalue \(\lambda\) of the walk matrix by \(\frac1T\sum_r\lambda^r\): near 1 for \(\lambda\approx1\) (the slow, community-scale eigenvectors) and near 0 for negative \(\lambda\). The window size \(T\) is the cut-off of a low-pass filter. The same filter returns as GCN's \(\hat A\) (Lecture 3), LightGCN (Lecture 11) and SGC (Lecture 20).
One vector per node is a positive semi-definite model
With a single table, the score matrix \(Z^\top Z\) is positive semi-definite. A network where links join unlike nodes has large negative eigenvalues (for \(K_{n,n}\) the adjacency eigenvalues are \(\pm n\)), and a PSD model cannot follow them at any dimension. Seshadhri et al. (PNAS 2020) argued that low-dimensional dot-product embeddings cannot reproduce the many triangles around low-degree nodes that real social networks have.
The reply (Chanpuriya et al., NeurIPS 2020) is instructive: the obstruction comes from tying the two sides. With separate source and target vectors and a logistic link, \(\sigma(XY^\top)\), every graph of maximum degree \(\Delta\) has an exact factorisation of rank \(2\Delta+1\). word2vec and DeepWalk already train two tables, node vectors \(\mathbf z\) and context vectors \(\mathbf c\) (as in the formula above), and then throw one away. If your graph is directed or heterophilous, keep both.
Comparing two runs: the Procrustes problem
Section 6 says embeddings are defined only up to an orthogonal map \(Q\). So how do you compare this month's embedding \(Z_1\) of a network with last month's \(Z_2\) (rows = the same nodes)? Find the rotation that aligns them best, \(\min_{Q^\top Q=I}\lVert Z_1Q-Z_2\rVert_F\), before measuring any drift.
Solution
Lab: hands-on and practical tips
Try it live. In the Graph Explorer: bend a node2vec walk with p and q, then train DeepWalk and lay the graph out by its embedding. Each lesson has predict-then-check questions.
notebook · L02 node embeddings implements random walks, the node2vec bias, skip-gram with negative sampling, evaluates on Cora and reproduces NetMF.
notebooks/cs224w/cache/; do the same so that evaluation changes do not retrain everything.Readings & lookup guide
lecture notes CS224W course notes (Leni Aniva, Autumn 2024 — in your course folder)
- Ch. 2 — Node embeddings (pp. 11–17)
Reading order: DeepWalk → node2vec → NetMF. You already have companion notes on the first two in this project ("Reading DeepWalk and node2vec").
read first Perozzi, Al-Rfou, Skiena — DeepWalk: Online Learning of Social Representations (KDD 2014)
- Read: §3 (the power-law argument: vertex frequencies on walks look like word frequencies) and §4 (algorithm, SkipGram, hierarchical softmax). Fig. 1 is the one to remember.
- Skim: §5–6 experiments — the real result is strong performance when labels are scarce.
- Look up later: the parallel/online claims (§4.3) when thinking about streaming social data.
core Grover & Leskovec — node2vec: Scalable Feature Learning for Networks (KDD 2016)
- Read: §3.1 (BFS/DFS, homophily vs structural equivalence) and §3.2 (the \(p,q\) walk — the tidiest argument in the paper). Fig. 3 (Les Misérables with two settings) is the best intuition pump.
- Read critically: §3.3 says \(p,q\) are tuned on 10% labelled data — so "task-independent" is relaxed. Table 4 (link prediction) depends heavily on the binary operator (Hadamard wins).
deepens Qiu et al. — Network Embedding as Matrix Factorization: Unifying DeepWalk, LINE, PTE, and node2vec (WSDM 2018)
- Read: Table 1 (all four methods as closed-form matrices) and Theorem 2 (DeepWalk). Then §3.3 on the spectral (low-pass filter) interpretation — it connects directly to GCNs in Lecture 3.
- Skip on first pass: the PTE derivation; NetMF's large-T approximation details.
background Hamilton, GRL book — Chapter 3 (Neighborhood reconstruction methods)
- The cleanest presentation of the encoder–decoder view, with a table of decoders and similarity measures (Laplacian eigenmaps, GraRep, HOPE, DeepWalk, node2vec).
Homework & Colabs connected to this lecture
Colab 1 — Node embeddings from scratch due Thu 10/8
The hands-on twin of this lecture. Expect (based on earlier years): compute graph statistics on the Karate Club graph, build positive edges and sample negative edges, create an nn.Embedding table, score edges with a dot product + sigmoid, train with BCE loss, and plot the 2-D projection. Everything here is literally §2 above with \(N_R(u)\) = direct neighbours.
Homework 1 · Q1.2–1.5 and Q2 due Thu 10/15
- Q1.2 — write the random-walk transition matrix \(M\) and its stationary distribution (\(r=Mr\)). Uses \(D^{-1}A\) from §5.
- Q2.1–2.4 (24 pts) — "node embedding ⇔ matrix factorisation": identify the decoder of \(\min\|A-Z^\top Z\|\); bilinear decoder \(z_i^\top W z_j\); bonus: when is it eigendecomposition; multi-hop similarity ⇒ factorise \(\mathbb{1}[\sum_{r\le k}A^r>0]\)-type matrices.
- Q2.5–2.8 — node2vec vs struc2vec on two disjoint 10-cliques: can random walks ever see that the two cliques are structurally identical? (Use the limitation in §6.)
Self-check
In the shallow encoder \(\text{ENC}(v)=\mathbf{Z}\mathbf{1}_v\), what is learned?
- A neural network shared by all nodes
- One free vector per node (the columns of Z)
- The random-walk strategy
- The decoder weights
The encoder is a lookup table. That's why it can't handle unseen nodes (transductive).
Why is the naive softmax loss \(O(|V|^2)\)?
- Random walks are quadratic in length
- Each embedding has \(|V|\) dimensions
- The denominator sums over all nodes, for every (u, v) pair
- SGD needs all pairs
Outer sum over nodes × inner normalisation over all nodes. Negative sampling replaces the normaliser with k samples.
node2vec walker came from t to w. A neighbour x of w with dist(t, x) = 2 gets unnormalised weight …
- 1/q
- 1/p
- 1
- q/p
Distance 0 → 1/p (return), distance 1 → 1, distance 2 → 1/q (move outward).
With \(p=q=1\), node2vec becomes …
- LINE
- BFS
- a deterministic DFS
- DeepWalk (uniform walks)
All weights are 1 → uniform choice among neighbours.
Inner-product decoder + "similar iff linked" is equivalent to …
- spectral clustering of the Laplacian
- low-rank factorisation of A
- PageRank
- a 1-layer GCN
\(\mathbf{z}_u^\top\mathbf{z}_v\approx A_{uv}\) for all pairs ⇔ \(\mathbf{Z}^\top\mathbf{Z}\approx A\).
Two hubs in distant parts of a graph with identical local structure. DeepWalk will give them …
- identical embeddings
- embeddings that differ only by sign
- generally unrelated embeddings
- embeddings equal to their degree
They never co-occur on short walks, so nothing pulls them together: no structural similarity.
Flashcards (click to flip)
History & the bigger picture
- 1950s — the distributional hypothesis (Harris 1954; Firth 1957: "you shall know a word by the company it keeps"). Meaning is positional.
- 1971 — Lorrain & White, structural equivalence. Sociologists formalise "role" as having the same relations to the same others — the exact thing random walks miss.
- 2001–2003 — Laplacian eigenmaps, spectral embeddings. Embeddings by eigendecomposition; elegant but \(O(n^3)\).
- 2013 — word2vec (Mikolov et al.). SkipGram + negative sampling makes embeddings cheap.
- 2014 — DeepWalk: "walks are sentences". 2015 — LINE. 2016 — node2vec. 2017 — struc2vec, GraphSAGE. 2018 — NetMF shows they were all matrix factorisations.
DeepWalk imports a linguistic theory of meaning (structuralism) into graphs, and it works because social networks are largely homophilous — "birds of a feather". But a theory that defines you by your company has a political edge: platform-scale embeddings of people are the backbone of targeting and of "people like you also…" recommendations. The same mathematics that clusters a community of scholars also clusters a dissident network.
Classic SNA bridge
| In this lecture | Classic SNA counterpart | What carried over, what changed |
|---|---|---|
| Similarity by co-occurrence on random walks | Structural equivalence (Lorrain & White 1971) and regular equivalence (White & Reitz 1983); cohesion vs position | Random walks measure cohesion (being in the same neighbourhood), not position (playing the same role). SNA kept the two apart; DeepWalk only sees the first, which is why role embeddings (struc2vec, RolX) had to be reinvented. |
| Encoder–decoder with a dot-product similarity | Multidimensional scaling and correspondence analysis of the sociomatrix (Kruskal 1964; Laplacian eigenmaps 2003) | Embedding people in a low-dimensional space is old; what changed is the objective (sampled walks instead of all pairwise distances), which is what scales to millions of nodes. |
| node2vec's \(p, q\) interpolate BFS and DFS | Ego-network density vs reachability; "strong ties are local, weak ties bridge" (Granovetter 1973) | A BFS-like walk measures the ego-network (strong-tie world); a DFS-like walk follows bridges into other communities. node2vec is a learned version of the weak-tie distinction. |
| Negative sampling | Null models: configuration model, degree-preserving rewiring | Negatives play the role of the null model: they define what "not a tie" looks like. Degree-biased negatives are the configuration model in disguise. |
| NetMF: it was matrix factorisation all along | Blockmodels and spectral clustering of the sociomatrix (White, Boorman & Breiger 1976) | Factorising a (transformed) adjacency matrix to find positions is the blockmodel programme. NetMF closed the loop: the deep-learning heuristic approximates the classical algebra. |
Compute node2vec with \(q=0.5\) and \(q=2\) on a retweet graph, and a role embedding (struc2vec) on the same graph. Cluster each and compare the clusters against (a) community detection (Louvain) and (b) a classical role analysis (blockmodel / regular equivalence). You will see directly which sociological construct each embedding approximates, which is the kind of grounding most graph-ML papers lack.
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 3 · Centrality & link analysis (DeepWalk and node2vec: the random surfer's walks fed to word2vec); Unit 6 · Communities & statistical network models (node embeddings recover communities without being asked to).
Connecting to your research
Running project. Section L02–L04 · community 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/rings-in-communities (hypotheses written before running): do coordinated rings look like tiny communities? Reciprocal rings get their own Louvain community and their own Laplacian eigenvectors (an unsupervised score with AUC 0.997); co-amplification rings do not.
- Role vs community is a sociological distinction (Lorrain & White) that ML keeps rediscovering (RolX, struc2vec, GraphWave). Your SNA grounding is an advantage: you can state precisely which equivalence (structural, regular, automorphic) a method approximates.
- Neuro-symbolic angle: a "role" is a predicate over relational structure. Embeddings reach it only as unnamed geometry. Can you extract a logical description (e.g. "in a triangle and a bridge endpoint") from embedding clusters?
- Practical: on Twitter retweet graphs, try node2vec with \(q<1\) (communities / echo chambers) vs \(q>1\); compare against a struc2vec-like role embedding to separate "who is in the same camp" from "who plays the same broadcaster role".
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.
rings-in-communities
Question. Do coordinated rings look like tiny communities, or hide inside real ones? experiment folder ↗
Datasets for this session
From the repo's catalogue (gl.datasets; the full list with sources and licences is in data/README.md). Load one with gl.datasets.graph(name), temporal(name) or node_data(name).
| name | dataset | nodes | ground truth | good for |
|---|---|---|---|---|
karate | Zachary's karate club | 34 | club after the split (2) | community detection, the course's running toy graph |
football | NCAA college football 2000 | 115 | conference (12) | community detection with ground truth; node embeddings recover conferences |
email-eu-core | EU research institution e-mail | 1,005 | department (42) | community detection and node classification with ground truth |
cora | Cora citations | 2,708 | topic (7) | the default GNN benchmark |
Frontier 2025–26: what changed since the slides
Frontiers · random-walk embeddings are spectral methods · three waves of self-supervision
Words & phrases
| Term | Simple meaning | Persian | In context |
|---|---|---|---|
| catchn. | a hidden problem or disadvantage | ایراد پنهان، گیر کار | "The catch: these shallow embeddings are a lookup table" |
| transductiveadj. | works only for the exact items seen during training (opposite: inductive) | تراگذر (در برابر استقرایی) | "Transductive, not inductive" |
| homophilyn. | the tendency of similar people/things to be connected | همجوشی، همسانیگرایی | "social networks are largely homophilous" |
| random walkn. | a path made by repeatedly stepping to a uniformly random neighbour | گام تصادفی | "co-occurrence on short random walks" |
| embeddingn. | a vector that stands for an object, learned so that similar objects get nearby vectors | تعبیه (بازنمایی برداری) | "a 64-dimensional embedding per node" |
| negative samplingn. | training by contrasting true pairs with a few randomly drawn false pairs instead of all of them | نمونهبرداری منفی | "negative sampling with k = 5" |
| stationary distributionn. | the long-run share of time a random walk spends at each node | توزیع مانا | "the stationary distribution is proportional to degree" |
Also worth knowing: surrogate (a stand-in objective), tractable (computable in reasonable time — رامشدنی، قابل محاسبه).
Go deeper
- Next: Lecture 3 — replace the lookup table with a neural network that aggregates neighbours' features: inductive, feature-aware, parameter-sharing.
- Structural roles: Ribeiro et al., struc2vec (KDD 2017) — needed for HW1 Q2.5–2.8.
- Theory: Levy & Goldberg (2014), "Neural word embedding as implicit matrix factorization" — the word2vec ancestor of NetMF.
- Open question: walk length × window size gives a "receptive field". Is it the same object as a \(k\)-layer GNN's \(k\)-hop neighbourhood? (Homework 1 Q1.3 hints that mean-aggregation GNNs are random walks in expectation.)