graphsimulacrum
Mechanistic synthetic data generation for Marketing Mix Modeling (MMM) validation.
MMMs are usually benchmarked against synthetic data built from the same functional
forms (Adstock, Hill curves) the models assume — which guarantees flattering but
meaningless parameter recovery. graphsimulacrum breaks that circularity: you declare a
causal DAG of agent-level behavioral rules (exposure, memory decay, purchase choice),
and macro phenomena like carryover and saturation emerge from millions of simulated
individual decisions instead of being written into equations.
Every run produces three things a real dataset never can:
- An observable dataset — a clean panel (spend, exposure, conversions, revenue) in schemas ready for Robyn, Meridian, or any custom MMM.
- A ground-truth ledger — the true per-channel, per-period causal increments, computed via paired counterfactual runs under Common Random Numbers (CRN). This is what your MMM estimates get scored against.
- A provenance manifest — full spec, seeds, and content hashes, so any run is exactly reproducible.
The framework can run fully synthetic, or in hybrid mode, binding real macroeconomic indicators or historical spend plans to the simulation — including ground-truth incrementality for a real media plan.
Quickstart
Requires Python 3.11+. Install into any environment — a plain venv, conda,
uv, or poetry all work. Using the standard library venv:
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install graphsimulacrum # or: pip install -e '.[dev]' from a clone
graphsimulacrum run docs/reference_scenarios/clean_world.yaml -o out/clean --backend numba
That writes a full run bundle to out/clean/: the observed panel, the ground-truth
ledger, MMM-ready exports (Robyn/Meridian/tidy), and a provenance manifest.
Prefer uv? It's a supported optional accelerator —
uv syncthenuv run graphsimulacrum ...— but nothing here requires it.On some filesystems (e.g. exFAT/FAT32 external drives) a virtual environment can't be created in-tree; put it on a native-filesystem path instead. See
docs/faq.md.
The two reference scenarios
clean_world.yaml— media spend is orthogonal to demand; everything the DAG uses is observed. No excuses for a badly specified MMM.confounded_world.yaml— TV spend is planned against the same seasonal cycle that drives demand, and the observed panel hides that seasonality column entirely. A naive attribution will credit TV with demand it never caused — the ledger is the only way to see it.
See docs/reference_scenarios/README.md for the DAG and the numbers.
Documentation
The full documentation is a MkDocs site under docs/. Build and preview it
locally with one command each:
pip install -e '.[docs]'
mkdocs serve # live preview at http://127.0.0.1:8000
mkdocs build --strict # production build; fails on broken links
| Doc | What's in it |
|---|---|
docs/index.md |
Site home / overview |
docs/quickstart.md |
Install → run → inspect → score a naive MMM, start to finish |
docs/concepts.md |
Core concepts: DGP/model decoupling, CRN, the ledger, the dirty lens |
docs/ARCHITECTURE.md |
Full design spec: layers, data contracts, RNG/CRN discipline |
docs/tutorial.md |
Spec → panel → ledger → export → score, worked end to end |
docs/tutorials/ |
Market-calibrated worlds scored against three real MMM libraries |
docs/hybrid_mode.md |
Binding real time series (spend plans, macro indices) |
docs/extend.md |
Authoring mechanisms, distributions, corruption steps, adapters |
docs/export_adapters.md |
Robyn / Meridian / tidy exports |
docs/experiments.md |
Scenarios and parameter sweeps |
docs/api.md / docs/reference.md |
API cheatsheet + autogenerated reference |
docs/releasing.md |
Maintainer release ritual (tag-driven publishing) |
docs/faq.md |
Common gotchas |
.claude/CLAUDE.md |
Development workflow, environment setup, build order |
Status
v1 feature-complete (M0–M3): spec + compiler, NumPy/Numba kernels, counterfactual
engine + ground-truth ledger, hybrid-mode series binding, observation model, Robyn/
Meridian/tidy export adapters, experiment manager (scenarios & sweeps), and the two
reference scenarios above. See .claude/CLAUDE.md for the detailed status and
docs/ARCHITECTURE.md §12 for the roadmap of what's intentionally out of scope for v1
(agent-to-agent interaction, distributed backends, differentiable simulation).
Development
From a clone, install the package with its dev dependencies (editable), then run the checks. One command sets everything up:
pip install -e '.[dev]'
pytest # full test suite
ruff check src/ tests/ # lint
ruff format --check src/ tests/ # format check
mypy src/graphsimulacrum/spec src/graphsimulacrum/compile --strict
(Prefix any command with uv run if you use uv; it is optional.)
See .claude/CLAUDE.md for the full contributor workflow.
Metadata
Release files for graphsimulacrum 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| graphsimulacrum-0.1.0.tar.gz | 2.4 MB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| graphsimulacrum-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.4 MB
Release files / graphsimulacrum-0.1.0.tar.gz
| Download URL | graphsimulacrum-0.1.0.tar.gz |
|---|---|
| Size | 2.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2203864facbecc3e9c952579bb261c9c8257e81ca8c4a7e0f72919676df65ec4
|
|
BLAKE2b-256 checksum How to use checksums |
42d740734ebff6e3a0a16bf947d5f2f3fc5ce90a667013ee7a8fd81309e3d6f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
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 Jul 21, 2026.
Transparency logRelease files / graphsimulacrum-0.1.0-py3-none-any.whl
| Download URL | graphsimulacrum-0.1.0-py3-none-any.whl |
|---|---|
| Size | 81.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
db17a072a84d74d49e7f0cd7fbf424562730ecba7d1c9658248d2ddd3f715a96
|
|
BLAKE2b-256 checksum How to use checksums |
f36b20c90089f5af6251df7476c846deffb9dcdf19b595459e6eb1563762a097
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
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 Jul 21, 2026.
Transparency logSecurity for graphsimulacrum 0.1.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for graphsimulacrum-0.1.0.tar.gz
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 Jul 21, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.