σ StatsDoge Causal inference workflows
12
Workflow·4 steps·branched

Model, identify, estimate, refute — the DoWhy four-step recipe (DoWhy)

Source DoWhy — PyWhy / Microsoft (Sharma, Kiciman et al.)
Summary by StatsDoge

A causal-graph–first recipe: write down the DAG, let the algorithm read off the backdoor adjustment set, plug any estimator in, and end with refutation tests (placebo treatment, random common cause) that try to falsify your effect. The discipline is in step 4.

1

Input · what goes in

A dataset plus a causal graph (DAG) naming treatment, outcome, confounders and any instruments — the assumptions you're willing to defend.

Show data format & exampleHide example

Format — a tidy table together with a causal graph (DOT/GML) over treatment v0, outcome y and confounders W*.

import dowhy.datasets
d = dowhy.datasets.linear_dataset(
        beta=10, num_common_causes=5, num_instruments=1, num_samples=1000)
# d['df']: v0 (treatment), y (outcome), W0..W4 (confounders), X0
2

Pipeline · the recipe ⑂ has parallel branches

↑ Click any step in the diagram to read its logic, code, assumptions & discussion.

1
Data prep

Model — encode the causal graph

Data preparation — shapes the raw inputs into what the estimator expects.

What happens here

State the DAG over treatment, outcome, confounders and instruments. The assumptions go in up front, as a graph, not buried in a regression.

Formula
au=\mathbb{E}ig[Y\mid do(T{=}1)ig]-\mathbb{E}ig[Y\mid do(T{=}0)ig]
Reads from the input data Feeds into the final output
Key code
from dowhy import CausalModel
model = CausalModel(data=df, treatment='v0', outcome='y', graph=gml_graph)

Reference / docs ↗

Discussion on this step (0)
  • No comments on this step yet — be the first.
2
Diagnostic / pre-tests

Identify — apply the backdoor criterion

A pre-flight check — run this before trusting any estimate downstream.

What happens here

DoWhy searches the graph for a valid adjustment set (backdoor), or an instrument/front-door, and returns the estimand symbolically — before touching the data.

Formula
\mathbb{E}[Y\mid do(T{=}t)]=\sum_{w}\mathbb{E}[Y\mid T{=}t,\,W{=}w]\,P(W{=}w)
Reads from the input data Feeds into the final output
Key code
estimand = model.identify_effect(proceed_when_unidentifiable=False)

Reference / docs ↗

Discussion on this step (0)
  • No comments on this step yet — be the first.
3
Estimation

Estimate — adjust for the backdoor set

The core estimate — where the causal quantity itself is computed.

What happens here

Plug in any estimator for the identified estimand: linear adjustment, propensity weighting/matching, or a DML/forest backend.

Formula
\hat au= rac1n\sum_i\Big( rac{T_iY_i}{\hat e(W_i)}- rac{(1-T_i)Y_i}{1-\hat e(W_i)}\Big)
Reads from the input data Feeds into the final output
Key code
est = model.estimate_effect(estimand,
        method_name='backdoor.propensity_score_weighting')

Reference / docs ↗

Discussion on this step (0)
  • No comments on this step yet — be the first.
4
Robustness check

Refute — placebo & unobserved-confounder tests

A robustness check — does the headline result survive a different lens?

What happens here

The step that earns trust: a random common cause shouldn't change τ̂; a placebo (permuted) treatment should drive it to zero; subsetting shouldn't move it much.

Formula
\hat au_{ ext{rand.\ cause}}\approx\hat au,\qquad \hat au_{ ext{placebo}}\approx 0
Reads from the input data Feeds into the final output
Key code
model.refute_estimate(estimand, est,
        method_name='placebo_treatment_refuter')

Reference / docs ↗

Discussion on this step (0)
  • No comments on this step yet — be the first.
3

Output · what you get 2 figures

The assumed causal graph: confounders W0–W4 point into both the treatment v0 and the outcome y; DoWhy reads identifiability straight off this DAG.
Fig 1The assumed causal graph: confounders W0–W4 point into both the treatment v0 and the outcome y; DoWhy reads identifiability straight off this DAG.
Refutation — 'effect of an unobserved common cause': how the estimate shifts as a hypothetical confounder's strength on treatment and outcome grows.
Fig 2Refutation — 'effect of an unobserved common cause': how the estimate shifts as a hypothetical confounder's strength on treatment and outcome grows.

Figures reproduced from DoWhy — PyWhy / Microsoft (Sharma, Kiciman et al.) — unofficial community showcase; all credit to the original authors.

⚠️ Unofficial community showcase of dowhy. Not affiliated with the authors; all credit to them.

Make your assumptions explicit: draw a causal graph, identify the estimand by the backdoor criterion, estimate it, then actively try to refute it with placebo and confounding tests.

Discussion (2)

  • 2

    The refute step is what sells DoWhy to me — placebo and random-common-cause as a default habit, not an afterthought.

  • 1

    Encoding the DAG up front forces the awkward assumptions into the open. Wish more pipelines did this.

    1

    Exactly — identification before estimation. The backdoor set is a modelling decision, not a tuning knob.