Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

60 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

networkx_backbone

Backbone extraction algorithms for complex networks, built on NetworkX.

This library provides 87 functions across 10 modules for extracting backbone structures from weighted, unweighted, and higher-order (hypergraph) networks.

Full documentation: https://www.brianckeegan.com/networkx_backbone/

Installation

pip install networkx-backbone

For full functionality (required for statistical tests, bipartite methods, and some structural methods):

pip install networkx-backbone[full]

Or install from source:

git clone https://github.com/brianckeegan/networkx_backbone.git
cd networkx_backbone
pip install -e ".[full]"

Modules

Module Description Key Functions
statistical Hypothesis-testing methods disparity_filter, noise_corrected_filter, marginal_likelihood_filter, ecm_filter, lans_filter, multiple_linkage_analysis
structural Topology-based methods global_threshold_filter, strongest_n_ties, global_sparsification, primary_linkage_analysis, edge_betweenness_filter, node_degree_filter, high_salience_skeleton, metric_backbone, ultrametric_backbone, doubly_stochastic_filter, h_backbone, modularity_backbone, planar_maximally_filtered_graph, maximum_spanning_tree_backbone
proximity Neighborhood-similarity scoring jaccard_backbone, dice_backbone, cosine_backbone, hub_promoted_index, hub_depressed_index, adamic_adar_index, resource_allocation_index, local_path_index, and more
hybrid Combined approaches glab_filter
bipartite Bipartite projection backbones simple_projection, hyper_projection, probs_projection, ycn_projection, sdsm, fdsm, fixedfill, fixedrow, fixedcol, backbone
hypergraph Higher-order (hypergraph) backbones mdl_hypergraph_backbone, hypergraph_compression_ratio, intersection_graph, maximal_hyperedges, order_filter, s_components, statistically_validated_hypergraph, statistically_validated_cores
unweighted Sparsification for unweighted graphs sparsify, lspar, local_degree
filters Post-hoc filtering utilities multigraph_to_weighted, threshold_filter, fraction_filter, boolean_filter, consensus_backbone
measures Evaluation and comparison node_fraction, edge_fraction, weight_fraction, reachability, ks_degree, ks_weight, compare_backbones
visualization Graph comparison plotting graph_difference, compare_graphs, save_graph_comparison

NetBone Core Coverage

Core method families used in netbone (Yassin et al., 2023) are represented here, including:

  • Statistical: disparity_filter, marginal_likelihood_filter, ecm_filter, noise_corrected_filter, lans_filter, multiple_linkage_analysis
  • Structural: global_threshold_filter, global_sparsification, primary_linkage_analysis, edge_betweenness_filter, high_salience_skeleton, doubly_stochastic_filter, maximum_spanning_tree_backbone
  • Hybrid: glab_filter

Every backbone model in Neal's Backbone 3.0 R package is also covered (disparity, mlf, lans, sdsm, fdsm, fixedfill/fixedrow/fixedcol, bicm, fastball, and the backbone_from_* wrappers), including its hypergraph-projection input via hypergraph_to_bipartite, plus its cross-cutting features: multiple-testing correction (adjust_pvalues, threshold_filter(mtc=...)), signed backbones (signed=True adds a sign edge attribute), and SDSM-EC edge constraints (sdsm(prohibited=, required=)). See docs/design/backbone-3.0-coverage.md for the full coverage analysis.

Quick Start

import networkx as nx
import networkx_backbone as nb

# Create a weighted graph
G = nx.les_miserables_graph()

# 1) Score edges
scored = nb.disparity_filter(G)

# 2) Filter edges
backbone = nb.threshold_filter(scored, "disparity_pvalue", 0.05)

# Compare backbone to original
print(f"Edges kept: {nb.edge_fraction(G, backbone):.1%}")
print(f"Nodes kept: {nb.node_fraction(G, backbone):.1%}")

Significance options: multiple-testing correction and signed backbones

# Correct p-values for the number of edges tested (Bonferroni, Holm, BH/FDR, BY)
backbone = nb.threshold_filter(scored, "disparity_pvalue", 0.05, mtc="bh")

# Signed backbone: keep significantly strong (+1) and significantly weak (-1)
# edges under a two-tailed test; read direction from the "sign" attribute
signed = nb.disparity_filter(G, signed=True)
strong = nb.threshold_filter(signed, "disparity_pvalue", 0.05, mtc="holm")
positives = [(u, v) for u, v, d in strong.edges(data=True) if d["sign"] == 1]

Disparity filter visualization

Disparity filter on Les Miserables

Proximity-based scoring

# Score edges by Jaccard similarity of endpoint neighborhoods
scored = nb.jaccard_backbone(G)

# Keep only the top 20% most structurally embedded edges
backbone = nb.fraction_filter(scored, "jaccard", 0.2, ascending=False)

Bipartite backbone

B = nx.davis_southern_women_graph()
women_nodes = [n for n, d in B.nodes(data=True) if d["bipartite"] == 0]
scored = nb.sdsm(B, agent_nodes=women_nodes, projection="hyper")
backbone = nb.threshold_filter(scored, "sdsm_pvalue", 0.05, mode="below")

Projection weights follow the simple/hyper/ProbS/YCN formulations described in Coscia & Neffke (2017).

Hypergraph backbones

Backbone a hypergraph (a collection of arbitrary-size hyperedges) directly:

# Parameter-free MDL backbone -- prunes nested/redundant hyperedges
# (Kirkley, Felippe, Malizia & Battiston, 2026)
H = [(1, 2, 3, 4), (1, 2, 3), (2, 3, 4), (8, 9)]
result = nb.mdl_hypergraph_backbone(H)          # method="auto" runs both greedy
print(result.backbone)            # [frozenset({1, 2, 3, 4}), frozenset({8, 9})]
print(result.compression_ratio)   # inverse compression ratio eta
# method="edge" (fastest single pass) or "node" are also available

# Statistically validated hypergraph (Musciotto, Battiston & Mantegna, 2021)
events = [(1, 2)] * 5 + [(3, 4)] * 100          # repeats = interaction counts
svh = nb.statistically_validated_hypergraph(events, alpha=0.05)

Interoperate with the higher-order ecosystem (all optional, lazily imported), or reuse the bipartite projection backbones via the incidence graph:

B, nodes = nb.hypergraph_to_bipartite(H)        # -> NetworkX bipartite graph
scored = nb.sdsm(B, agent_nodes=nodes)          # projection backbone of a hypergraph

nb.write_hif(H, "graph.hif")                    # HIF interchange (xgi/HNX/HGX/HAT)
edges = nb.from_xgi(xgi_hypergraph)             # xgi / hypernetx / hypergraphx / hat

Comparing multiple methods

backbones = {
    "disparity": nb.threshold_filter(nb.disparity_filter(G), "disparity_pvalue", 0.05),
    "mst": nb.boolean_filter(nb.maximum_spanning_tree_backbone(G), "mst_keep"),
}
results = nb.compare_backbones(G, backbones)

Dependencies

  • Required: networkx >= 3.0
  • Optional: numpy >= 1.23, scipy >= 1.9, matplotlib >= 3.7 (needed for statistical methods, bipartite methods, some structural/proximity methods, visualization helpers, and docs gallery generation)

Testing

pip install -e ".[test]"
pytest

Visualization gallery

Backbone visualizations in the docs are generated with Sphinx Gallery from example scripts under docs/examples/.

Build docs (including the graph comparison gallery and function-linked visualizations):

pip install -e ".[docs]"
sphinx-build -b html docs docs/_build/html

References

Key papers behind the implemented methods:

Other libraries and datasets:

License

BSD 3-Clause License. See LICENSE for details.

About

Implementation of backbone functions and filtering for complex networks

Topics

Resources

Contributing

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages