Community detection algorithms
|
This section documents the current Neo4j This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, as Neo4j iterates quickly. This section’s bibliography lists the reference material consulted while preparing these pages. |
Community detection algorithms group nodes into clusters — weakly related by mutual reachability, densely
interconnected, or both — without any label telling the algorithm where one group ends and the next begins.
The Graph Data Science (GDS) library ships each of these as a graph algorithm with the same three execution
modes (stream, write, mutate); the examples below use stream to return results without persisting
anything back to the graph.
Weakly Connected Components (WCC)
WCC treats every relationship as undirected and assigns every node reachable from every other node — in either direction — the same component id. It is the quickest "how many disconnected pieces does this graph have" check: run it before anything else, because a component boundary caps what any other algorithm below can find inside it — Louvain and Leiden can only ever split a component further, never merge across one.
CALL gds.wcc.stream('graphProjection')
YIELD nodeId, componentId
RETURN gds.util.asNode(nodeId).name AS name, componentId
ORDER BY componentId;
Strongly Connected Components (SCC)
SCC respects relationship direction: two nodes share a component only if each is reachable from the other by following relationships forward. It is best suited for finding cycles and mutual-dependency clusters in a directed graph — circular payment chains, mutual-follow clusters, or cyclic dependencies between services — that WCC’s undirected view would hide inside one large, unhelpful component.
CALL gds.scc.stream('graphProjection')
YIELD nodeId, componentId
RETURN gds.util.asNode(nodeId).name AS name, componentId
ORDER BY componentId;
Triangle Count and the Local Clustering Coefficient
Triangle Count counts, per node, how many closed triples of mutually connected neighbors it takes part in — best suited as a cheap, local signal of how tightly-knit a node’s neighborhood is, and as a building block the algorithms below rely on internally. The Local Clustering Coefficient normalizes that count against how many triangles the node’s neighborhood could form, giving a 0-1 score comparable across nodes of very different degree.
CALL gds.triangleCount.stream('graphProjection')
YIELD nodeId, triangleCount
RETURN gds.util.asNode(nodeId).name AS name, triangleCount
ORDER BY triangleCount DESC;
CALL gds.localClusteringCoefficient.stream('graphProjection')
YIELD nodeId, localClusteringCoefficient
RETURN gds.util.asNode(nodeId).name AS name, localClusteringCoefficient
ORDER BY localClusteringCoefficient DESC;
Louvain
Louvain repeatedly merges nodes into communities that locally maximize modularity, then collapses each community into a single node and repeats on that coarser graph. It is best suited for a fast, good-enough multi-level community structure on large graphs, and it exposes the intermediate levels so a caller can pick a coarser or finer partition without rerunning the algorithm.
CALL gds.louvain.stream('graphProjection')
YIELD nodeId, communityId
RETURN gds.util.asNode(nodeId).name AS name, communityId
ORDER BY communityId;
See Louvain.
Label Propagation
Label Propagation starts every node with its own unique label and repeatedly relabels each node to whatever label a plurality of its neighbors hold, until labels stop changing. It is best suited for near-linear-time community detection on very large graphs where Louvain’s or Leiden’s iterative refinement would be too slow, at the cost of less stable, sometimes trivially large communities.
CALL gds.labelPropagation.stream('graphProjection')
YIELD nodeId, communityId
RETURN gds.util.asNode(nodeId).name AS name, communityId
ORDER BY communityId;
See Label Propagation.
Leiden
Leiden refines Louvain’s merge step with an additional partition-refinement phase that guarantees every community it produces stays internally connected. It is Louvain’s more-stable successor: it fixes Louvain’s known failure mode of occasionally producing internally-disconnected communities, and it is the modern default choice whenever both are available.
CALL gds.leiden.stream('graphProjection')
YIELD nodeId, communityId
RETURN gds.util.asNode(nodeId).name AS name, communityId
ORDER BY communityId;
See Leiden.
Choosing among them
| Algorithm | Best suited for |
|---|---|
WCC |
A quick "how many disconnected pieces does this graph have" check, and a required first pass before any of the algorithms below. |
SCC |
Cycles and mutual-dependency clusters in a directed graph. |
Triangle Count |
A cheap local density signal per node, and an internal building block for other algorithms. |
Local Clustering Coefficient |
A degree-normalized 0-1 density score, comparable across nodes. |
Louvain |
Fast, good, multi-level community structure on large graphs, with inspectable intermediate levels. |
Label Propagation |
Near-linear-time community detection at very large scale, when some instability is acceptable. |
Leiden |
Louvain’s more-stable successor — guaranteed internally-connected communities; the modern default. |
Where this fits in a larger pipeline
Community detection is rarely the end goal by itself — it is usually a filtering or feature-generation step inside a larger analytical or investigative pipeline. See Use Cases and Algorithms in Practice for a worked fraud-ring detection example that layers WCC, Louvain and Betweenness Centrality: WCC first isolates the connected pieces worth examining, Louvain finds dense communities within each piece, and Betweenness Centrality then ranks the nodes that bridge those communities as the accounts most likely to be laundering funds between rings.
For the full algorithm catalog, including centrality, similarity and path-finding algorithms not covered here, see GDS Algorithms — its community-detection section covers every algorithm on this page plus a few more specialized variants (Modularity Optimization, Approximate Maximum k-cut, Speaker-Listener Label Propagation) not detailed here.