Measurement-Mechanistic RCA
This repository contains a Python package for measurement-mechanistic root cause analysis and the replication package for the NeurIPS paper Root Cause Analysis of Measurement and Mechanistic Anomalies.
The top-level package is the recommended entry point for users. It installs with pip, avoids the R dependency by default, and exposes the method for several practical settings:
- contaminated data, with priors learned implicitly by the method;
- contaminated data, with user-provided measurement and generative priors;
- uncontaminated training data, followed by inference on new samples with provided priors.
- causal discovery with the optional bundled NoGAM helper, followed by measurement-mechanistic RCA.
The original experiment code is kept in replication_neurips/. The git repository is intended to contain both the lightweight package and the complete replication artifact. A wheel or PyPI-style distribution should contain only the high-level package, the minimal cali implementation needed to run the method, and the bundled NoGAM causal-discovery helper. It should not contain the full replication package or external baselines.
Citation
If you use this code, please cite:
@inproceedings{suhr:2026:rca,
title={Root Cause Analysis of Measurement and Mechanistic Anomalies},
author={Hendrik Suhr and David Kaltenpoth and Jilles Vreeken},
booktitle={Advances in Neural Information Processing Systems},
volume={39},
year={2026},
url={https://openreview.net/forum?id=2sxylzR1R2}
}
Installation
For the lightweight method package, install from PyPI:
pip install measurement-mechanistic-rca
Install the optional NoGAM causal-discovery dependencies with:
pip install "measurement-mechanistic-rca[causal-discovery]"
For local development from this repository:
python -m venv .venv
source .venv/bin/activate
pip install -e .
The default backend is the pure-Python spline expectile variant using pygam. A scikit-learn spline quantile backend is also available for comparison.
Editable installs from a full repository checkout can also use the bundled examples and replication helpers. Built package distributions are intentionally smaller: they include the public measurement_mechanistic_rca API, the minimal cali method implementation, and NoGAM via the bundled dodiscover code. The complete NeurIPS replication package remains in the git repository.
The R/qgam backend is still available for comparison if R, qgam, mgcv, and rpy2 are installed:
pip install "measurement-mechanistic-rca[qgam]"
To run the notebook examples:
pip install -e ".[causal-discovery,notebooks]"
jupyter notebook examples/method_usage.ipynb
Quick Start
The graph must be a networkx.DiGraph, and the data must be an n x d NumPy array whose columns match the graph node indices.
import networkx as nx
import numpy as np
from measurement_mechanistic_rca import MeasurementMechanisticRCA
dag = nx.DiGraph([(0, 1), (1, 2)])
data = np.random.normal(size=(100, 3))
model = MeasurementMechanisticRCA()
result = model.fit_explain(data, dag)
print(result.assignment)
print(result.top_features(sample_idx=0, k=3))
result.feature_scores[i, j] scores feature j as a root cause for sample i. result.classifications[i, j] is 1 for measurement-origin explanations and 0 for generative-origin explanations.
An executable walkthrough of the main usage patterns is provided in examples/method_usage.ipynb.
Contaminated Data With Provided Priors
If you have prior probabilities for measurement and generative anomalies, pass them directly. Priors can be global vectors of shape (d,) or sample-specific arrays of shape (n, d).
measurement_priors = np.array([0.01, 0.10, 0.01])
generative_priors = np.array([0.02, 0.02, 0.05])
model = MeasurementMechanisticRCA(
prior_mode="single_root",
)
result = model.fit_explain(
data,
dag,
measurement_priors=measurement_priors,
generative_priors=generative_priors,
)
Use prior_mode="single_root" for the fast setting that assumes one active root cause per sample. Use prior_mode="exhaustive" to enumerate all assignments; this is only practical for small graphs because it scales as 4^d.
Clean Training Data Then New Samples
When mechanisms are learned from uncontaminated data, priors must be provided for inference on new samples. The package keeps the training scaler, mechanisms, and residual distributions fixed.
clean_data = np.random.normal(size=(500, 3))
new_samples = np.random.normal(size=(10, 3))
measurement_priors = np.array([0.01, 0.10, 0.01])
generative_priors = np.array([0.02, 0.02, 0.05])
model = MeasurementMechanisticRCA()
model.fit(clean_data, dag)
result = model.explain(
new_samples,
measurement_priors=measurement_priors,
generative_priors=generative_priors,
)
The same workflow is included in the notebook:
jupyter notebook examples/method_usage.ipynb
Causal Discovery Then RCA
The method consumes a networkx.DiGraph. If the causal graph is unknown, learn a DAG first and pass the learned graph into the same RCA API:
from measurement_mechanistic_rca import MeasurementMechanisticRCA, discover_dag_nogam
learned_dag = discover_dag_nogam(clean_data, n_crossval=3)
model = MeasurementMechanisticRCA()
result = model.fit_explain(
data,
learned_dag,
measurement_priors=measurement_priors,
generative_priors=generative_priors,
)
discover_dag_nogam wraps the bundled Python NoGAM implementation. It has no R dependency and is available from PyPI when installing with the causal-discovery extra. The repository also includes discover_dag_topic for the bundled TOPIC implementation when running from a full checkout, and discover_dag_from_order for small examples where a causal order is known. Minimal wheel/PyPI-style distributions are not expected to bundle TOPIC.
Regression Backends
Choose the spline regression backend through regression_backend:
expectile: default pure-Python spline expectile regression.quantile: pure-Python scikit-learn spline median-regression replacement.qgam: R/qgam backend used in all paper experiments.
MeasurementMechanisticRCA()
MeasurementMechanisticRCA(regression_backend="quantile")
MeasurementMechanisticRCA(regression_backend="qgam")
Replication Package
The paper replication package lives in replication_neurips/. It contains the experiment runner, baselines, cached result files, plotting code, and Docker-based build instructions. Clone the git repository to run these exact paper experiments; they are intentionally not part of the PyPI package. For the full replication setup, including the recommended Docker build, see replication_neurips/README.md.
Representative paper experiments:
python main.py -e rca
python main.py -e classification
python main.py -e causal_discovery
python main.py -e rca_cc_strong
python main.py -e classification_cc_strong
python main.py -e sachs
These cover the standard synthetic root-cause localization experiment, anomaly-type classification, RCA with learned causal graphs, Causal Chamber real-data variants, and the Sachs real-world experiment. The replication package also contains robustness and sensitivity studies such as rca_dag_misspecification, rca_confounding, rca_heteroscedasticity, rca_soft_interventions, rca_sample_sensitivity, rca_feature_sensitivity, and the corresponding classification variants.
The generated result tables are written under replication_neurips/src/results/, and plots are written under replication_neurips/src/plots/.
License
Code developed for this package is released under the CC BY 4.0 license; see LICENSE. Bundled or adapted external code remains under the licenses of the respective upstream projects; see THIRD_PARTY_NOTICES.md, the external repositories, and the notes in replication_neurips/README.md.
Metadata
Release files for measurement-mechanistic-rca 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 | |
|---|---|---|---|---|
| measurement_mechanistic_rca-0.1.0.tar.gz | 143.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| measurement_mechanistic_rca-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 317.1 kB
Release files / measurement_mechanistic_rca-0.1.0.tar.gz
| Download URL | measurement_mechanistic_rca-0.1.0.tar.gz |
|---|---|
| Size | 143.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
016b0d01e60448c8e448c2dfa8c6438e010c23d36ece7c973178c2c76f51ed21
|
|
BLAKE2b-256 checksum How to use checksums |
0d70e26f7e87517f53f055f4d0e460736fd7f80a243d659bf20b993cf08269fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Release files / measurement_mechanistic_rca-0.1.0-py3-none-any.whl
| Download URL | measurement_mechanistic_rca-0.1.0-py3-none-any.whl |
|---|---|
| Size | 173.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
247c8db8b0ac7f06f5f2e4a00a2ce441d4d1296f692d0d2c7ab7d10f922c2d57
|
|
BLAKE2b-256 checksum How to use checksums |
1ac2f1c98df453c2aae1696809dd946aff5f730b489c1d64d6c79a5bd305001b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Security for measurement-mechanistic-rca 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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.