Skip to main content

MODERN

MOdule DEtection and Refinement in signed Networks (MODERN) detects community structure in signed networks — networks with both positive (attractive) and negative (repulsive) edges. It extends classical community detection algorithms (Louvain, Leiden) to leverage negative edge information, which is critical for accurate module detection in biological networks such as gene co-expression networks.

Why signed networks?

Standard community detection methods use only positive edges and ignore negative correlations between genes. When inter-community positive edges are abundant (e.g., in correlation-based networks), unsigned methods fail to identify the correct community structure because they cannot distinguish "noise" positive edges from true intra-community edges.

Signed methods use negative edges as repulsive forces to push nodes apart, recovering the correct community structure even when the positive graph alone is ambiguous.

Signed adjacency matrix sorted by detected communities. As inter-community positive edges increase (top to bottom), unsigned modularity collapses (ARI=0.07) while signed methods maintain near-perfect recovery (ARI>0.93).

Methods

MODERN provides three community detection methods for signed networks:

Method Algorithm Objective Best for
louvain LouvainSigned α·Q⁺ − (1−α)·Q⁻ Compatibility with existing Louvain workflows
leiden-mod-alpha LeidenSigned (modularity) α·Q⁺ − (1−α)·Q⁻ General signed networks
leiden-cpm-single LeidenSigned (CPM) Σ(w_ij − γ) on signed graph Correlation-based networks (co-expression)

When to use CPM over modularity: Modularity's null model assumes a configuration-model random graph. In correlation-based networks (e.g., gene co-expression), the positive graph is inherently dense, distorting the null model. CPM uses an absolute density threshold (γ) instead and is not affected by this issue.

Installation

pip install modernsn

Dependencies

  • Python ≥ 3.9
  • numpy
  • igraph (python-igraph)
  • leidenalg
  • networkx
  • matplotlib (for plotting outputs)
  • scipy (for MAT format support)

Quick start

# Basic run with Leiden signed modularity
modern --pos positive_edges.tsv --neg negative_edges.tsv \
  --method leiden-mod-alpha --alpha 0.6 --resolution 1.0 \
  --out-prefix results/my_analysis

# Leiden signed CPM (recommended for co-expression networks)
modern --pos positive_edges.tsv --neg negative_edges.tsv \
  --method leiden-cpm-single --gamma 0.05 --lambda-neg 1.0 \
  --out-prefix results/my_analysis

# Louvain signed
modern --pos positive_edges.tsv --neg negative_edges.tsv \
  --method louvain --alpha 0.6 --resolution 1.0 \
  --out-prefix results/my_analysis

# Multi-seed negative-edge leverage screen
modern --pos positive_edges.tsv --neg negative_edges.tsv \
  --method leiden-mod-alpha --negative-edge-leverage \
  --leverage-seeds 1 2 3 10 42 \
  --out-prefix results/my_analysis

# Signed-network diagnostic and analysis recommendations
modern --pos positive_edges.tsv --neg negative_edges.tsv \
  --method leiden-mod-alpha --check-signed-network \
  --leverage-seeds 1 2 3 10 42 \
  --out-prefix results/my_analysis

Input formats

TSV (default)

Tab-separated file with five columns (no header):

gene_id1    gene_id2    gene_name1    gene_name2    weight
ENSG00001   ENSG00002   GeneA         GeneB         15.3
ENSG00001   ENSG00003   GeneA         GeneC         12.1

Provide separate files for positive and negative edges via --pos and --neg. Use --thre-pos and --thre-neg to filter edges by weight.

MAT (MATLAB sparse matrix)

modern --format mat --mat data/network.mat \
  --pos-key pos --neg-key neg \
  --method leiden-mod-alpha --out-prefix results/mat_run

The MAT file should contain two sparse matrices (positive and negative adjacency).

Output files

When --out-prefix is specified, MODERN generates the following outputs:

File Description
<prefix>_partition.tsv Community assignment for each gene (gene_id, gene_name, community)
<prefix>_summary.txt Parameters, graph statistics, community size distribution, entropy
<prefix>_communities.gmt GMT format for direct use with GSEA, Enrichr, clusterProfiler
<prefix>_community_sizes.pdf Rank-size plot and histogram of community sizes
<prefix>_inter_community.pdf Heatmap of inter-community edge density (positive / negative / signed)
<prefix>_module_<id>.pdf Subnetwork visualization for top modules (positive=red, negative=blue)

With --negative-edge-leverage, MODERN instead writes one row per seed to <prefix>_negative_edge_leverage.tsv and a multi-seed summary to <prefix>_negative_edge_leverage_summary.txt.

With --check-signed-network, MODERN reports network size, low- and high-resolution partition summaries, metanode enrichment, multi-seed negative-edge leverage, and analysis recommendations. The full result is saved to <prefix>_signed_network_check.json.

Negative-edge leverage

Negative-edge leverage asks whether positive-only reintegration would merge module boundaries supported by negative edges. MODERN first generates a high-resolution positive-only Leiden partition, then performs reintegration without applying the negative-edge veto. The score is

(negative edges newly placed within modules) / (negative edges evaluated)

The defaults reproduce the manuscript screen: resolution 4, positive-coupling robust-z threshold 1, minimum module size 10, and seeds 1, 2, 3, 10, and 42. The empirical candidate threshold of 0.02 is reported as a screen rather than a general significance cutoff.

Disabling outputs

--no-plot     # Skip all PDF plots
--no-gmt      # Skip GMT output
--quiet       # Suppress progress messages

Controlling module plots

--top-modules 10             # Number of top modules to plot (default: 10)
--max-nodes-per-module 200   # Max nodes per module plot (default: 200)

Parameters

Method-specific parameters

Modularity-based methods (louvain, leiden-mod-alpha):

Parameter Description Default
--alpha Balance between positive and negative modularity (0–1). Higher α emphasizes positive edges. 0.5
--resolution Resolution parameter. Higher values produce more, smaller communities. 1.0

CPM method (leiden-cpm-single):

Parameter Description Default
--gamma CPM resolution. Minimum edge density within communities. 0.5
--lambda-neg Weight multiplier for negative edges. Controls how strongly negative edges repel. 0.0
--neg-weight-mode How to transform negative weights: absolute (−λ·|w|) or signed (λ·w). absolute

Common parameters

Parameter Description Default
--seed Random seed for reproducibility. None
--out-prefix Output file prefix. If omitted, only prints summary to stdout. None

Python API

MODERN can also be used as a Python library:

import modernsn.network_module as nr
import modernsn.LeidenSigned as les

# Load graphs
G_pos = nr.load_graph_from_TSV_igraph("positive.tsv", threshold=10)
G_neg = nr.load_graph_from_TSV_igraph("negative.tsv", threshold=5)

# Leiden signed modularity
partition = les.find_partition_signed_modularity_alpha(
    G_pos, G_neg, alpha=0.6, resolution=1.0, seed=42
)

# Leiden signed CPM (single signed graph)
G_signed = nr.load_signed_graph_from_two_TSV_igraph(
    "positive.tsv", "negative.tsv",
    pos_threshold=10, neg_threshold=5, lambda_neg=1.0
)
partition = les.find_partition_signed_CPM_single_graph(
    G_signed, gamma=0.05, seed=42
)

# Inspect results
print(partition.membership)
nr.display_communities_by_name(G_pos, partition)
nr.count_nodes_in_communities(partition)

# Multi-seed negative-edge leverage
leverage = nr.calculate_negative_edge_leverage_multiseed(
    G_pos, G_neg, seeds=[1, 2, 3, 10, 42]
)
print(leverage["negative_edge_leverage_median"])
print(leverage["classification"])

# Combined signed-network diagnostic
diagnostic = nr.check_signed_network(G_pos, G_neg)
print(diagnostic["network"])
print(diagnostic["recommendations"])

Visualization

# Visualize a specific module (positive=red, negative=blue)
nr.visualize_module_signed(G_pos, G_neg, partition, community_id=0)

# Visualize the module containing a specific gene
nr.visualize_module_of_gene_signed(G_pos, G_neg, partition, "TP53")

# Top-degree nodes within a module
nr.visualize_module_of_gene_top_degree_nodes_signed(
    G_pos, G_neg, partition, "TP53", top_n=30
)

Benchmarking

MODERN includes a simulation framework for evaluating community detection methods on signed networks.

# Quick test (no modernsn package required)
python sim3_benchmark.py test

# Full benchmark with all methods and parameter grids
python sim3_benchmark.py run sim3_results/

# Generate example correlation matrix visualizations
python sim3_benchmark.py plot sim3_results/

Simulation types

Type Model Tests
Type A Correlation-based co-expression Modularity null model distortion on dense positive graphs
Type B Planted partition (stochastic block model) Control — balanced positive/negative structure
Type C scRNA-seq exclusive expression Multipartite negative graph where "enemy of enemy ≠ friend"

Example visualizations

# Generate concrete examples showing signed vs unsigned differences
python sim3_examples.py sim3_examples/

This produces network graphs and adjacency matrix heatmaps at three difficulty levels, clearly demonstrating when signed methods outperform unsigned methods.

How it works

Signed modularity (multiplex optimization)

The positive and negative graphs are treated as two layers of a multiplex network. The objective function is:

Q_signed = α · Q_modularity(G⁺) − (1 − α) · Q_modularity(G⁻)

This is optimized using leidenalg.optimise_partition_multiplex, which simultaneously considers both layers with different weights.

Signed CPM (single graph)

Positive and negative edges are combined into a single graph with signed weights:

w_signed(i,j) = w_pos(i,j) − λ_neg · w_neg(i,j)

Standard CPM is then applied, where the objective function naturally penalizes negative edges within the same community:

H_CPM = Σ_{i,j in same community} (w_signed(i,j) − γ)

Choosing a method

Is your network correlation-based (co-expression, etc.)?
├── Yes → Use leiden-cpm-single
│         Start with --gamma 0.05 --lambda-neg 1.0
│         Increase gamma for smaller communities
│
└── No (e.g., social network, citation network)
    ├── Need reproducibility/stability? → Use leiden-mod-alpha
    │   Start with --alpha 0.6 --resolution 1.0
    │
    └── Compatibility with existing Louvain pipeline? → Use louvain
        Start with --alpha 0.6 --resolution 1.0

Citation

If you use MODERN in your research, please cite:

[Citation information to be added]

Release files for modernsn 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for modernsn 0.1.0
File Size Uploaded
modernsn-0.1.0.tar.gz 66.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for modernsn 0.1.0
File Interpreter ABI Platform
modernsn-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 129.1 kB

Release files / modernsn-0.1.0.tar.gz

Download URL modernsn-0.1.0.tar.gz
Size 66.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d7f02977227034eb63c0ae680db56a5e46e827a267194652b2e19d1cafdc9c1d
BLAKE2b-256 checksum
How to use checksums
eae16deb0a7730fb0a79a14fe588925be8c28e1f2335a4f60ddbbe0b67bf48e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.13

Release files / modernsn-0.1.0-py3-none-any.whl

Download URL modernsn-0.1.0-py3-none-any.whl
Size 62.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c68759f7688ff6a99e596a0511e93e5c15df8f66245eb014a6c710d0fdd7e7cd
BLAKE2b-256 checksum
How to use checksums
848e9a2747d19edf1996a5bfbb7c1c1802e7fedb1416d0ee5528d574f2581844
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.13

Release history Release notifications | RSS feed

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page