GraphSAGE: Generalizing Graph Embeddings

GraphSAGE : Guide Complet — Généralisation d'Embeddings de Graphes

GraphSAGE: Complete Guide — Generalizing Graph Embeddings

Summary — GraphSAGE (Graph Sample and Aggregate), introduced by Hamilton, Ying, and Leskovec in 2017, is an inductive approach for generating node embeddings. Unlike transductive methods (DeepWalk, node2vec, classical GCN) that require knowing all nodes during training, GraphSAGE learns an aggregation function that can generate embeddings for nodes never seen during training, using only their features and their neighborhood. This inductive property is critical for applications where the graph evolves dynamically (social networks, product recommendation, webs).


Mathematical Principle

1. Message Propagation

Like classical GNNs, GraphSAGE aggregates neighborhood features to update each node.

2. Generic Formulation

At each layer k, node v aggregates the embeddings of its neighbors N(v):

h_v^{(k)} = sigma(W_k · AGGREGATE([h_v^{(k-1)}, {h_u^{(k-1)} for u in N(v)}]))

The key to GraphSAGE is the AGGREGATE function, which must be permutation-invariant and differentiable.

3. Types of Aggregators

GraphSAGE offers three flexible aggregators:

Mean Aggregator (similar to GCN but without degree normalization):

AGG = mean([h_v^{(k-1)}, mean(h_u^{(k-1)} for u in N(v))])
h_v^{(k)} = sigma(W · AGG)

This is the simplest and most effective aggregator in practice.

LSTM Aggregator: Uses an LSTM to process neighbor embeddings in a random order (since the LSTM is not inherently permutation-invariant). The LSTM captures non-linear dependencies between neighbors but is more computationally expensive.

Pooling Aggregator: Applies a non-linear transformation followed by max-pooling:

AGG = max({sigma(W_pool · h_u^{(k-1)} + b) for u in N(v)})

Max-pooling acts as a pattern detector: each dimension of the pooling responds to a different pattern among the neighbors.

4. Neighborhood Sampling

For very large graphs, GraphSAGE samples a fixed subset of neighbors at each layer:

S_1 neighbors sampled at layer 1
S_2 neighbors sampled at layer 2

For example, with K=2 layers, S_1=25 and S_2=10, each node aggregates at most 10+25=35 neighbors, regardless of the node’s actual degree.


Intuition

A transductive network (node2vec, classical GCN) is like a phone book: it knows everyone but is lost when faced with a stranger. GraphSAGE is like a detective: it observes the associates and traits of a person it has never met and deduces who they are.

Imagine you arrive in a new city. Instead of memorizing every resident (transductive), you learn to recognize neighborhoods by their vibe: the cafés, shops, schools present. When you meet a new resident, you classify them by the neighborhood they live in. GraphSAGE does exactly this for nodes.


Python Implementation

1. Mean Aggregator

import torch
import torch.nn as nn
import torch.nn.functional as F


class MeanAggregator(nn.Module):
    def __init__(self, in_dim, out_dim):
        super().__init__()
        self.weight = nn.Linear(2 * in_dim, out_dim)

    def forward(self, self_feat, neighbor_feats):
        neighbor_mean = neighbor_feats.mean(dim=-2)
        combined = torch.cat([self_feat, neighbor_mean], dim=-1)
        return F.relu(self.weight(combined))


class GraphSAGE(nn.Module):
    def __init__(self, in_dim, hidden_dim, out_dim, num_layers=2):
        super().__init__()
        self.layers = nn.ModuleList()
        self.layers.append(MeanAggregator(in_dim, hidden_dim))
        for _ in range(num_layers - 1):
            self.layers.append(MeanAggregator(hidden_dim, hidden_dim))
        self.classifier = nn.Linear(hidden_dim, out_dim)

    def forward(self, adj, features, sample_sizes):
        h = features
        for i, s_size in enumerate(sample_sizes):
            neighbors = self.sample_neighbors(adj, s_size)
            neighbor_feats = torch.index_select(h, 0, neighbors.view(-1))
            neighbor_feats = neighbor_feats.view(adj.size(0), s_size, -1)
            self_feat = h
            h = self.layers[i](self_feat, neighbor_feats)
            h = F.normalize(h, p=2, dim=-1)
        return self.classifier(h)

2. Training

import torch.optim as optim

model = GraphSAGE(in_dim=1433, hidden_dim=128, out_dim=7, num_layers=2)
optimizer = optim.Adam(model.parameters(), lr=1e-2, weight_decay=5e-4)
sample_sizes = [25, 10]

for epoch in range(200):
    model.train()
    out = model(adj, features, sample_sizes)
    loss = F.cross_entropy(out[mask_train], labels[mask_train])
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 50 == 0:
        model.eval()
        with torch.no_grad():
            out = model(adj, features, sample_sizes)
            test_acc = (out[mask_test].argmax(1) == labels[mask_test]).float().mean()
        print(f'Epoch {epoch} | Loss: {loss:.4f} | Test acc: {test_acc:.3f}')

Hyperparameters

Hyperparameter Typical Value Description
num_layers 2 Number of aggregation layers (K=2 is sufficient for most tasks)
sample_sizes [25, 10] Number of neighbors sampled per layer (S_1=25, S_2=10)
aggregator mean mean/pooling/lstm (mean is the most common and effective)
hidden_dim 128-256 Hidden latent space dimensions per layer
lr 1e-2 Adam learning rate
dropout 0.5 Regularization between layers

Advantages

  1. Inductive: Generates embeddings for never-before-seen nodes, unlike transductive methods like DeepWalk or node2vec which require retraining when the graph changes.
  2. Scalable: Neighborhood sampling controls computational complexity for very large graphs with millions of nodes.
  3. Flexible: Different aggregators (mean, LSTM, pooling) for different needs. The mean aggregator is fast, the LSTM captures complex patterns.
  4. Rich features: Can use any type of node features (text, image, attributes) unlike methods based solely on graph structure.
  5. Easy transfer: A model trained on one graph can be transferred to another graph of the same feature type.

Limitations

  1. Loss of global structural information: Sampling reduces the neighborhood view, losing distant relationships and global structural patterns.
  2. Sensitive hyperparameters: sample_sizes strongly influences performance and memory. A bad choice can destroy performance.

4 Concrete Use Cases

1. Product Recommendation

In a user-product network, GraphSAGE generates embeddings for new products without retraining, enabling real-time addition to the catalog.

2. Social Network Analysis

Community detection with members who continuously join the network. New user embeddings are generated on the fly without recomputing the entire graph.

3. Protein Classification

Classification of new proteins based on their neighboring structure and function, useful in drug discovery.

4. Spam Detection

Fraudulent accounts often have abnormal connection patterns that aggregators easily capture, even for new accounts.


GraphSAGE and Recommendation Networks

GraphSAGE is the algorithm behind Pinterest’s recommendation system, which processes millions of pins and users. Instead of storing one embedding per user, they compute the embedding on the fly by aggregating recent interactions. When a new user signs up, they immediately have an embedding based on their first actions.

SAGE vs GAT vs GCN — Summary Table

| Property | GCN | GraphSAGE | GAT |
|—|—|—|—|—|
| Type | Transductive | Inductive | Inductive |
| Neighbors | All (matrix) | Sampled | Sampled |
| Weights | Normalized degree | Uniform/Learned | Attention |
| Scalability | O(N^2) | O(Nk) | O(Nk*h) |
| New nodes | No | Yes | Yes |

GraphSAGE is the best trade-off between performance and scalability for massive graphs with dynamic nodes. It is the most widely deployed algorithm in the industry today.

In-Depth Analysis of Mean-Pooling vs LSTM-Pooling vs GCN-Pooling Aggregation

Mean Pooling

Mean aggregation is the simplest and fastest. It takes the element-wise average of neighbor embeddings and concatenates them with the target node’s embedding. This approach does not account for the order of neighbors or their relative importance. Despite its simplicity, it works remarkably well on many benchmarks and remains the recommended default choice.

LSTM Pooling

LSTM pooling uses sequential LSTM networks to process neighbors one by one in a random order. The final hidden state of the LSTM serves as the aggregation. This method is more expressive because it captures sequential interactions between neighbors. However, the fact that the order is random limits the LSTM’s advantage over simple mean pooling. In practice, the performance gain is marginal for a significantly higher computational cost.

GCN Pooling

GCN pooling uses a degree-normalized weighted average. This is a special case of GraphSAGE aggregation where the weights are fixed by the graph structure rather than learned. GraphSAGE generalizes this approach by allowing learned aggregation functions.

Benchmark on Reference Datasets

On the Reddit dataset (230K nodes, 114M edges), GraphSAGE achieves a micro F1 score of 0.954 for community classification, comparable to the best models of its time. On PPI (56K nodes, 818K edges), GraphSAGE achieves micro F1 of 0.6120 compared to 0.504 for linear methods. These results demonstrate the superiority of the neighborhood aggregation approach on biological and social graphs.

GraphSAGE’s scalability is impressive: on a single GPU, training on the full Reddit dataset takes about 25 minutes. GCN requires loading the entire adjacency matrix into memory, which is impossible for graphs of this size. GraphSAGE, through its sampling, enables training on graphs with hundreds of millions of nodes.

See Also


About Salah YAHIAOUI

Salah YAHIAOUI publie sur The Pingouin des tutoriels Python et des décryptages sur l’intelligence artificielle. Les cas pratiques récents précisent leurs données, leurs tests et leurs limites. À propos, méthode éditoriale et contact.

View all posts by Salah YAHIAOUI →