Decision Intelligence Delivery
Putting causal estimates in front of decision-makers as tools they can use.
What you'll learn
- 1Days 71–73A versioned parameters file, a scenario API with FastAPI, scenario design and uncertainty for executives.
By the end: Students can package causal estimates as a versioned parameters file, serve a scenario simulator through a FastAPI service, design a scenario menu that refuses to extrapolate quietly, and describe uncertainty in words and pictures an executive can act on.
- 2Days 74–76The Streamlit simulator, counterfactual charts, tests, CI, a container and a smoke test.
By the end: Students can build a slider-driven scenario simulator in Streamlit, chart counterfactuals without misleading, test the engine, the API and the app automatically, and package the API for deployment with a smoke test.
- 3Days 77–80Monitoring for effect drift, when to re-run the experiment, and the final capstone defence.
By the end: Students can detect when causal estimates have gone stale, put a dollar value on re-estimating or re-testing, design the re-test, and carry a full decision cycle (monitor, rebuild, simulate, recommend, defend) on new data.
Tools
Mini-capstone
Annual pricing review: detect the drift, rebuild the parameters, run the scenario pack through the API and defend a recommendation against the truth.
The ten days
Before you start: module setup and project structure
Course: Applied Causal Inference & Decision Science Audience: Economists and analysts who completed Modules 1–7 Environment: GitHub Codespaces (VS Code in the browser) Time per day: ~5 hours (including breaks and exercises) Goal by end of Day 73: Students can package causal estimates as a versioned parameters file, serve a scenario simulator through a FastAPI service, design a scenario menu that refuses to extrapolate quietly, and describe uncertainty in words and pictures an executive can act on.
Where we are
Seven modules produced estimates: price elasticities per store segment and category (Module 6), and a coupon uplift curve (Module 7). They live in notebooks and scripts that only their author can run. Module 8 turns them into something the business uses every week: a scenario simulator. A category manager moves a price slider and sees projected profit next to the counterfactual (what happens if nothing changes), with an honest range.
| Days | Question | Tools |
|---|---|---|
| 71–73 | How do other people's programs and people use our estimates? | parameters file, FastAPI, pydantic, scenario presets, plain-language uncertainty |
| 74–76 | How do decision-makers use them, and how do we keep it working? | Streamlit, Altair, pytest, GitHub Actions, Docker |
| 77–80 | How do we know when the estimates are out of date? | rolling monitoring, CUSUM, value of information, final capstone |
The architecture, in one picture
data/*.csv ──► engine/build.py ──► models/causal_parameters.json ──► engine/simulate.py
(Modules 6–7 estimators) (versioned, committed) │
├──► service/app.py (FastAPI: other programs)
└──► app/streamlit_app.py (people)
The key design decision: estimation and simulation are separate. Estimation is slow (minutes of DoubleML and DR-learners) and runs when new data arrive. Simulation is fast (milliseconds of arithmetic) and runs every time someone moves a slider. Between them sits one small JSON file with a version string. Anyone can ask "which estimates produced this number?" and get a precise answer.
Setup
mkdir -p engine service app tests models day71 day72 day73 day74 day75 day76 day77 day78 day79 day80
touch engine/__init__.py service/__init__.py app/__init__.py tests/__init__.py
Three new packages. Add them to requirements.txt and install (pip install -r requirements.txt):
streamlit==1.66.1
pytest==9.2.0
httpx==0.28.1 # FastAPI's TestClient uses it
FastAPI, uvicorn and requests are already pinned from Module 1. Altair comes with Streamlit.
A small change to causalkit/demand.py. The simulator gains three optional arguments for Days 77–79: drift_week, drift_segment and drift_factor (from that week on, one segment's elasticities are multiplied by the factor), and price_test (a randomised price test in half of one segment's stores, which adds a price_test column). The hidden _elasticity column is now per row. With the defaults nothing changes: every earlier result is identical. Copy the updated file from the course repository.
What gets committed. Unlike earlier modules, models/causal_parameters.json is committed: it is small, it's the thing the app serves, and Git's history of it is the history of the business's beliefs. Data, figures and secrets stay out as before.