Skip to content

Add counterfactual terminology callouts to quasi-experimental notebooks#854

Open
drbenvincent wants to merge 11 commits intomainfrom
fix/852-counterfactual-terminology-callouts
Open

Add counterfactual terminology callouts to quasi-experimental notebooks#854
drbenvincent wants to merge 11 commits intomainfrom
fix/852-counterfactual-terminology-callouts

Conversation

@drbenvincent
Copy link
Copy Markdown
Contributor

@drbenvincent drbenvincent commented Mar 5, 2026

Summary

  • Adds an :::{admonition} callout to four quasi-experimental notebooks (interrupted_time_series, difference_in_differences, regression_discontinuity, excess_deaths) clarifying that "counterfactual" is used in the Rubin/potential outcomes sense and how this differs from Pearl's L3 unit-level counterfactuals
  • Fixes a misleading "famous do-operator" reference in excess_deaths.ipynb (the notebook does not use pm.do)
  • Fixes a pre-existing dtype bug in regression_discontinuity.ipynb (np.zeros/np.ones producing float64 instead of bool for the treated data container)
  • Adds bibliography entries for Rubin (1974), Imbens & Rubin (2015), and Pearl (2009, 2nd ed.)
  • Migrates two deprecated PyMC APIs encountered while re-executing on PyMC 5.28+:
    • pm.MutableDatapm.Data (difference_in_differences, excess_deaths)
    • model.add_coord(..., mutable=False)model.add_coord(...) (excess_deaths)
  • Re-executes all four notebooks via jupyter nbconvert --execute so outputs are nbformat-valid (the previous re-execute had stripped required name/metadata fields, which crashed myst-nb on Read the Docs)

Closes #852

Merge order: Merge #850 first, then this PR (#854). The callouts here cross-reference the label interventional_what_if_do_operator, which is created by #850. Merging #854 first will leave broken cross-references until #850 lands.

Changes Made

Each callout is tailored to the specific method:

  • ITS: Counterfactual as forecast extrapolating pre-intervention trends
  • DiD: Parallel trends assumption provides proxy for treated group's counterfactual
  • RDD: Quasi-random assignment near threshold approximates counterfactual
  • Excess deaths: Forecast from pre-COVID model (same pattern as ITS); also cross-references the ITS notebook

All callouts include references and cross-reference the interventional_what_if_do_operator notebook for the full L2/L3 distinction.

Test plan

  • Pre-commit hooks pass (black-jupyter, nbqa-isort, bibtex-tidy, jupytext, etc.)
  • Both .ipynb and .myst.md versions updated consistently
  • All four notebooks re-executed successfully on PyMC 5.28
  • Bibliography entries in correct alphabetical order
  • Existing code and narrative preserved
  • Read the Docs build passes (callouts render correctly in Sphinx/MyST)

Each of the four quasi-experimental notebooks (ITS, DiD, RDD, excess deaths)
now has an admonition callout clarifying that "counterfactual" is used in the
Rubin/potential outcomes sense, how this differs from Pearl's L3 unit-level
counterfactuals, and why the usage is appropriate. Also removes a misleading
do-operator reference from excess_deaths.ipynb and adds three bibliography
entries (Rubin 1974, Imbens & Rubin 2015, Pearl 2009).

Closes #852

Made-with: Cursor
@review-notebook-app
Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@drbenvincent drbenvincent marked this pull request as draft March 5, 2026 13:41
np.zeros/np.ones produce float64 by default, but the model's treated
container expects bool. Pass dtype=bool to match the original data type.

Made-with: Cursor
@drbenvincent drbenvincent marked this pull request as ready for review March 5, 2026 14:07
Anticipates PR #850 renaming counterfactuals_do_operator to
interventional_what_if_do_operator. Both PRs should merge together.

Made-with: Cursor
@NathanielF
Copy link
Copy Markdown
Contributor

The individual call out boxes seem like a good idea. But i don't think Pearl's actual terminology here is "out of the box" helpful. A couple of things: "Abductive inference" is better than "abduction" as it's less easy to confuse with kidnapping. Secondly i don't think "abductive inference" is a great description of what Pearl is doing here. Or at least if we use the term we need to unpack it a bit more. Something like Pearlian counterfactuals aim at Inference about the best explanation of individual action. These depends on a thorough estimate of each individual's response profile. To do this we need to estimate their precise error term and re-use it in downstream calculations.

" which require abduction — inferring unit-specific exogenous variables from observed data and then reasoning about what would have happened to that particular unit under a different action."

I think i'd just drop the abduction term and emphasise it's about unit-specific effects. So in these cases distinct from what we care about DiD etc...

Copy link
Copy Markdown
Contributor

@NathanielF NathanielF left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe drop or explain abduction a bit better why Pearlian counterfactuals are effectively not relevant

drbenvincent and others added 3 commits May 2, 2026 09:06
The previous re-execute (commits a71b4f7, 6bcfcba) produced nbformat-invalid
notebooks: stream outputs were missing the required `name` field and
display_data outputs were missing the required `metadata` field. This caused
myst-nb to crash on Read the Docs with `AttributeError: name` while reading
difference_in_differences.

Re-executes all four affected notebooks against a current PyMC env using
jupyter nbconvert, producing valid nbformat output. While re-executing,
migrates two deprecated APIs to keep the notebooks runnable on PyMC 5.28+:

- pm.MutableData -> pm.Data (DiD and excess_deaths)
- model.add_coord(..., mutable=False) -> model.add_coord(...) (excess_deaths)

The cross-references to interventional_what_if_do_operator and the L2/L3
counterfactual callouts added by this PR are preserved.

Co-authored-by: Cursor <cursoragent@cursor.com>
…t-level

Per review feedback, the previous wording leaned on Pearl's "abduction" /
Level 3 terminology to set up a contrast it then had to talk itself out of.
That framing was easy to misread and not a great description of what these
methods actually deliver.

Replaces the Pearl L2/L3 contrast paragraph with a single paragraph that
frames the distinction more directly: these quasi-experimental methods
target group-level average counterfactuals, which is distinct from
unit-level counterfactuals about a particular individual. Pearl's hierarchy
is mentioned only in passing, with the cross-reference to the
interventional_what_if_do_operator notebook preserved for readers who want
the formal treatment.

Applies the same revision to all four notebooks (DiD, ITS, RDD,
excess_deaths) and their .myst.md pairs.

Co-authored-by: Cursor <cursoragent@cursor.com>
@review-notebook-app
Copy link
Copy Markdown

review-notebook-app Bot commented May 4, 2026

View / edit / reply to this conversation on ReviewNB

aloctavodia commented on 2026-05-04T05:43:01Z
----------------------------------------------------------------

Maybe something like this

We rely on the parallel trends assumption, which states that in the absence of treatment, the treated and control groups would have followed the same trajectory over time. This allows us to use the control group's...


@review-notebook-app
Copy link
Copy Markdown

review-notebook-app Bot commented May 4, 2026

View / edit / reply to this conversation on ReviewNB

aloctavodia commented on 2026-05-04T05:43:03Z
----------------------------------------------------------------

... We extrapolate pre-intervention trends to predict the unobserved potential outcome Y(0): what would have happened, on average, without the intervention. This is a group-level counterfactual prediction, standard in the quasi-experimental literature.

This group-level counterfactual is distinct from a unit-level...


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add counterfactual terminology callouts to quasi-experimental notebooks

2 participants