PyCausalSim v0.1.0: A Python Framework for Causal Discovery Through Simulation

Finally, a tool that tells you WHY things happen, not just WHAT happened

https://github.com/Bodhi8/pycausalsim

If you found this useful, you can support my independent research here: https://www.paypal.biz/vector1research


If you’ve ever run an A/B test, analyzed conversion rates, or tried to understand what actually drives your key metrics, you’ve probably faced the same frustrating question:

“Is this really causing the change, or is it just correlation?”

Traditional analytics and machine learning tell you what predicts an outcome. But prediction ≠ causation. And when you need to make decisions — to intervene, to optimize, to change something — you need causation.

Today, I’m excited to announce the release of PyCausalSim v0.1.0, a Python framework that uses simulation to discover and validate causal relationships in your data.


The Problem: Correlation Is Easy, Causation Is Hard

Let’s say your conversion rate increased after you reduced page load time. Great! But did the load time cause the increase? Or did something else change at the same time?

  • Maybe you launched a marketing campaign the same week
  • Maybe seasonal effects kicked in
  • Maybe a competitor went offline
  • Maybe it was just random noise

Traditional approaches fail here:

python

# WRONG: This doesn't tell you what CAUSES conversions
from sklearn.ensemble import RandomForestRegressor

rf = RandomForestRegressor()
rf.fit(X, y)
print(rf.feature_importances_)  # Tells you what predicts, NOT what causes

Feature importance tells you what predicts your outcome, but it doesn’t account for confounding, can’t distinguish cause from effect, fails with selection bias, and gives you correlation — not causation.


The Solution: PyCausalSim

PyCausalSim takes a fundamentally different approach. Instead of just finding patterns, it:

  1. Learns the causal structure of your system
  2. Simulates counterfactual scenarios (what would have happened if…)
  3. Validates causal claims with rigorous statistical tests

Here’s how it works:

python

from pycausalsim import CausalSimulator

# Initialize with your data
simulator = CausalSimulator(
    data=df,
    target='conversion_rate',
    treatment_vars=['page_load_time', 'price', 'design_variant'],
    confounders=['traffic_source', 'device_type']
)

# Discover causal structure
simulator.discover_graph(method='ges')

# Simulate: What if we reduce load time to 2 seconds?
effect = simulator.simulate_intervention('page_load_time', 2.0)
print(effect.summary())

Output:

Causal Effect Summary
==================================================
Intervention: page_load_time = 2.0
Original value: 3.71
Target variable: conversion_rate

Effect on conversion_rate: +2.3%
95% CI: [+1.8%, +2.8%]
P-value: 0.001

This is a TRUE causal effect, not just correlation!

What’s New in v0.1.0

This release includes a complete, working implementation of the core PyCausalSim vision.

Core Causal Simulator

The CausalSimulator class is the heart of PyCausalSim. It handles graph discovery (learning causal structure automatically from data), intervention simulation (Monte Carlo simulation for counterfactual outcomes), driver ranking (ranking variables by true causal importance), policy optimization (finding optimal settings for controllable variables), and built-in validation (sensitivity analysis, placebo tests, and refutation methods).

python

# Rank true causal drivers
drivers = simulator.rank_drivers()
for var, effect in drivers:
    print(f"{var}: {effect:+.3f}")

# Output:
# page_load_time: +0.150
# price: -0.120
# design_variant: +0.030

Marketing Attribution

Move beyond last-touch attribution to understand the true incremental value of each marketing channel:

python

from pycausalsim import MarketingAttribution

attr = MarketingAttribution(
    data=touchpoint_data,
    conversion_col='converted',
    touchpoint_cols=['email', 'display', 'search', 'social', 'direct']
)

# Causal Shapley values for fair attribution
attr.fit(method='shapley')
weights = attr.get_attribution()
# {'search': 0.35, 'email': 0.25, 'social': 0.20, 'display': 0.15, 'direct': 0.05}

# Optimize budget allocation
optimal = attr.optimize_budget(total_budget=100000)

Supported methods: Shapley values (cooperative game theory), Markov chain attribution, uplift-based attribution, logistic regression, and first/last touch baselines.

A/B Test Analysis

Analyze experiments with proper causal inference — not just t-tests:

python

from pycausalsim import ExperimentAnalysis

exp = ExperimentAnalysis(
    data=ab_test_data,
    treatment='new_feature',
    outcome='engagement',
    covariates=['user_tenure', 'activity_level']
)

# Doubly robust estimation (consistent if EITHER model is correct)
effect = exp.estimate_effect(method='dr')
print(f"Effect: {effect.estimate:.4f} (p={effect.p_value:.4f})")

# Analyze heterogeneous effects
het = exp.analyze_heterogeneity(covariates=['user_tenure'])
# Who responds differently to the treatment?

Estimation methods: Simple difference in means, OLS with covariate adjustment, inverse probability weighting (IPW), doubly robust / AIPW, and propensity score matching.

Uplift Modeling

Identify who will respond to treatments — not just the average effect:

python

from pycausalsim.uplift import UpliftModeler

uplift = UpliftModeler(
    data=campaign_data,
    treatment='received_offer',
    outcome='purchased',
    features=['recency', 'frequency', 'monetary']
)

uplift.fit(method='two_model')

# Segment users by predicted response
segments = uplift.segment_by_effect()

User segments explained:

  • Persuadables — Will convert only if treated. Target these!
  • Sure Things — Will convert regardless. Don’t waste budget on them.
  • Lost Causes — Won’t convert regardless. Don’t waste budget.
  • Sleeping Dogs — Treatment actually hurts them. Avoid!

Structural Causal Models

Build explicit causal models that capture how your system works:

python

from pycausalsim.models import StructuralCausalModel

# Define causal graph
graph = {
    'revenue': ['demand', 'price'],
    'demand': ['price', 'advertising'],
    'price': [],
    'advertising': []
}

scm = StructuralCausalModel(graph=graph)
scm.fit(data)

# Generate counterfactuals
cf = scm.counterfactual(
    intervention={'advertising': 80},
    data=current_data
)

# Compute average treatment effect
ate = scm.ate(
    treatment='price',
    outcome='revenue',
    treatment_value=27,
    control_value=30
)

Multiple Discovery Algorithms

PyCausalSim supports multiple algorithms for learning causal structure:

  • PC (Constraint-based) — General purpose, interpretable
  • GES (Score-based) — Efficient search, good defaults
  • LiNGAM (Functional) — Best for non-Gaussian data
  • NOTEARS (Neural) — Handles complex relationships
  • Hybrid (Ensemble) — Robustness via consensus of multiple methods

python

# Try different methods
simulator.discover_graph(method='pc')      # Constraint-based
simulator.discover_graph(method='ges')     # Score-based
simulator.discover_graph(method='notears') # Neural
simulator.discover_graph(method='hybrid')  # Ensemble

Built-in Validation

Every causal claim should be validated. PyCausalSim makes this easy:

python

sensitivity = simulator.validate(variable='page_load_time')

print(sensitivity.summary())
# - Confounding bounds at different strengths
# - Placebo test results
# - Refutation test results
# - Robustness value (how much confounding would nullify the effect?)

Real-World Example: E-commerce Optimization

Let’s walk through a complete example. You run an e-commerce site and want to understand what actually drives conversions:

python

import pandas as pd
from pycausalsim import CausalSimulator

# Load your data
data = pd.read_csv('ecommerce_metrics.csv')

# Initialize simulator
sim = CausalSimulator(
    data=data,
    target='conversion_rate',
    treatment_vars=['page_load_time', 'price', 'shipping_cost'],
    confounders=['traffic_source', 'device_type', 'time_of_day']
)

# Step 1: Discover causal structure
sim.discover_graph(method='ges')
sim.plot_graph()  # Visualize the learned DAG

# Step 2: Simulate interventions
load_effect = sim.simulate_intervention('page_load_time', 2.0)
price_effect = sim.simulate_intervention('price', current_price * 0.9)

print(f"Load time effect: {load_effect.point_estimate:+.2%}")
print(f"Price reduction effect: {price_effect.point_estimate:+.2%}")

# Step 3: Rank all drivers
print("\nCausal Drivers of Conversion:")
for var, effect in sim.rank_drivers():
    print(f"  {var}: {effect:+.4f}")

# Step 4: Find optimal policy
optimal = sim.optimize_policy(
    objective='maximize_conversion',
    constraints={'price': (10, 50), 'page_load_time': (1, 5)}
)
print(f"\nOptimal settings: {optimal.settings}")
print(f"Expected improvement: {optimal.improvement:+.2%}")

Why This Matters

The difference between correlation and causation isn’t academic — it’s about money.

Wasted Ad Spend — Optimizing for the wrong channels burns budget.

Wrong Product Decisions — Building features that don’t actually drive engagement.

Misattributed Credit — Giving credit to channels that aren’t working.

Failed Interventions — Changes that don’t move the needle.

With PyCausalSim, you can:

Test before you invest — Simulate interventions before deploying them

Stop wasting money — Find what actually drives results

Make confident decisions — Know the causal effect, not just correlation

Validate your assumptions — Built-in sensitivity analysis


Installation

Install directly from GitHub:

bash

pip install git+https://github.com/Bodhi8/pycausalsim.git

Or clone and install locally:

bash

git clone https://github.com/Bodhi8/pycausalsim.git
cd pycausalsim
pip install -e ".[dev]"

Dependencies: numpy, pandas, scipy, scikit-learn (core), plus matplotlib and networkx for visualization. Optional integrations with dowhy and econml.


What’s Next: Roadmap

v0.2.0 (Q2 2025) — Enhanced neural causal models, time-series causal discovery, improved visualization suite, and full DoWhy/EconML integration.

v0.3.0 (Q3 2025) — Agent-based simulation for network effects, real-time inference API, and causal reinforcement learning.

v1.0.0 (Q4 2025) — Production-ready with full test coverage, performance optimization, comprehensive documentation, and industry case studies.


Technical Foundation

PyCausalSim builds on decades of causal inference research:

Pearl’s Causality Framework — Structural causal models, do-calculus, and the causal hierarchy.

Potential Outcomes — Rubin causal model for treatment effect estimation.

Modern ML — Neural networks for causal discovery (NOTEARS, DAG-GNN).

Simulation — Monte Carlo methods for counterfactual estimation.

It integrates with the broader ecosystem including DoWhy (Microsoft), EconML (Microsoft), and CausalML (Uber).


Join the Causal Revolution

Data science is evolving. We’re moving beyond prediction to understanding:

Machine Learning asks “What will happen?”

Causal Inference asks “Why did it happen?”

PyCausalSim asks “What would happen if…?”

Stop guessing. Start simulating.


Resources

  • GitHub: github.com/Bodhi8/pycausalsim
  • Documentation: Coming soon at pycausalsim.readthedocs.io
  • Examples: Check the examples/ directory
  • Issues: Report bugs or request features on GitHub

Try It Today

bash

pip install git+https://github.com/Bodhi8/pycausalsim.git

python

from pycausalsim import CausalSimulator

# Your causal discovery journey starts here
simulator = CausalSimulator(data, target='your_outcome')
simulator.discover_graph()
effect = simulator.simulate_intervention('your_variable', new_value)
print(effect.summary())

Found this useful? Star the GitHub repo and share with your team!

Have questions? Open an issue or start a discussion on GitHub.


About the Author

Brian Curry is a Kansas City-based Data Scientist, AI expert, and founder of Vector1 Research, where he explores the frontier of Artificial Intelligence, Causal Inference, Agentic Systems, and Economic Modeling.

His work focuses on building intelligent systems that reveal the causal structures driving performance across marketing, content, and economics. He is the creator of PyCausalSim (causal discovery through simulation), Papilon (complex system optimization), Daedalus (causal and economic analysis), and Memory-Node Encapsulation (data structures for artificial episodic memory).

Contact: brian@vector1.ai


This article may be shared with attribution under Creative Commons Attribution 4.0 International (CC BY 4.0).

Tags: #CausalInference #DataScience #Python #MachineLearning #ABTesting #Analytics #Simulation #Causality #MarketingAttribution #UpliftModeling

Related research