Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions docs/source/_extensions/strip_citation_labels.py

This file was deleted.

5 changes: 0 additions & 5 deletions docs/source/_static/custom.css

This file was deleted.

6 changes: 2 additions & 4 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from causalpy.version import __version__

sys.path.insert(0, os.path.abspath("../"))
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "_extensions"))


# Generate gallery before building docs
Expand Down Expand Up @@ -105,7 +104,6 @@ def generate_gallery():
"sphinx_sitemap",
"sphinx_togglebutton",
"sphinxext.rediraffe",
"strip_citation_labels",
]

# -- Redirects for renamed how-to notebooks (issue #840) --------------------
Expand Down Expand Up @@ -180,7 +178,7 @@ def generate_gallery():

# bibtex config
bibtex_bibfiles = ["references.bib"]
bibtex_default_style = "alpha"
bibtex_default_style = "unsrt"
bibtex_reference_style = "author_year"


Expand Down Expand Up @@ -240,7 +238,7 @@ def generate_gallery():

html_theme = "labs_sphinx_theme"
html_static_path = ["_static"]
html_css_files = ["custom.css", "gallery.css"]
html_css_files = ["gallery.css"]
html_extra_path = ["robots.txt"]
html_favicon = "_static/favicon_logo.png"
# Theme options are theme-specific and customize the look and feel of a theme
Expand Down
6 changes: 6 additions & 0 deletions docs/source/knowledgebase/design_notation.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,9 @@ From an analysis perspective, regression discontinuity designs are very similar
## Summary

This page has offered a brief overview of the tabular notation used to describe quasi-experimental designs. The notation is a useful tool for summarizing the design of a study, and can be used to help identify the strengths and limitations of a study design. But readers are strongly encouraged to consult the original sources when assessing the relative strengths and limitations of making causal claims under different quasi-experimental designs.

## References

:::{bibliography}
:filter: docname in docnames
:::
6 changes: 6 additions & 0 deletions docs/source/knowledgebase/estimands.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,9 @@ The descriptions above assume standard usage. Always consider what your specific
| Regression Discontinuity | Local treatment effect at cutoff | Prediction-based |

For methods not covered in detail here (IV, IPW, ANCOVA), see the respective notebook documentation, {doc}`quasi_dags` for identification, and the {doc}`glossary` for estimand definitions. Note that some of these methods have more limited implementation support in CausalPy---for example, IV does not yet have full `plot()` and `summary()` support, and IPW and ANCOVA are Bayesian-only.

## References

:::{bibliography}
:filter: docname in docnames
:::
1 change: 0 additions & 1 deletion docs/source/knowledgebase/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ structural_causal_models.ipynb
custom_pymc_models.ipynb
causal_video_resources
causal_written_resources
../references
:::
11 changes: 11 additions & 0 deletions docs/source/knowledgebase/quasi_dags.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,17 @@
"* $Y_0 \\to Y_1$ and $X \\to Y_1$ Past spend, tenure, and region predict future spend. \n",
"* $T \\to Y_1$ The discount may increase (or cannibalise) post-campaign sales."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
11 changes: 11 additions & 0 deletions docs/source/knowledgebase/structural_causal_models.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5144,6 +5144,17 @@
"source": [
"The results all indicate a positive effect on weight due to the quitting smoking. They vary slightly in the attributed effect but, interestingly even if we try to zero out the correlation between treatment and outcome the model still implies a higher effect than observed in the simpler regression model. The Bayes factor plots report that the alternative hypothesis $\\alpha \\neq 3.3$ is between 5 and 40 times more likely than the null hypothesis of $\\alpha = 3.3$. They also indicate the effect of Bayesian updating by the extent in which the posterior has transformed from the prior in each plot. Interestingly, these array of results suggests the treatment estimate is sensitive to the endogeneity correction. Allowing $\\rho \\neq 0$ increases the estimated effect (from ~5 to ~6). That means the joint model is using the estimated correlation between unobservables to further adjust the treatment coefficient beyond what the model with $\\rho = 0$ does. To top this off, the sign of the $\\rho$ estimate matters. When $\\rho$ is allowed to vary, the posterior estimate forces the correlation between treatment propensity and outcome measure negative. In other words, the propensity to quit is associated with _less weight gain_. By modelling this relationship as a correlation, the $\\alpha$ parameter is not forced to reflect this pattern, and the model can attribute a higher effect to the treatment intervention than we found with the OLS estimate. \n\n## Applying These Methods\n\nThe models demonstrated here are not recipes to be followed mechanically but frameworks for making structural assumptions explicit. Before fitting a Bayesian causal model to real data, ask yourself three questions:\n\n**First: Can I defend my causal structure theoretically?** Which variables do you believe are confounders, which are instruments, which are irrelevant? Write down your causal graph before writing down your priors. If you cannot justify exclusion restrictions through domain knowledge or institutional understanding, data-driven variable selection will not rescue you—it will merely dress speculation in statistical clothing.\n\n**Second: How sensitive are my conclusions to structural assumptions?** The confounding parameter $\\rho$ is rarely identified from observables alone. Vary your priors on ρ across plausible ranges and observe how your treatment effect estimate shifts. Fit models with normal priors, sparse priors, and theory-driven exclusions. If your causal conclusions are stable across specifications, they're robust. If they vary dramatically, that variation is real epistemic uncertainty and should be reported as such.\n\n**Third: Where have I placed flexibility, and why?** Automated variable selection and nonparametric methods are powerful tools, but flexibility in the outcome equation can absorb the causal effects you're trying to estimate. As we demonstrated with BART, sufficiently flexible outcome models learn total associations rather than structural parameters. Use flexibility in the treatment equation if needed, but keep the outcome equation constrained to interpretable causal parameters.\n\n## Conclusion\n\nThese questions point to what distinguishes structural modeling from purely associational approaches. When we specify a Bayesian causal model, we write down a probabilistic program that encodes our beliefs about how data are generated—which variables influence which, how uncertainty enters, what exclusions hold. Once fitted, the model becomes a working machine we can run forward under interventions, perturb in its assumptions, and interrogate for consequences. This executable character lets us simulate alternative worlds and test the coherence of our causal story, rather than merely report coefficients.\n\nThe virtue of treating causal models as probabilistic programs is twofold. First, it forces us to articulate our causal beliefs explicitly i.e. the graphical, functional, and stochastic components that make the model run. Second, it offers a disciplined way to explore what follows from those beliefs under uncertainty. Bayesian structural causal inference therefore unites an epistemic modesty with computational rigor: each model is a local, provisional machine for generating causal understanding, not a final map of the world.\n\nThe credibility revolution's achievement was recognizing that causal claims require more than correlations. Causal inference requires identification strategies. These strategies try to bracket complexity through design. Bayesian structural modeling takes a complementary path: it models complexity explicitly, then explores how robust our conclusions are to structural perturbations. Both approaches succeed when we know not only how our models work, but where they stop working. \n\nEvery causal model, like every fish tank, is a \"small world\" whose regularities we can nurture but never universalize. Our task is not to master the ocean, but to build clear tanks and learn when to change the water."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
11 changes: 11 additions & 0 deletions docs/source/notebooks/difference-in-differences-banks-pymc.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,17 @@
"\n",
"ETable([result1, result2, result3, result_twfe], coef_fmt=\"b:.3f\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
11 changes: 11 additions & 0 deletions docs/source/notebooks/geolift-single-cell.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,17 @@
"\n",
"ETable(result, coef_fmt=\"b:.3f\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
11 changes: 11 additions & 0 deletions docs/source/notebooks/instrumental-variables-pymc.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,17 @@
"\n",
"Like other techniques in causal inference, allot hinges on how plausible the initial DAG is for your circumstances and whether the nature of the confounding can be addressed by the technique. Instrumental variable regressions are popular and foundational in econometrics largely because the underlying pattern of confounding is so prevalent where we wish to examine the effect of policy interventions. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3200,6 +3200,18 @@
"As always in causal inference, the model is a question posed to the data. Variable selection priors help us ask that question more precisely, but we still need theory to tell us if we're asking the right question at all.\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "f0f53175",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3529,6 +3529,17 @@
"\n",
"More fundamentally, in IV we are estimating a __local__ average treatment effect, a different one for each set of compliers. As we vary instruments we vary the set of compliers. By default the problem posed is one of model-uncertainty - any single IV model only tells part of the story. Each can be argued for, but a clear picture of the effect of our treatment emerges only when our estimate is broadly consistent over multiple well motivated models. Credibility accrues more to the emerging literature than any single study, this is particularly true in the case of instrumental variable designs. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,17 @@
"%load_ext watermark\n",
"%watermark -n -u -v -iv -w -p causalpy,pymc,arviz"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,17 @@
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
11 changes: 11 additions & 0 deletions docs/source/notebooks/inverse-propensity-latent.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -4760,6 +4760,17 @@
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
11 changes: 11 additions & 0 deletions docs/source/notebooks/inverse-propensity-pymc.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,17 @@
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
12 changes: 12 additions & 0 deletions docs/source/notebooks/multi-cell-geolift.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1708,6 +1708,18 @@
"\n",
"Finally, we demonstrated how to extract the lift estimates in a format suitable for Media Mix Model (MMM) calibration using the `extract_lift_for_mmm()` helper function. This bridges the gap between CausalPy's geo-lift experiments and downstream MMM workflows in [PyMC-Marketing](https://github.com/pymc-labs/pymc-marketing).\n"
]
},
{
"cell_type": "markdown",
"id": "2a26821e",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
2 changes: 1 addition & 1 deletion docs/source/notebooks/panel-fixed-effects.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@
"cell_type": "markdown",
"id": "fa9a9f8b",
"metadata": {},
"source": "## Connection to Difference-in-Differences\n\nTwo-way fixed effects (TWFE) - with both unit and time fixed effects - is closely related to difference-in-differences (DiD).\n\nWith a simple 2x2 design (2 groups, 2 periods, binary treatment), TWFE produces **numerically identical** estimates to the classic DiD estimator. The model:\n\n$$Y_{it} = \\alpha_i + \\gamma_t + \\beta \\cdot D_{it} + \\epsilon_{it}$$\n\nwhere:\n- $\\alpha_i$ = unit fixed effects\n- $\\gamma_t$ = time fixed effects\n- $D_{it}$ = treatment indicator\n\nis a workhorse of applied causal inference. The coefficient $\\beta$ captures the treatment effect.\n\nWith more complex designs (staggered treatment adoption, heterogeneous effects), TWFE and simple DiD can diverge. Recent econometrics research {cite:p}`goodman2021difference,dechaisemartin2020twfe` has highlighted that TWFE can give misleading results when:\n\n1. **Treatment effects vary over time** (dynamic effects)\n2. **Treatment rolls out at different times** (staggered adoption)\n3. **Treatment effects differ across units** (heterogeneity)\n\nFor these cases, consider using CausalPy's `DifferenceInDifferences` class or newer estimators designed for staggered designs.\n\n:::{seealso}\nSee the [Difference-in-Differences notebook](difference-in-differences-pymc.ipynb) for more on DiD methods in CausalPy.\n:::\n"
"source": "## Connection to Difference-in-Differences\n\nTwo-way fixed effects (TWFE) - with both unit and time fixed effects - is closely related to difference-in-differences (DiD).\n\nWith a simple 2x2 design (2 groups, 2 periods, binary treatment), TWFE produces **numerically identical** estimates to the classic DiD estimator. The model:\n\n$$Y_{it} = \\alpha_i + \\gamma_t + \\beta \\cdot D_{it} + \\epsilon_{it}$$\n\nwhere:\n- $\\alpha_i$ = unit fixed effects\n- $\\gamma_t$ = time fixed effects\n- $D_{it}$ = treatment indicator\n\nis a workhorse of applied causal inference. The coefficient $\\beta$ captures the treatment effect.\n\nWith more complex designs (staggered treatment adoption, heterogeneous effects), TWFE and simple DiD can diverge. Recent econometrics research {cite:p}`goodmanbacon2021difference,dechaisemartin2020twfe` has highlighted that TWFE can give misleading results when:\n\n1. **Treatment effects vary over time** (dynamic effects)\n2. **Treatment rolls out at different times** (staggered adoption)\n3. **Treatment effects differ across units** (heterogeneity)\n\nFor these cases, consider using CausalPy's `DifferenceInDifferences` class or newer estimators designed for staggered designs.\n\n:::{seealso}\nSee the [Difference-in-Differences notebook](difference-in-differences-pymc.ipynb) for more on DiD methods in CausalPy.\n:::\n"
},
{
"cell_type": "markdown",
Expand Down
11 changes: 11 additions & 0 deletions docs/source/notebooks/piecewise-interrupted-time-series-pymc.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1480,6 +1480,17 @@
"source": [
"fig, ax = result6.plot()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
11 changes: 11 additions & 0 deletions docs/source/notebooks/regression-discontinuity-donut-pymc.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1692,6 +1692,17 @@
"\n",
"ETable([result_baseline, result_donut, result_combined], coef_fmt=\"b:.3f\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
11 changes: 11 additions & 0 deletions docs/source/notebooks/regression-discontinuity-drinking-pymc.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,17 @@
"\n",
"ETable([result, result2, result3], coef_fmt=\"b:.3f\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,17 @@
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
":::{bibliography}\n",
":filter: docname in docnames\n",
":::"
]
}
],
"metadata": {
Expand Down
Loading