Skip to main content

Python package for fitting a mean-field fitness-based two-star model (Fit2SM) for undirected binary networks (dcGM and UBCM are also available for comparisons).

Project description

fit2SM

fit2SM is a lightweight research package for reconstructing undirected binary networks from partial information.

In many economic and financial settings, the full adjacency matrix is unavailable, but node-level “fitness proxies” (e.g., aggregate activity, volumes, exposures, total trading amounts) are observable and provide reliable information on heterogeneity. fit2SM uses these proxies together with a small set of global constraints to build a faithful probabilistic reconstruction of the network.

The package currently provides three solvers:

  • dcGM (density-corrected Gravity Model): matches the expected number of links $L$ using strengths as fitness proxies.
  • UBCM (Undirected Binary Configuration Model): matches the expected degrees $k_i$.
  • Fit2SM (Fitness-based Two-Star Model, mean-field): matches $(L, S)$ where $S = \sum_i \binom{k_i}{2}$ is the total number of two-stars (wedges).

Why two-stars? Matching $S$ allows Fit2SM to reproduce the second moment of the degree distribution (and hence its variance), a key ingredient for processes whose behavior depends on both $\langle k \rangle$ and $\langle k^2 \rangle$ (e.g., epidemic thresholds, systemic-risk proxies, spectral indicators). See the accompanying paper for the model definition, motivation, and empirical validation:

  • M. Marzi, F. Giuffrida, D. Garlaschelli, T. Squartini, Reproducing the first and second moment of empirical degree distributions, arXiv:2505.10373 (v2), DOI: 10.48550/arXiv.2505.10373.

Installation

The package is available on PyPI:

pip install fit2SM

For development:

git clone https://github.com/mattiamarzi/fit2SM
cd fit2SM
pip install -e ".[dev]"
pytest -q

Quick start (Fit2SM)

The Fit2SM solver takes as input:

  • nonnegative fitness proxies strengths,
  • the target number of links L,
  • the target number of two-stars S.

It returns the fitted parameters (z, y) and the reconstructed probability matrix $P=(p_{ij})$ (optionally).

import numpy as np
from fit2sm.fit2sm import Fit2SMModel

# Example inputs (replace with your own)
n = 200
rng = np.random.default_rng(0)

strengths = rng.lognormal(mean=0.0, sigma=1.0, size=n)  # nonnegative fitness proxies
L_target = 1200.0                                       # expected number of links
S_target = 45000.0                                      # expected number of two-stars

model = Fit2SMModel(strengths=strengths, L=L_target, S=S_target)

# "Single-iteration" (fast) reconstruction: kappa is initialized from dcGM and not iterated further.
res = model.fit(outer_max_steps=1, inner_tol=1e-6, inner_max_iter=200, return_P=True)

print("z =", res.z)
print("y =", res.y)
print("L_hat =", res.L_hat, "target =", res.L_target)
print("S_hat =", res.S_hat, "target =", res.S_target)

P = res.P  # fitted link probabilities

If you do not request return_P=True, you can still compute the probability matrix later:

P = model.probabilities()

If you have an observed adjacency matrix

If you do have a binary adjacency matrix $A$, you can compute targets as:

k_obs = A.sum(axis=1)
L_obs = 0.5 * A.sum()
S_obs = float(0.5 * np.sum(k_obs * (k_obs - 1.0)))

Advanced options (Fit2SM)

Outer self-consistency on $\kappa$

Fit2SM is defined in terms of hidden mean-field degrees $\kappa$. You can iterate them until self-consistency:

res = model.fit(
    outer_max_steps=25,
    outer_tol=1e-6,
    inner_tol=1e-8,
)

Fixing $\kappa$ to a supplied degree sequence (like the observed one)

If you want to bypass the outer fixed point and keep $\kappa$ fixed, set use_true_degrees=True and pass degrees=...:

res = model.fit(
    use_true_degrees=True,
    degrees=k_obs,
)

Other solvers

You can also import and use dcGM and UBCM directly:

from fit2sm.dcgm import DcGMModel
from fit2sm.ubcm import UBCMModel

# dcGM (matches L using strengths)
dcgm = DcGMModel(strengths=strengths, L=L_target)
dcgm_res = dcgm.fit()
P_dcgm = dcgm_res.P

# UBCM (matches expected degrees)
ubcm = UBCMModel(degrees=k_obs)
ubcm_res = ubcm.fit()
P_ubcm = ubcm.probabilities()

Documentation

  • docs/usage.md
  • docs/api_quick_reference.md
  • docs/math.md

License

MIT, see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fit2sm-0.1.0.tar.gz (19.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fit2sm-0.1.0-py3-none-any.whl (19.6 kB view details)

Uploaded Python 3

File details

Details for the file fit2sm-0.1.0.tar.gz.

File metadata

  • Download URL: fit2sm-0.1.0.tar.gz
  • Upload date:
  • Size: 19.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.13

File hashes

Hashes for fit2sm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 45f06efbee759c93a6d2ac9fcac9048f7d9a3249f7d5b3226cf4e2d82f9210ae
MD5 ee36f46494997c8f8f1859c44a2f520e
BLAKE2b-256 b1a69035006b0d15868448d335d1f0a86a0bc0907d419653b1734bc653875c3e

See more details on using hashes here.

File details

Details for the file fit2sm-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: fit2sm-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 19.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.13

File hashes

Hashes for fit2sm-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f677a86ede7e0a32b6d1e77945a737d766c9cf78dc4638eb31bcecfb70bcc35d
MD5 2a9595801bc980e592dd6bc89dbf6557
BLAKE2b-256 c24e43fc7f30d6950f41bb742b2c5e1d043c743e32dd61818594526d3d93392b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page