CoolFace
Apppublic

jordancheney89/causality

sourceHugging Facemitupdated 3mo agoView on Hugging Face
0likes
App README

![Live Demo](https://jordancheney89-causality.hf.space/) ![Hugging Face Spaces](https://huggingface.co/spaces/jordancheney89/causality) ![License: MIT](LICENSE) ![Python](https://www.python.org/) ![uv](https://docs.astral.sh/uv/) ![Dash](https://dash.plotly.com/) ![PyMC](https://www.pymc.io/)

Causal Inference Dashboard

Interactive Dash app for comparing a suite of causal measurement approaches using a publicly available randomised marketing experiment as an example (Hillstrom, 2008).

Live demo: Hugging Face Space

This project provides a dashboard to:

  • โ€”estimate average treatment effects (ATE) with uncertainty
  • โ€”inspect heterogeneity and targeting value
  • โ€”show where each method agrees and disagrees, and what assumptions drive the result

What this dashboard shows

Teams might ask two different questions:

  • โ€”"Did the campaign work on average?" (causal effect / ATE)
  • โ€”"Who should we target next?" (HTE / uplift policy)

This dashboard puts both views side-by-side so the methodological choices and any business implications are easily comparable.

Methods Covered

TabMethodRole in this project
1OverviewDataset summary, arm balance, headline effects
2Bayesian A/B (PyMC hurdle model)Probabilistic effect estimation with posterior uncertainty
3Multi-Arm OLS with interactionsPrecision-adjusted average effects and subgroup patterns
4Uplift / HTE (S- and X-Learner)Ranking customers by estimated incremental value, X-learner is default
5PSM (propensity matching + caliper)Pedagogical: the workflow you'd use on observational data, run on this RCT for comparison
6Method ComparisonSide-by-side estimate reconciliation and takeaway

Dataset

Source: MineThatData Email Analytics (Hillstrom)

Randomised experiment across ~64,000 customers:

  • โ€”Men's, Women's and Control (split roughly equal-sized three ways)
  • โ€”Primary outcome: 2-week post-campaign spend (USD)
  • โ€”Key covariates: recency, history, mens/womens indicators, zip code, newbie, channel

Quick Start

Dependencies are managed with [uv](https://docs.astral.sh/uv/).

Requirements

  • โ€”uv installed
  • โ€”Python 3.13+

Install

From the project root:

bash
uv sync

This creates .venv (if needed) and installs the locked dependency set.

Run

bash
uv run app.py

Open http://localhost:8050.

First-run behavior

  • โ€”First run precomputes models and caches results in .cache/results.pkl.
  • โ€”Subsequent runs load from cache and start quickly.
  • โ€”Depending on machine speed, initial build can take several minutes.

Force recompute

  • โ€”Delete .cache/results.pkl, or set USE_CACHE = False in causal_utils.py.
  • โ€”Restart the app once to rebuild the cache.
  • โ€”Set USE_CACHE back to True after a deliberate rebuild (optional, deleting the pickle has the same effect if USE_CACHE stays True).

Hugging Face Spaces (Docker)

Live Space: huggingface.co/spaces/jordancheney89/causality

This repo includes a `Dockerfile` configured for the Docker Spaces SDK

Methodology Notes and Caveats

  • โ€”The underlying dataset is randomized, so causal identification of average effects comes from random assignment.
  • โ€”Covariate-adjusted analyses are included for precision and interpretability, propensity matching is included as a pedagogical workflow.
  • โ€”Average CATE is reported with a bootstrap interval, though that interval is estimation-conditional and reads as a lower bound on the true uncertainty for high-stakes targeting.
  • โ€”Propensity matching (PSM) is included as a demo workflow for non-randomised data, and isn't used as a headline estimate for this dashboard.

Results Snapshot

  • โ€”Men's email lifts two-week spend by about $0.77 per recipient (95% CI $0.50 to $1.05), Women's by about $0.42 ($0.17 to $0.67).
  • โ€”The methods agree: Bayesian, OLS and both uplift learners all land between $0.74 and $0.79 (Men's) and $0.42 and $0.45 (Women's).
  • โ€”The lift is a conversion effect. The emails roughly double the share of customers who buy (1.25% / 0.88% vs 0.57% in control) while spend per buyer stays around $114.
  • โ€”Both uplift rankings beat random targeting (permutation p < 0.002), and the policy view turns the ranking plus a send cost and margin into an optimal mailing share.

Project Structure

text
.
โ”œโ”€โ”€ Dockerfile             # Hugging Face Spaces (Docker SDK), gunicorn on port 7860
โ”œโ”€โ”€ .dockerignore          # Smaller build context (excludes .venv, caches of dev tools)
โ”œโ”€โ”€ app.py                 # Thin entrypoint: Dash app, theme registration, layout, callback wiring
โ”œโ”€โ”€ causal_utils.py        # Data prep, caching, and all causal estimation logic
โ”œโ”€โ”€ dashboard/
โ”‚   โ”œโ”€โ”€ theme.py           # Design tokens, Plotly template, shared style dicts
โ”‚   โ””โ”€โ”€ data.py            # Loads cache โ†’ exposes RESULTS, DF, PSM, BAYESIAN, UPLIFT, OLS
โ”œโ”€โ”€ pages/                 # Dash Pages route registration
โ”‚   โ”œโ”€โ”€ overview.py        # /
โ”‚   โ”œโ”€โ”€ bayesian.py        # /bayesian
โ”‚   โ”œโ”€โ”€ ols.py             # /ols
โ”‚   โ”œโ”€โ”€ uplift.py          # /uplift
โ”‚   โ”œโ”€โ”€ psm.py             # /psm
โ”‚   โ””โ”€โ”€ comparison.py      # /comparison
โ”œโ”€โ”€ layouts/
โ”‚   โ”œโ”€โ”€ shell.py           # Masthead + section nav + Dash Pages container
โ”‚   โ”œโ”€โ”€ components.py      # Reusable UI helpers
โ”‚   โ”œโ”€โ”€ overview.py        # Overview layout
โ”‚   โ”œโ”€โ”€ psm.py             # PSM layout
โ”‚   โ”œโ”€โ”€ bayesian.py        # Bayesian A/B layout
โ”‚   โ”œโ”€โ”€ uplift.py          # Uplift / HTE layout
โ”‚   โ”œโ”€โ”€ ols.py             # Multi-Arm OLS layout
โ”‚   โ””โ”€โ”€ comparison.py      # Method Comparison layout
โ”œโ”€โ”€ callbacks/
โ”‚   โ”œโ”€โ”€ __init__.py        # register_callbacks(app)
โ”‚   โ”œโ”€โ”€ psm.py             # PSM callbacks
โ”‚   โ”œโ”€โ”€ bayesian.py        # Bayesian A/B callbacks
โ”‚   โ”œโ”€โ”€ uplift.py          # Uplift / HTE callbacks
โ”‚   โ”œโ”€โ”€ ols.py             # Static OLS figure builder
โ”‚   โ””โ”€โ”€ comparison.py      # Method Comparison callbacks
โ”œโ”€โ”€ figures/
โ”‚   โ””โ”€โ”€ overview.py        # Static Plotly helpers for Overview tab
โ”œโ”€โ”€ content/
โ”‚   โ””โ”€โ”€ methodology.py     # Long-form copy separated from layout code
โ”œโ”€โ”€ assets/
โ”‚   โ””โ”€โ”€ style.css          # Global styles (Dash serves /assets automatically)
โ”œโ”€โ”€ .cache/                # Precomputed outputs (e.g. results.pkl)
โ”œโ”€โ”€ pyproject.toml
โ”œโ”€โ”€ uv.lock
โ”œโ”€โ”€ .python-version
โ””โ”€โ”€ README.md

Roadmap

  • โ€”Add data ingestion wizard

License

MIT. See LICENSE.