Skip to main content

REMFlow: relational event modeling in Python

REMFlow implements relational event models (REMs) for ordered sender-receiver interactions. For each observed event, it constructs the set of events that could have occurred and evaluates time-varying network statistics for the observed and alternative events.

The package fits conditional event-choice models for ordinal data and intensity models for exact or duration data. It supports tie-oriented and actor-oriented specifications, model diagnostics, and next-event prediction. The general high-level facade supports untyped and typed tie-oriented events. A dedicated misinformation subclass adds descriptive actor-role and group-similarity measures and evaluates actor removal in the conditional next-event distribution.

Installation

REMFlow requires Python 3.11 or newer. Install the released package from PyPI:

python -m pip install remflow

Only for development from a source checkout, use an editable install:

python -m pip install -e .

For development and documentation work:

python -m pip install -e ".[dev,docs]"

JAX support is optional:

python -m pip install "remflow[gpu]"

For GPU use, install the JAX build appropriate for the local CUDA setup. An explicit backend="jax:gpu" request fails with BackendUnavailable if JAX cannot see a GPU; it does not fall back to the CPU.

The optional CuPy dependency is used only by the CUDA comparison benchmarks:

python -m pip install "remflow[benchmark-cuda]"

A small example

The following example fits an exact-time model with inertia, reciprocity, and outgoing two-path statistics:

import pandas as pd

from remflow import diagnostics, remify, remstats, remstimate

events = pd.DataFrame(
    {
        "time": [1.0, 2.0, 3.0, 4.0, 5.0],
        "sender": ["A", "B", "A", "C", "B"],
        "receiver": ["B", "A", "C", "A", "C"],
    }
)

history = remify(events, actors=["A", "B", "C"], ordinal=False)
statistics = remstats(
    history,
    tie_effects="~ inertia() + reciprocity() + otp()",
    first=2,
)
fit = remstimate(history, statistics, backend="numpy")

print(fit.summary())
print(diagnostics(fit, history, statistics).summary())

Set ordinal=True to fit a conditional event-choice model instead. Public actor, dyad, type, and event identifiers are 1-based; the input labels remain available in the history dictionaries.

The formula language is intentionally restricted and never calls eval or exec. The same effects can also be assembled with the Python builder API.

What is implemented

Event histories may be directed or undirected and may use exact, ordinal, or duration time. The preprocessing code handles simultaneous and typed events, weights, actor and dyad attributes, manual opportunity sets, and sampled tie risk sets. For larger datasets, remify(..., ncores=2) can build risk sets concurrently without changing their order.

The statistics module includes inertia, reciprocity, degree effects, shared partners, participation shifts, recency, rank, active-state effects, and user covariates. Both string formulas and typed effect objects preserve term order.

The main estimation paths are:

  • tie-oriented and actor-oriented ordinal or exact-time MLE;
  • HMC for supported tie and actor models;
  • interval and ordinal duration MLE;
  • sampled tie likelihoods;
  • frequentist penalties, random effects, finite mixtures, and moving windows;
  • Bayesian shrinkage in its documented NumPy paths.

Fits retain coefficient order, covariance information, convergence status, backend metadata, fitted probabilities, and the data needed by the available diagnostics. AIC, BIC, AICC, and WAIC are provided where their required inputs exist.

The general RelationalEventModel facade works with untyped or typed events. MisinformationModel extends it with action and stance conventions, descriptive actor-role scores, source ranking, echo-chamber metrics, and a conditional next-event intervention. The intervention is not a full cascade simulator or a causal estimator.

Current limitations

Several combinations are rejected explicitly because their statistical or backend implementation is not complete:

  • type-expanded actor risk sets and actor case-control sampling;
  • Bayesian frailty/random-effects models and general Bayesian duration models;
  • WAIC for mixture, random-effects, and duration fits;
  • non-constant concomitant formulas in mixture models;
  • JAX execution for mixtures, random effects, penalties, and shrinkage;
  • duration attribution with remtribute.

Text embeddings and stance labels are not generated by REMFlow. Supply them as covariates if an analysis needs them.

Backends

Use backend="numpy", "jax", "jax:cpu", or "jax:gpu". The default numpy backend runs on the CPU. For model families with a JAX implementation, jax:cpu and jax:gpu place the likelihood and derivative calculations on the requested device. Both implementations use float64, and the test suite checks their numerical agreement. Fit metadata records the selected backend, platform, device, precision, JAX version, and compilation state.

engine="auto" currently selects SciPy. The optimizer engine and array backend are separate choices: selecting SciPy does not prevent supported objective or gradient work from running through JAX.

GPU benchmark

The hardware-gated suite was run using an NVIDIA GeForce RTX 4070 Laptop GPU (8 GiB), Python 3.12.3, JAX/JAXLIB 0.7.2, CUDA 12, and float64. All 11 GPU tests passed without CPU fallback.

The measurements below are means from 10 likelihood-and-gradient evaluations after JAX compilation. They measure the numerical kernel, not event preprocessing or total fitting time.

Actors Events Risk set NumPy JAX GPU Speedup Maximum gradient error
50 1,000 2,450 176.330 ms 5.734 ms 30.75x 2.13e-14
100 1,000 9,900 419.867 ms 11.055 ms 37.98x 2.49e-14

Warm-up took 3.208 seconds for 50 actors and 11.220 seconds for 100 actors. Measured peak GPU memory was 165.42 MiB and 512.00 MiB, respectively. To rerun the checks and benchmark:

REMFLOW_REQUIRE_GPU=1 JAX_ENABLE_X64=true python -m pytest -q tests/gpu
python benchmarks/run_gpu_study.py --repeats 10 --include-large

Small problems may be faster with NumPy because JAX compilation and device transfer overhead dominate the computation.

Development checks

uv run python -m pytest
uv run python -m ruff check .
uv run python -m mypy src
uv run python -m sphinx -W --keep-going -b html docs docs/_build/html

The physical-GPU tests run only when compatible hardware is available and REMFLOW_REQUIRE_GPU=1 is set.

Documentation

License

REMFlow is released under the MIT License. The classroom dataset in data/classroom_events/ keeps its upstream CC BY-NC-ND 4.0 license and is not covered by the project license. Provenance and reuse terms are recorded with the data.

Metadata

Release files for remflow 0.1.1

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

Source distribution (sdist)

Source distribution for remflow 0.1.1
File Size Uploaded
remflow-0.1.1.tar.gz 111.9 kB Details

Built distribution (wheel)

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

Total release size: 229.1 kB

Release files / remflow-0.1.1.tar.gz

Download URL remflow-0.1.1.tar.gz
Size 111.9 kB
Tags Source
SHA-256 checksum
How to use checksums
136247d0ee48f04a29a673c28f62da02e49b561be901839281be3cf88d393648
BLAKE2b-256 checksum
How to use checksums
a4624dd896bb9b9c74651ec1b4c5d6ecd40d4f28d3679106dbbfe850d5a60306
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 5, 2026.

Transparency log

Release files / remflow-0.1.1-py3-none-any.whl

Download URL remflow-0.1.1-py3-none-any.whl
Size 117.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
34456bb77cb0120b652bc3bd8225027e9632fdf5d8ccb2262e3756d31de6927b
BLAKE2b-256 checksum
How to use checksums
4d3d43ca457f19bc75d84b785ea00e8c4bd36f7a1354825bc471b7103bd1cb0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 5, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.2

2 release files

This release

0.1.1 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