Quant Memo
Core

Graph Convolutional Networks (GCN)

A GCN updates every node by averaging its neighbors' features, weighted so that well-connected nodes don't drown out sparsely-connected ones — the same idea as message passing, made concrete with one specific, carefully normalized weighting rule.

Prerequisites: Message Passing Neural Networks

Message passing says "aggregate your neighbors' features," but leaves open exactly how — a plain average treats a company with 2 suppliers and a company with 200 suppliers identically, diluting the 2-supplier company's signal a lot less than the 200-supplier one, which sounds fine until you realize a node's own influence on itself also needs the same fair treatment, and simply averaging can let extremely well-connected "hub" nodes dominate everything nearby. The graph convolutional network fixes this with one specific, careful normalization rule, borrowed from how image convolutions weight nearby pixels, adapted to a graph where "nearby" means "directly connected" rather than "physically adjacent."

The analogy: splitting a restaurant bill by table size, fairly

Imagine several tables at a shared event, and a rule that every table's food budget gets partly replaced by an average of the budgets at tables it's linked to (say, tables that share a serving station). A naive rule — "each linked table's budget counts equally, full weight" — breaks down the moment one table is linked to twenty others: that table's own original budget gets swamped, diluted into insignificance by twenty voices. A fairer version divides a table's contribution to its neighbors by how many neighbors it itself has, and divides what a table receives by how many neighbors it has — so a heavily-linked table's voice gets appropriately quieted (it's already sharing itself across many connections) while a table with few links keeps a clear, undiluted voice. This is exactly what a GCN's normalization does with node degree, the count of direct connections.

The mechanism: degree-normalized averaging

For node vv, one GCN layer computes

hv(k+1)=σ(uN(v){v}1dvduWhu(k))h_v^{(k+1)} = \sigma\left(\sum_{u \in \mathcal{N}(v) \cup \{v\}} \frac{1}{\sqrt{d_v}\sqrt{d_u}}\, W\, h_u^{(k)}\right)

Here dvd_v and dud_u are the degrees of nodes vv and uu — how many direct connections each has (node vv is always included as its own neighbor, so it never loses its own signal entirely), WW is a learned weight matrix shared across every node in the layer (the same transformation applied everywhere, so the network doesn't need a separate weight for every possible node), and σ\sigma is a nonlinearity like ReLU applied at the end. In words: sum up every neighbor's (and the node's own) feature vector after passing it through a shared learned transformation, but weight each term by one over the square root of both nodes' degrees — a symmetric normalization that shrinks the contribution of hub nodes on both the giving and receiving end, so that a highly-connected node neither dominates its neighbors nor gets overwhelmed by them.

Why 1/dvdu1/\sqrt{d_v d_u} specifically, rather than a plain 1/dv1/d_v average? A plain average normalizes only from the receiving node's side, but a hub node uu is also sending its influence to dozens of neighbors simultaneously, and without normalizing on the sending side too, that hub's raw feature vector gets injected at full strength into every one of those neighbors. Splitting the normalization symmetrically between both endpoints keeps the total influence balanced in both directions at once.

hub, d=6 weight per edge ≈ 1/√6 d=1 weight on its one edge ≈ 1
Degree normalization shrinks each edge's weight for a well-connected hub while leaving a sparsely connected node's single edge close to full strength.

Worked example 1: normalizing one node's update by hand

Node vv has degree dv=4d_v=4 (three neighbors plus itself). One neighbor uu has degree du=9d_u=9. The edge weight between them is 1/dvdu=1/36=1/60.1671/\sqrt{d_v d_u} = 1/\sqrt{36} = 1/6 \approx 0.167. Compare this to a second neighbor ww with degree dw=1d_w=1: edge weight 1/4×1=1/2=0.51/\sqrt{4 \times 1} = 1/2 = 0.5. Even though both uu and ww are single, direct neighbors of vv, node uu's high degree of 9 shrinks its per-edge influence to about a third of node ww's — the busy, well-connected neighbor gets automatically quieted relative to the sparsely-connected one, without the network ever being told explicitly which nodes are hubs.

Worked example 2: a full aggregation step

Take vv with degree dv=3d_v=3 (two neighbors AA, BB, plus itself), where dA=2d_A=2, dB=6d_B=6, and self-degree used as dv=3d_v=3. Suppose (for a single scalar feature, ignoring WW and σ\sigma for simplicity) hv=2.0h_v=2.0, hA=5.0h_A=5.0, hB=1.0h_B=1.0. The self-term uses weight 1/3×3=1/31/\sqrt{3\times3}=1/3, contributing 2.0/3=0.6672.0/3=0.667. The AA-term uses weight 1/3×2=1/60.4081/\sqrt{3\times2}=1/\sqrt{6}\approx0.408, contributing 5.0×0.408=2.0415.0\times0.408=2.041. The BB-term uses weight 1/3×6=1/180.2361/\sqrt{3\times6}=1/\sqrt{18}\approx0.236, contributing 1.0×0.236=0.2361.0\times0.236=0.236. Summing: 0.667+2.041+0.236=2.9440.667+2.041+0.236=2.944, then passed through WW and a nonlinearity in a real layer. Notice node BB, despite having the largest raw feature-to-degree ratio issue (degree 6), contributed less to vv's update than AA did, precisely because of its high degree.

A GCN layer is a degree-normalized weighted average of a node's neighbors (including itself), passed through a shared learned transformation and a nonlinearity. The normalization by 1/dvdu1/\sqrt{d_v d_u} is what keeps hub nodes from dominating the graph purely because they happen to have many connections.

What this means in practice

GCNs are a natural fit wherever financial entities form a network with meaningfully different connectivity — a company connected to two suppliers should be treated differently from one connected to two hundred, and a GCN's degree normalization builds that distinction in automatically rather than requiring hand-crafted features like "log of connection count" bolted on separately. They're used for node classification (will this company default, given its network context), and as a building block inside larger models for portfolio risk propagation across correlated or connected assets.

It's easy to assume degree normalization makes a GCN insensitive to how connected a node is, since it's specifically designed to "correct for" degree. It does the opposite of erasing that information — it rebalances influence, not awareness. The node's own degree is still implicitly present in how much its neighbors' information gets diluted versus concentrated, and stacking several GCN layers on a graph with very uneven degree distribution (a few extreme hubs, many sparse nodes) is a common source of the over-smoothing problem, because hub nodes still end up as intermediaries that many other nodes' representations pass through repeatedly.

Practice

  1. Two nodes, PP with degree 1 and QQ with degree 100, are both directly connected to node RR which has degree 10. Compute the edge weight for each and explain which neighbor influences RR more per edge.
  2. Why does the formula include the node itself in the neighborhood sum (N(v){v}\mathcal{N}(v) \cup \{v\}) rather than aggregating only over true neighbors?
  3. If every node in a graph had exactly the same degree dd, what would the degree-normalization term 1/dvdu1/\sqrt{d_v d_u} simplify to, and how would the GCN update compare to a plain unweighted average in that special case?

Related concepts

Practice in interviews

Further reading

  • Kipf & Welling, Semi-Supervised Classification with Graph Convolutional Networks (2016)
ShareTwitterLinkedIn