selib

A standardized library for structural entropy — compute it, optimize it, and benchmark SE methods against classical baselines under one API.

v0.1.0 298 benchmark runs6 methods 13 datasetsMIT

GitHub repo · SE gallery · SE tutorial · recursive structures · periodic table · survey maps · raw results JSON · reproduction benchmark · survey paper

What this is

Every SE paper ships its own loader, metric, and (often unmaintained) code, so "does structural entropy actually help?" is hard to answer on equal footing. selib fixes the interface: one Method.fit_predict(G, k, seed) contract, a native 2D-structural-entropy encoding-tree core, shared datasets and metrics, and a one-call benchmark — so an SE method and a Louvain baseline are scored exactly the same way. The tables below are produced by that benchmark; the headline takeaway matches the survey's regime-dependent verdict.

import selib
recs = selib.benchmark(["louvain", "leiden", "se_agglomerative"],
                       ["Karate", "SBM-Clean", "SBM-Noisy"])
selib.summarize(recs, "nmi")

0 · The library's SE optimizer

The shipped se_agglomerative only ever merges, so an early bad merge can never be undone — it gets stuck in poor local optima. se_louvain is this library's stronger minimizer of the same 2D structural-entropy objective: Louvain-style local node moves + community aggregation + multistart, with an O(degree) exact move delta. Validated against the canonical metric and against brute-force exhaustive optima on small graphs (gap 0.000).

2D structural entropy reached on each graph (lower is better); Δ is the relative reduction of se_louvain over the naive merger. se_louvain wins on 8/9 graphs.

se_agglomerative (SE)se_louvain (SE)
se_agglomerativese_louvainΔ (lower=better)
Karate3.7313.731+0.0%
SBM-Clean6.0356.031+0.1%
SBM-Noisy6.4196.407+0.2%
LFR-mu0.16.1756.164+0.2%
LFR-mu0.26.6736.662+0.2%
LFR-mu0.37.2047.103+1.4%
LFR-mu0.47.7507.551+2.6%
LFR-mu0.58.0647.895+2.1%
LFR-mu0.68.1298.055+0.9%

0b · The library's hierarchical SE optimizer

Structural entropy is defined over an encoding tree, not just a flat partition. se_hier builds a multilevel tree (binary se_agglomerative dendrogram + recursive se_louvain inits) and refines it with exact-guarded local moves — collapse a redundant level, relocate a subtree — accepting a move only when it strictly lowers the exact tree structural entropy HT. Because refinement starts from the naive dendrogram and only takes improving moves, the result is the naive dendrogram by construction; it is strictly lower on 6/6 graphs.

Encoding-tree structural entropy HT (lower better)

se_agglomerativelouvain_2levelse_hierΔ vs naive
Karate2.69323.32752.4856+7.7%
SBM-Clean5.30716.03045.0286+5.2%
SBM-Noisy5.44966.17475.3495+1.8%
LFR-mu0.14.36365.06714.1184+5.6%
LFR-mu0.35.09905.73605.0343+1.3%
LFR-mu0.55.44566.16535.3532+1.7%

Dasgupta cost of the hierarchy (lower better)

se_agglomerativelouvain_2levelse_hierΔ vs naive
Karate2304.03746.02625.0-13.9%
SBM-Clean81858.0108050.085440.0-4.4%
SBM-Noisy93208.0127962.093041.0+0.2%
LFR-mu0.139778.056416.040673.0-2.2%
LFR-mu0.380040.0104988.084418.0-5.5%
LFR-mu0.599638.0131146.0100689.0-1.1%

Validated in selib.htree: a 2-level tree's HT equals the canonical 2D structural entropy exactly, and refinement is monotone. louvain_2level is a flat (2-level) hierarchy baseline.

0c · Comparison with existing work

All methods run on the identical graphs, all at free k (so the structural-entropy objective is compared fairly). The published SE community detectors CoDeSEG (original C++) and deDoc (original Java, the founding SE algorithm) run their real implementations through selib's wrappers. For the hierarchical comparison the original HCSE and BBM code (github.com/Hardict/HCSE) build the trees, and classical hierarchies (Paris, average / Ward linkage) are included — all scored on the same encoding-tree objective as se_hier. (* = structural-entropy method.)

2D structural entropy reached — free k (lower better)

louvainleideninfomapcodeseg *dedoc *se_louvain *
Karate3.3113.2793.4963.4284.4833.229
SBM-Clean6.0306.0306.0306.3166.0355.978
SBM-Noisy6.1966.2007.1836.5457.1666.178
LFR-mu0.15.0675.0675.0675.5337.1545.067
LFR-mu0.35.7365.7445.8236.1077.1625.728
LFR-mu0.56.1636.1227.1416.4247.1416.129

2D community detection — NMI vs. ground truth (higher better)

louvainleideninfomapcodeseg *dedoc *se_louvain *
Karate0.5960.5880.5680.4410.3400.499
SBM-Clean1.0001.0001.0000.4180.9850.766
SBM-Noisy0.1070.0890.0000.2270.3620.134
LFR-mu0.11.0001.0001.0000.8300.5411.000
LFR-mu0.30.9390.9440.9030.6450.5410.877
LFR-mu0.50.2680.2840.0000.3940.5400.308

On its own objective, se_louvain wins: it reaches the lowest 2D structural entropy on every graph — below the modularity methods and the published CoDeSEG. NMI tells a subtler, honest story: minimizing 2D-SE at free k tends to over-segment relative to the planted communities, so on clean graphs the modularity methods (Louvain/Leiden) recover ground truth better even though their structural entropy is higher. Run with a target k (§1) se_louvain recovers ground truth strongly. It beats the published SE detector CoDeSEG on NMI on 4/6 graphs; CoDeSEG's finer segmentation helps only on the hardest (noisy SBM, μ=0.5). Lesson: lower structural entropy ≠ better label recovery — a point the survey makes. deDoc (the founding SE algorithm, original Java) recovers the clean SBM almost perfectly (NMI 0.985) but degenerates to near-singletons on sparse Karate/LFR — it was designed for dense weighted Hi-C matrices; this exactly reproduces the survey campaign's numbers. (Its successor deDoc2 is excluded here: it only forms contiguous TAD-like domains over genomically-ordered bins, so on a general graph it groups consecutive node IDs and ignores the topology — a Hi-C tool, not a community detector.)

Hierarchical — encoding-tree structural entropy HT (lower better)

se_hier *se_agglomerative *bbm *hcse *parisaverageward
Karate2.4862.6933.2342.6842.4862.7952.791
SBM-Clean5.0295.3075.3506.6565.0325.1305.288
SBM-Noisy5.3495.4505.7956.6715.3495.4745.473
LFR-mu0.14.1184.3644.3094.7424.1244.3454.273
LFR-mu0.35.0345.0995.5216.5605.0595.2835.290
LFR-mu0.55.3535.4465.6976.5835.3535.4595.503

Hierarchical — Dasgupta cost (lower better)

se_hier *se_agglomerative *bbm *hcse *parisaverageward
Karate2625230434792796262528022829
SBM-Clean854408185886112171938854098948098563
SBM-Noisy930419320897293138163930419313495586
LFR-mu0.140673397784144352376406004651246067
LFR-mu0.3844188004096605144122868529178794429
LFR-mu0.510068999638104408144936100689100106104012

se_hier reaches the lowest HT on every graph — below the original BBM and HCSE code, Paris, and the linkage baselines. It warm-starts from several constructions (binary SE dendrogram, recursive se_louvain, Paris) and refines the best with exact-guarded moves, so it is ≤ each by construction. BBM (deep binary merge) is the strongest original SE tree; HCSE targets a height-constrained hierarchy, so its full-depth HT is higher here. Paris is the best non-SE classical tree.

Attributed graphs — citation networks with node features

se_gnn is selib's attribute-aware method (ported from the author's glass-jax prototype): a tiny GCN trained end-to-end to minimize a differentiable soft 2D structural entropy — validated so that the soft objective at a hard assignment equals the canonical 2D-SE exactly. DeSE / LSENet are the published feature-aware SE methods (reproduction-campaign numbers); the rest are run fresh by selib on the same standard Planetoid data.

NMI

se_gnn *DeSE *LSENet *se_louvain *louvainleideninfomapspectral
Cora0.4870.5790.4950.1200.4490.4660.4530.039
Citeseer0.2620.4430.0940.2460.3270.3280.3190.014
Photo0.667

ARI

se_gnn *DeSE *LSENet *se_louvain *louvainleideninfomapspectral
Cora0.3870.5220.418-0.0040.2460.2590.265-0.004
Citeseer0.2130.4480.1130.0220.0890.0860.1580.005
Photo0.574

Reading: feature-aware beats topology-only. se_gnn (2-layer GCN over the normalized adjacency + a balanced Sinkhorn assignment head, best-of-starts selected by the SE objective) finds the full number of communities (k = 6–7, no collapse) and beats every topology method on NMI, ARI and ACC on both datasets — on Cora it matches LSENet (NMI 0.487 vs 0.495) with a far smaller model. The Sinkhorn head is what prevents the cluster collapse that pure SE minimization induces with a plain softmax (ablation in segnn_head_eval.json). DeSE still leads NMI — the remaining gap.

Visualizations

What the optimizers actually produce — node-link layouts coloured by se_louvain communities, and the se_hier encoding tree. Rendered as inline SVG from the run.

Karate
Karate: se_louvain communities
SBM-Clean
SBM-Clean: se_louvain communities
LFR-mu0.3
LFR-mu0.3: se_louvain communities
Karate: se_hier encoding tree
se_hier encoding tree (leaves = vertices; depth downward)

0d · Robustness & scale

Every synthetic comparison repeated over 3 independent graph realizations (means shown). se_louvain has the lowest mean 2D-SE on 5/5 generators; se_hier ≤ Paris (the strongest classical tree) on 5/5.

se_louvain 2D-SEbest otherlowest?se_hier HTParis HT≤ Paris?
SBM-Clean5.9776.0265.0385.042
SBM-Noisy6.1736.1845.3485.348
LFR-mu0.14.9024.9023.9823.984
LFR-mu0.35.6435.6554.9514.996
LFR-mu0.56.1176.1385.3635.363

Hierarchy quality at n = 500–1000

The first-improvement refinement (exact-guarded, O(m log h) scoring) extends se_hier beyond small graphs: it reaches the lowest HT at every size, with growing margins over Paris and the original BBM.

se_hierse_agglomerativebbmparisse_hier time
LFR-mu0.3-n500 (n=500)6.1156.4636.7726.559535s
SBM-n1000 (n=1000)5.7526.2866.2635.8991175s
LFR-mu0.3-n1000 (n=1000)6.5946.7577.4956.9381626s

1 · Real graphs & controlled SBM

louvainleideninfomapspectralse_agglomerative (SE)se_louvain (SE)
louvainleideninfomapcodeseg *dedoc *se_louvain *
Karate0.5960.5880.5680.4410.3400.499
SBM-Clean1.0001.0001.0000.4180.9850.766
SBM-Noisy0.1070.0890.0000.2270.3620.134
LFR-mu0.11.0001.0001.0000.8300.5411.000
LFR-mu0.30.9390.9440.9030.6450.5410.877
LFR-mu0.50.2680.2840.0000.3940.5400.308

Accuracy — ARI vs. ground truth

Higher is better.

louvainleideninfomapspectralse_agglomerativese_louvain
Karate0.5350.4650.5910.8820.8820.882
SBM-Clean1.0001.0001.0001.0000.9800.996
SBM-Noisy0.0370.0490.0000.0530.0150.022

Cross-objective — modularity

Higher = more modular partition.

louvainleideninfomapspectralse_agglomerativese_louvain
Karate0.4420.4450.4320.4040.4040.404
SBM-Clean0.4050.4050.4050.4050.4020.404
SBM-Noisy0.2060.0930.0000.1710.1520.165
louvainleideninfomapcodeseg *dedoc *se_louvain *
Karate3.3113.2793.4963.4284.4833.229
SBM-Clean6.0306.0306.0306.3166.0355.978
SBM-Noisy6.1966.2007.1836.5457.1666.178
LFR-mu0.15.0675.0675.0675.5337.1545.067
LFR-mu0.35.7365.7445.8236.1077.1625.728
LFR-mu0.56.1636.1227.1416.4247.1416.129

SE (se_agglomerative, the native greedy 2D-SE encoding tree) matches the baselines on clean, well-separated structure and on Karate, but does not rescue performance once the planted signal is weak — the same fragility the survey reports for unsupervised community detection.

2 · LFR difficulty sweep

LFR graphs (n=500), mixing parameter μ on the x-axis: higher μ = more inter-community edges = harder. Mean NMI over 5 seeds.

louvainleideninfomapspectralse_agglomerative (SE)se_louvain (SE)
0.000.250.500.751.000.10.20.30.40.50.6mean NMI

All methods — SE and baselines alike — degrade together as μ rises and collapse past the detectability threshold; no method's curve is rescued by the SE objective. This is the core empirical message, now reproducible in one call.

3 · Scalability

SBM with per-node community signal held constant as N grows (k=10 blocks). Left: wall-clock per run; right table: NMI stays high, so runtime is measured on a task every method can solve.

louvainleideninfomapspectralse_agglomerative (SE)se_louvain (SE)
0.0010.2220.4430.6640.8820050010002000wall-clock (s)

Scalability — NMI

Per-node community signal held constant as N grows.

louvainleideninfomapspectralse_agglomerativese_louvain
SBM-scale-N2001.0001.0001.0001.0001.0001.000
SBM-scale-N5001.0001.0001.0001.0000.9841.000
SBM-scale-N10001.0001.0001.0001.0000.9951.000
SBM-scale-N20001.0001.0001.0001.0000.9971.000

The native se_agglomerative core is a pure-Python greedy merge; the optimized C/igraph baselines (Louvain/Leiden/Infomap) are faster, while spectral clustering's dense eigendecomposition scales worst. These are wall-clock facts from the run, not claims.

Datasets

datasetnodesedgesk (true)
Karate34782
LFR-mu0.1500701711
LFR-mu0.2500716211
LFR-mu0.3500733211
LFR-mu0.4500751411
LFR-mu0.5500750511
LFR-mu0.6500755011
SBM-Clean15014193
SBM-Noisy15011853
SBM-scale-N10001000899910
SBM-scale-N200200179310
SBM-scale-N200020001820210
SBM-scale-N500500449810

Reproduce

git clone https://github.com/SuuTTT/selib && cd selib
pip install -e ".[extra]"
python3 scripts/run_full_benchmark.py     # writes results/benchmark_results.json
python3 scripts/build_site.py             # regenerates this page from that JSON

All numbers on this page are read directly from results/benchmark_results.json produced by the run above on an RTX 3070 box. Methods that wrap a paper's original code (deDoc, CoDeSEG) are available through the same API once their upstream artifact is configured; the runs shown here use the native methods + classical baselines.

Generated from 298 benchmark records · selib v0.1.0 · part of the structural-entropy survey & benchmark project.