CausalBoundingEngine
A unified Python framework for causal effect bounding algorithms
Overview
CausalBoundingEngine is a modular Python package that provides a unified interface for comparing and applying state-of-the-art causal bounding algorithms. It enables researchers and practitioners to compute bounds on causal effects when unmeasured confounding is present.
Key Features
🔧 Unified Interface - Consistent API across all algorithms and scenarios
📊 Multiple Algorithms - Manski, Tian-Pearl, Autobound, Causaloptim, Zaffalonbounds, and more
🎯 Flexible Scenarios - Support for confounded and instrumental variable settings
🔗 External Engines - Integration with R (rpy2) and Java (jpype1) backends
🚀 Easy Extension - Simple framework for adding new algorithms and scenarios
📚 Comprehensive Docs - Detailed documentation with examples and API reference
Supported Algorithms
| Algorithm | ATE | PNS | Scenarios | Dependencies | Reference |
|---|---|---|---|---|---|
| Manski | ✓ | ✗ | BinaryConf | Core | Manski (1990) |
| Tian-Pearl | ✗ | ✓ | BinaryConf | Core | Tian & Pearl (2000) |
| Autobound | ✓ | ✓ | BinaryConf, BinaryIV | Core | Duarte et al. (2023) |
| Entropybounds | ✓ | ✓ | BinaryConf | Core | Jiang et al. (2023) |
| Causaloptim | ✓ | ✓ | BinaryConf, BinaryIV | R | Sachs et al. (2022) |
| Zaffalonbounds | ✓ | ✓ | BinaryConf, BinaryIV | Java | Zaffalon et al. (2022) |
| ZhangBareinboim | ✓ | ✗ | ContIV | Core | Zhang & Bareinboim (2021) |
Installation
🐍 For smooth sailing, Python 3.12 or greater is recommended.
While CausalBoundingEngine supports Python 3.8+, you may encounter issues in some specific situations with older versions.
Core Package
pip install causalboundingengine
Optional Dependencies
For extended functionality, install with optional dependencies:
# R integration (Causaloptim algorithm)
pip install causalboundingengine[r]
# Java integration (Zaffalonbounds algorithm)
pip install causalboundingengine[java]
# All optional features
pip install causalboundingengine[full]
# Documentation building
pip install causalboundingengine[docs]
System Dependencies
For algorithms requiring external engines:
R Support (for Causaloptim):
# Ubuntu/Debian
sudo apt install r-base
# macOS
brew install r
# Windows: Download from https://cran.r-project.org/
Java Support (for Zaffalonbounds):
# Ubuntu/Debian
sudo apt install default-jre
# macOS
brew install openjdk
# Windows: Download from https://adoptium.net/
Quick Start
Note: numeric results in the examples are for illustrative porpuses and not necessarily correct.
Basic Usage
import numpy as np
from causalboundingengine.scenarios import BinaryConf
# Your observational data
X = np.array([0, 1, 1, 0, 1, 0, 1, 0]) # Treatment
Y = np.array([1, 0, 1, 0, 1, 1, 0, 1]) # Outcome
# Create scenario and compute bounds
scenario = BinaryConf(X, Y)
# Compute ATE bounds with different algorithms
manski_bounds = scenario.ATE.manski() # (-1.0, 1.0) - Most conservative
autobound_bounds = scenario.ATE.autobound() # (-0.5, 0.5) - LP optimization
print(f"Manski bounds: {manski_bounds}")
print(f"Autobound bounds: {autobound_bounds}")
Instrumental Variable Analysis
from causalboundingengine.scenarios import BinaryIV
# IV data (e.g., randomized trial with non-compliance)
Z = np.array([0, 1, 1, 0, 1, 0, 1, 0]) # Instrument (randomization)
X = np.array([0, 1, 0, 0, 1, 0, 1, 0]) # Treatment (actual uptake)
Y = np.array([1, 0, 1, 0, 1, 1, 0, 1]) # Outcome
# Create IV scenario
scenario = BinaryIV(X, Y, Z)
# Compute bounds leveraging IV assumptions
iv_bounds = scenario.ATE.autobound()
print(f"IV-based bounds: {iv_bounds}") # Often tighter than confounded case
Continuous Outcomes
from causalboundingengine.scenarios import ContIV
# Binary instrument/treatment with continuous outcome
Z = np.array([0, 1, 1, 0, 1]) # Binary instrument
X = np.array([0, 1, 1, 0, 1]) # Binary treatment
Y = np.array([0.2, 0.8, 0.6, 0.1, 0.9]) # Continuous outcome [0,1]
scenario = ContIV(X, Y, Z)
bounds = scenario.ATE.zhangbareinboim()
print(f"Continuous outcome bounds: {bounds}")
Examples
Algorithm Comparison
import numpy as np
from causalboundingengine.scenarios import BinaryConf
# Generate example data
np.random.seed(42)
n = 1000
X = np.random.binomial(1, 0.3, n)
Y = np.random.binomial(1, 0.6, n)
scenario = BinaryConf(X, Y)
# Compare multiple algorithms
algorithms = ['manski', 'autobound', 'entropybounds']
results = {}
for alg in algorithms:
if alg == 'entropybounds':
bounds = getattr(scenario.ATE, alg)(theta=0.5)
else:
bounds = getattr(scenario.ATE, alg)()
results[alg] = bounds
print(f"{alg:15} ATE bounds: {bounds}")
# Output:
# manski ATE bounds: (-0.7, 0.7)
# autobound ATE bounds: (-0.3, 0.3)
# entropybounds ATE bounds: (-0.2, 0.2)
Sensitivity Analysis
# Sensitivity analysis with Entropybounds
thetas = [0.1, 0.3, 0.6, 0.8]
for theta in thetas:
bounds = scenario.ATE.entropybounds(theta=theta)
width = bounds[1] - bounds[0]
print(f"θ={theta}: bounds={bounds}, width={width:.3f}")
# Output shows how bounds widen as assumptions weaken:
# θ=0.1: bounds=(-0.15, 0.15), width=0.735
# θ=0.3: bounds=(-0.25, 0.25), width=0.995
# θ=0.6: bounds=(-0.35, 0.35), width=1.000
# θ=0.8: bounds=(-0.45, 0.45), width=1.000
Robust Analysis Workflow
def robust_analysis(X, Y, Z=None):
"""Run multiple algorithms for robustness."""
if Z is None:
scenario = BinaryConf(X, Y)
algorithms = ['manski', 'autobound']
else:
scenario = BinaryIV(X, Y, Z)
algorithms = ['autobound'] # Add 'causaloptim', 'zaffalonbounds' if available
results = {}
for alg in algorithms:
try:
results[alg] = getattr(scenario.ATE, alg)()
print(f"✓ {alg}: {results[alg]}")
except Exception as e:
print(f"✗ {alg}: {e}")
return results
# Run robust analysis
bounds_dict = robust_analysis(X, Y)
Scenarios
CausalBoundingEngine organizes algorithms by causal scenario:
BinaryConf
- Use case: Observational studies with binary treatment/outcome
- Assumptions: Potential unmeasured confounding
- Algorithms: Manski, Autobound, Entropybounds, Causaloptim, Zaffalonbounds
BinaryIV
- Use case: Instrumental variable analysis with binary variables
- Assumptions: Valid instrument (relevance, exclusion, exogeneity)
- Algorithms: Autobound, Causaloptim, Zaffalonbounds
ContIV
- Use case: Binary instrument/treatment with continuous outcome [0,1]
- Assumptions: Valid instrument, bounded outcome
- Algorithms: ZhangBareinboim
Advanced Features
Custom Algorithm Parameters
# Entropybounds with custom confounding strength
bounds = scenario.ATE.entropybounds(theta=0.2)
# Causaloptim with custom R path
bounds = scenario.ATE.causaloptim(r_path="/usr/local/bin/R")
Algorithm Availability
# Check available algorithms
print("ATE algorithms:", scenario.get_algorithms('ATE'))
print("PNS algorithms:", scenario.get_algorithms('PNS'))
# Dynamic algorithm access
algorithm_name = 'manski'
if algorithm_name in scenario.get_algorithms('ATE'):
bounds = getattr(scenario.ATE, algorithm_name)()
Error Handling
import logging
logging.basicConfig(level=logging.WARNING)
# Algorithms return trivial bounds on failure
bounds = scenario.ATE.some_algorithm()
if bounds == (-1.0, 1.0): # ATE trivial bounds
print("Algorithm failed, returned trivial bounds")
Documentation
📖 Full Documentation: https://causalboundingengine.readthedocs.io/
The documentation includes:
- Installation Guide - Detailed setup instructions
- Quick Start - Get up and running quickly
- User Guide - Concepts and best practices
- Algorithm Reference - Detailed algorithm documentation
- Scenario Guide - When to use which scenario
- API Reference - Complete API documentation
- Examples - Real-world usage examples
- References - Citations and credits
Testing
CausalBoundingEngine includes a comprehensive test suite to ensure reliability.
Quick Test Run
# Run basic tests (minimal dependencies)
python -m pytest tests/test_dummy.py tests/test_scenarios.py::TestDataClass -v
# Run core algorithm tests
python -m pytest tests/test_core_algorithms.py -v
# Run all tests
python -m pytest tests/ -v
Test Coverage
✅ Core functionality - Data structures, basic algorithms
✅ Algorithm interfaces - Manski, Tian-Pearl bounds
✅ Scenario framework - Data handling, dispatching
✅ Integration tests - End-to-end workflows
⚠️ Optional components - Require additional dependencies
See TESTING.md for detailed testing documentation.
Contributing
We welcome contributions! The process is simple:
- Fork the repository on GitHub
- Clone your fork and install:
pip install -e . - Make your changes and add tests
- Submit a Pull Request
See our Contributing Guide for details.
Areas for Contribution
- 🔧 New algorithm implementations
- 📊 Additional causal scenarios
- 🐛 Bug fixes and improvements
- 📚 Documentation and examples
- 🚀 Performance optimizations
Citation
If you use CausalBoundingEngine in your research, please cite the relevant algorithm papers. See the References section for complete citations.
BibTeX Template
@software{causalboundingengine,
title={CausalBoundingEngine: A Unified Framework for Causal Effect Bounding},
author={[Tobias Maringgele]},
year={2025},
url={https://github.com/tmaringgele/CausalBoundingEngine},
note={Python package for causal effect bounding algorithms}
}
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
CausalBoundingEngine integrates algorithms from multiple research papers. We gratefully acknowledge:
- Manski (1990) - Nonparametric bounds foundation
- Tian & Pearl (2000) - Probability of causation bounds
- Duarte et al. (2023) - Autobound optimization approach
- Jiang et al. (2023) - Entropy-based weak confounding
- Sachs et al. (2022) - Causaloptim R library
- Zaffalon et al. (2022) - Causal expectation maximisation approach
- Zhang & Bareinboim (2021) - Continuous outcome bounding
See the References page for complete citations and attributions.
Built with 💙 for causal inference
Documentation • PyPI • GitHub
Metadata
Release files for causalboundingengine 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| causalboundingengine-0.1.5.tar.gz | 22.9 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| causalboundingengine-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.3 MB
Release files / causalboundingengine-0.1.5.tar.gz
| Download URL | causalboundingengine-0.1.5.tar.gz |
|---|---|
| Size | 22.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cd71334def35c2f8e2d3fbdf6be03ea08513f8071f0c3c97ebcdee6b281cdc13
|
|
BLAKE2b-256 checksum How to use checksums |
1cd30f713a072875391032a858d74a3ba6b28b95715367bbdb1b9e0b384cadeb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.6
|
Release files / causalboundingengine-0.1.5-py3-none-any.whl
| Download URL | causalboundingengine-0.1.5-py3-none-any.whl |
|---|---|
| Size | 22.5 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2309f902cfec413ea902b7106c731e7bfdce7f24659b529a75fcd348c0182789
|
|
BLAKE2b-256 checksum How to use checksums |
d4c3eddef2aacb32a631483fe7f71889b6544112b6b64d9d92f18ec33a138654
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.6
|