CausalPy 0.8.0__tar.gz → 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {causalpy-0.8.0 → causalpy-0.9.0}/CausalPy.egg-info/PKG-INFO +121 -44
- {causalpy-0.8.0 → causalpy-0.9.0}/CausalPy.egg-info/SOURCES.txt +34 -9
- {causalpy-0.8.0 → causalpy-0.9.0}/CausalPy.egg-info/requires.txt +20 -8
- {causalpy-0.8.0 → causalpy-0.9.0}/PKG-INFO +121 -44
- causalpy-0.9.0/README.md +179 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/__init__.py +27 -1
- causalpy-0.9.0/causalpy/checks/__init__.py +54 -0
- causalpy-0.9.0/causalpy/checks/bandwidth.py +140 -0
- causalpy-0.9.0/causalpy/checks/base.py +135 -0
- causalpy-0.9.0/causalpy/checks/convex_hull.py +119 -0
- causalpy-0.9.0/causalpy/checks/leave_one_out.py +135 -0
- causalpy-0.9.0/causalpy/checks/mccrary.py +152 -0
- causalpy-0.9.0/causalpy/checks/outcome_falsification.py +387 -0
- causalpy-0.9.0/causalpy/checks/persistence.py +141 -0
- causalpy-0.9.0/causalpy/checks/placebo_in_space.py +152 -0
- causalpy-0.9.0/causalpy/checks/placebo_in_time.py +1048 -0
- causalpy-0.9.0/causalpy/checks/pre_treatment_placebo.py +124 -0
- causalpy-0.9.0/causalpy/checks/prior_sensitivity.py +171 -0
- causalpy-0.9.0/causalpy/constants.py +28 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/custom_exceptions.py +21 -3
- causalpy-0.9.0/causalpy/data/california_prop99.csv +32 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/datasets.py +62 -35
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/simulate_data.py +157 -116
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/experiments/__init__.py +5 -1
- causalpy-0.9.0/causalpy/experiments/base.py +545 -0
- causalpy-0.9.0/causalpy/experiments/diff_in_diff.py +701 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/experiments/instrumental_variable.py +146 -37
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/experiments/interrupted_time_series.py +532 -657
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/experiments/inverse_propensity_weighting.py +329 -64
- causalpy-0.9.0/causalpy/experiments/model_adapter.py +703 -0
- causalpy-0.9.0/causalpy/experiments/panel_regression.py +1026 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/experiments/piecewise_its.py +386 -408
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/experiments/prepostnegd.py +203 -71
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/experiments/regression_discontinuity.py +259 -176
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/experiments/regression_kink.py +206 -73
- causalpy-0.9.0/causalpy/experiments/staggered_did.py +1496 -0
- causalpy-0.9.0/causalpy/experiments/synthetic_control.py +904 -0
- causalpy-0.9.0/causalpy/experiments/synthetic_difference_in_differences.py +948 -0
- causalpy-0.9.0/causalpy/formula_utils.py +101 -0
- causalpy-0.9.0/causalpy/maketables_adapters.py +433 -0
- causalpy-0.9.0/causalpy/pipeline.py +216 -0
- causalpy-0.9.0/causalpy/plot_utils.py +490 -0
- causalpy-0.9.0/causalpy/pymc_forecast_models.py +442 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/pymc_models.py +662 -116
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/reporting.py +236 -181
- causalpy-0.9.0/causalpy/skills/__init__.py +20 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/skl_models.py +39 -15
- causalpy-0.9.0/causalpy/steps/__init__.py +25 -0
- causalpy-0.9.0/causalpy/steps/estimate_effect.py +131 -0
- causalpy-0.9.0/causalpy/steps/report.py +167 -0
- causalpy-0.9.0/causalpy/steps/sensitivity.py +221 -0
- causalpy-0.9.0/causalpy/templates/report.html +131 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/transforms.py +119 -24
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/utils.py +62 -20
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/variable_selection_priors.py +14 -8
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/version.py +2 -2
- {causalpy-0.8.0 → causalpy-0.9.0}/pyproject.toml +95 -31
- causalpy-0.9.0/scripts/_ast_introspection.py +142 -0
- causalpy-0.9.0/scripts/check_architecture_inventory.py +224 -0
- causalpy-0.9.0/scripts/check_public_exports.py +164 -0
- causalpy-0.9.0/scripts/check_rediraffe_redirects.py +242 -0
- causalpy-0.9.0/scripts/generate_gallery.py +330 -0
- causalpy-0.9.0/scripts/generate_plots.py +327 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/scripts/run_notebooks/runner.py +53 -10
- causalpy-0.9.0/scripts/validate_docstring_lists.py +129 -0
- causalpy-0.9.0/scripts/validate_notebooks.py +223 -0
- causalpy-0.8.0/README.md +0 -113
- causalpy-0.8.0/causalpy/data/ancova_generated.csv +0 -201
- causalpy-0.8.0/causalpy/data/did.csv +0 -41
- causalpy-0.8.0/causalpy/data/geolift1.csv +0 -209
- causalpy-0.8.0/causalpy/data/geolift_multi_cell.csv +0 -209
- causalpy-0.8.0/causalpy/data/gt_social_media_data.csv +0 -182
- causalpy-0.8.0/causalpy/data/its.csv +0 -121
- causalpy-0.8.0/causalpy/data/its_simple.csv +0 -121
- causalpy-0.8.0/causalpy/data/regression_discontinuity.csv +0 -101
- causalpy-0.8.0/causalpy/data/synthetic_control.csv +0 -101
- causalpy-0.8.0/causalpy/experiments/base.py +0 -197
- causalpy-0.8.0/causalpy/experiments/diff_in_diff.py +0 -607
- causalpy-0.8.0/causalpy/experiments/staggered_did.py +0 -968
- causalpy-0.8.0/causalpy/experiments/synthetic_control.py +0 -942
- causalpy-0.8.0/causalpy/plot_utils.py +0 -126
- causalpy-0.8.0/scripts/validate_notebooks.py +0 -126
- {causalpy-0.8.0 → causalpy-0.9.0}/CausalPy.egg-info/dependency_links.txt +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/CausalPy.egg-info/top_level.txt +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/LICENSE +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/AJR2001.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/GDP_in_dollars_billions.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/PISA18sampleScale.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/__init__.py +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/banks.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/data_nevo.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/deaths_and_temps_england_wales.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/drinking.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/lalonde.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/nets_df.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/nhefs.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/schoolingReturns.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/data/zipcodes_data.csv +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/causalpy/date_utils.py +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/scripts/run_notebooks/injected.py +0 -0
- {causalpy-0.8.0 → causalpy-0.9.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: CausalPy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: Causal inference for quasi-experiments in Python
|
|
5
5
|
Author-email: Ben Vincent <ben.vincent@pymc-labs.com>
|
|
6
6
|
License: Apache License
|
|
@@ -224,29 +224,34 @@ Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
|
224
224
|
Requires-Python: >=3.11
|
|
225
225
|
Description-Content-Type: text/markdown
|
|
226
226
|
License-File: LICENSE
|
|
227
|
-
Requires-Dist: arviz
|
|
227
|
+
Requires-Dist: arviz<1.0,>=0.14.0
|
|
228
228
|
Requires-Dist: graphviz
|
|
229
229
|
Requires-Dist: ipython!=8.7.0
|
|
230
|
+
Requires-Dist: jinja2
|
|
230
231
|
Requires-Dist: matplotlib>=3.5.3
|
|
231
|
-
Requires-Dist: numpy
|
|
232
|
+
Requires-Dist: numpy
|
|
232
233
|
Requires-Dist: pandas
|
|
233
234
|
Requires-Dist: patsy
|
|
234
|
-
Requires-Dist: pymc
|
|
235
|
+
Requires-Dist: pymc<6,>=5.15.1
|
|
236
|
+
Requires-Dist: pytensor<3,>=2.38.1
|
|
235
237
|
Requires-Dist: scikit-learn>=1
|
|
236
238
|
Requires-Dist: scipy
|
|
237
239
|
Requires-Dist: seaborn>=0.11.2
|
|
238
240
|
Requires-Dist: statsmodels
|
|
239
241
|
Requires-Dist: xarray>=v2022.11.0
|
|
240
242
|
Requires-Dist: pymc-extras>=0.3.0
|
|
243
|
+
Provides-Extra: forecast
|
|
244
|
+
Requires-Dist: pymc-forecast[extras]<0.3,>=0.2; extra == "forecast"
|
|
241
245
|
Provides-Extra: dev
|
|
242
|
-
Requires-Dist:
|
|
246
|
+
Requires-Dist: prek; extra == "dev"
|
|
243
247
|
Requires-Dist: twine; extra == "dev"
|
|
244
|
-
Requires-Dist: interrogate; extra == "dev"
|
|
245
248
|
Requires-Dist: codespell; extra == "dev"
|
|
246
249
|
Requires-Dist: nbformat; extra == "dev"
|
|
247
250
|
Requires-Dist: nbconvert; extra == "dev"
|
|
251
|
+
Requires-Dist: PyYAML; extra == "dev"
|
|
248
252
|
Provides-Extra: docs
|
|
249
253
|
Requires-Dist: ipykernel; extra == "docs"
|
|
254
|
+
Requires-Dist: maketables; extra == "docs"
|
|
250
255
|
Requires-Dist: pymc-marketing>=0.13.1; extra == "docs"
|
|
251
256
|
Requires-Dist: daft-pgm; extra == "docs"
|
|
252
257
|
Requires-Dist: linkify-it-py; extra == "docs"
|
|
@@ -261,52 +266,86 @@ Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
|
261
266
|
Requires-Dist: sphinx-rtd-theme; extra == "docs"
|
|
262
267
|
Requires-Dist: sphinx-sitemap; extra == "docs"
|
|
263
268
|
Requires-Dist: statsmodels; extra == "docs"
|
|
264
|
-
Requires-Dist: sphinxcontrib-bibtex; extra == "docs"
|
|
269
|
+
Requires-Dist: sphinxcontrib-bibtex>=2.7.0; extra == "docs"
|
|
265
270
|
Requires-Dist: sphinx-notfound-page; extra == "docs"
|
|
266
271
|
Requires-Dist: ipywidgets; extra == "docs"
|
|
267
272
|
Requires-Dist: sphinx-design; extra == "docs"
|
|
268
273
|
Requires-Dist: sphinx-togglebutton; extra == "docs"
|
|
274
|
+
Requires-Dist: nbformat; extra == "docs"
|
|
275
|
+
Requires-Dist: nbconvert; extra == "docs"
|
|
276
|
+
Requires-Dist: Pillow; extra == "docs"
|
|
277
|
+
Requires-Dist: PyYAML; extra == "docs"
|
|
278
|
+
Requires-Dist: sphinxext-rediraffe; extra == "docs"
|
|
269
279
|
Provides-Extra: lint
|
|
270
|
-
Requires-Dist:
|
|
271
|
-
Requires-Dist: pre-commit; extra == "lint"
|
|
280
|
+
Requires-Dist: prek; extra == "lint"
|
|
272
281
|
Requires-Dist: ruff; extra == "lint"
|
|
273
282
|
Requires-Dist: mypy; extra == "lint"
|
|
274
283
|
Provides-Extra: test
|
|
275
284
|
Requires-Dist: pytest; extra == "test"
|
|
276
285
|
Requires-Dist: pytest-cov; extra == "test"
|
|
286
|
+
Requires-Dist: diff-cover; extra == "test"
|
|
277
287
|
Requires-Dist: codespell; extra == "test"
|
|
278
288
|
Requires-Dist: nbformat; extra == "test"
|
|
279
289
|
Requires-Dist: nbconvert; extra == "test"
|
|
280
290
|
Requires-Dist: papermill; extra == "test"
|
|
291
|
+
Requires-Dist: pymc-forecast[extras]<0.3,>=0.2; extra == "test"
|
|
281
292
|
Dynamic: license-file
|
|
282
293
|
|
|
283
294
|
<div align="center">
|
|
284
|
-
<a href="https://github.com/pymc-labs/CausalPy"><img width="
|
|
295
|
+
<a href="https://github.com/pymc-labs/CausalPy"><img width="40%" src="https://raw.githubusercontent.com/pymc-labs/CausalPy/main/docs/source/_static/logo.png"></a>
|
|
285
296
|
</div>
|
|
286
297
|
|
|
287
298
|
----
|
|
288
299
|
|
|
300
|
+
[](https://badge.fury.io/py/CausalPy)
|
|
301
|
+
[](https://anaconda.org/conda-forge/causalpy)
|
|
302
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
303
|
+
|
|
289
304
|

|
|
290
305
|
[](https://github.com/astral-sh/ruff)
|
|
291
|
-
[](https://github.com/pre-commit/pre-commit)
|
|
307
|
+
[](https://codecov.io/gh/pymc-labs/CausalPy)
|
|
308
|
+
|
|
309
|
+

|
|
293
310
|

|
|
311
|
+
[](https://pepy.tech/project/causalpy)
|
|
294
312
|

|
|
295
|
-

|
|
296
|
-
[](https://codecov.io/gh/pymc-labs/CausalPy)
|
|
297
313
|
|
|
298
|
-
|
|
314
|
+
<!-- docs-start -->
|
|
315
|
+
|
|
316
|
+
# Causal Inference for Quasi-Experiments
|
|
317
|
+
|
|
318
|
+
**Research-grade causal inference workflows** for quasi-experimental designs in Python.
|
|
319
|
+
|
|
320
|
+
CausalPy helps you estimate causal effects with transparent assumptions, uncertainty-aware modeling, and reproducible outputs:
|
|
321
|
+
|
|
322
|
+
- **Quasi-experimental methods:** Difference-in-differences, synthetic control, regression discontinuity, interrupted time series, instrumental variables, and more
|
|
323
|
+
- **Bayesian-first estimation** via [PyMC](https://www.pymc.io/) with full uncertainty quantification, plus traditional OLS via [scikit-learn](https://scikit-learn.org)
|
|
324
|
+
- **Decision-ready outputs:** Effect summaries with credible intervals (HDI), practical significance (ROPE), and publication-quality plots
|
|
299
325
|
|
|
300
|
-
|
|
326
|
+
## 📞 [**Book a consulting call**](https://calendly.com/benjamin-vincent/causalpy)
|
|
327
|
+
|
|
328
|
+
CausalPy is built and maintained by [PyMC Labs](https://www.pymc-labs.com). If your team is exploring a consulting engagement for lift testing, complex or high-stakes causal work, you can book an introductory call. _These calls are for consulting inquiries only. For technical usage questions and free community support, please use GitHub Discussions and the documentation below._
|
|
329
|
+
|
|
330
|
+
## Help and documentation
|
|
331
|
+
|
|
332
|
+
- Ask usage questions in [GitHub Discussions Q&A](https://github.com/pymc-labs/CausalPy/discussions/categories/q-a) so the issue tracker stays focused on bugs and enhancements.
|
|
333
|
+
- Report bugs and feature requests in [Issues](https://github.com/pymc-labs/CausalPy/issues)
|
|
334
|
+
- Browse detailed guides in the [documentation](https://causalpy.readthedocs.io)
|
|
301
335
|
|
|
302
336
|
## Installation
|
|
303
337
|
|
|
304
338
|
To get the latest release:
|
|
339
|
+
|
|
305
340
|
```bash
|
|
306
341
|
pip install CausalPy
|
|
307
342
|
```
|
|
308
343
|
|
|
309
|
-
|
|
344
|
+
or via conda:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
conda install causalpy -c conda-forge
|
|
348
|
+
```
|
|
310
349
|
|
|
311
350
|
Alternatively, if you want the very latest version of the package you can install from GitHub:
|
|
312
351
|
|
|
@@ -314,6 +353,10 @@ Alternatively, if you want the very latest version of the package you can instal
|
|
|
314
353
|
pip install git+https://github.com/pymc-labs/CausalPy.git
|
|
315
354
|
```
|
|
316
355
|
|
|
356
|
+
## AI Agent Skills
|
|
357
|
+
|
|
358
|
+
CausalPy includes agent skills that teach AI coding assistants how to use the library for causal inference. Skills are available via [Decision AI Hub](https://hub.decision.ai) and live in `causalpy/skills/` in the source tree.
|
|
359
|
+
|
|
317
360
|
## Quickstart
|
|
318
361
|
|
|
319
362
|
```python
|
|
@@ -325,7 +368,7 @@ df = (
|
|
|
325
368
|
cp.load_data("drinking")
|
|
326
369
|
.rename(columns={"agecell": "age"})
|
|
327
370
|
.assign(treated=lambda df_: df_.age > 21)
|
|
328
|
-
|
|
371
|
+
)
|
|
329
372
|
|
|
330
373
|
# Run the analysis
|
|
331
374
|
result = cp.RegressionDiscontinuity(
|
|
@@ -334,32 +377,52 @@ result = cp.RegressionDiscontinuity(
|
|
|
334
377
|
running_variable_name="age",
|
|
335
378
|
model=cp.pymc_models.LinearRegression(),
|
|
336
379
|
treatment_threshold=21,
|
|
337
|
-
|
|
380
|
+
)
|
|
338
381
|
|
|
339
|
-
# Visualize
|
|
340
|
-
fig, ax = result.plot()
|
|
382
|
+
# Visualize the causal effect at the threshold
|
|
383
|
+
fig, ax = result.plot()
|
|
341
384
|
|
|
342
|
-
# Get a results summary
|
|
385
|
+
# Get a results summary with posterior estimates
|
|
343
386
|
result.summary()
|
|
344
|
-
|
|
345
|
-
plt.show()
|
|
346
387
|
```
|
|
347
388
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
Plans for the repository can be seen in the [Issues](https://github.com/pymc-labs/CausalPy/issues).
|
|
389
|
+
The `result.plot()` visualizes the regression discontinuity design, showing the estimated jump at the treatment threshold. The `result.summary()` prints posterior estimates of the causal effect with uncertainty intervals.
|
|
351
390
|
|
|
352
391
|
## Videos
|
|
392
|
+
|
|
353
393
|
Click on the thumbnail below to watch a video about CausalPy on YouTube.
|
|
394
|
+
|
|
354
395
|
[](https://www.youtube.com/watch?v=gV6wzTk3o1U)
|
|
355
396
|
|
|
356
|
-
##
|
|
397
|
+
## When CausalPy is a good fit
|
|
398
|
+
|
|
399
|
+
- You have a plausible quasi-experimental design (threshold rule, policy change, staggered rollout, geo lift, etc.)
|
|
400
|
+
- You want uncertainty-aware estimates and diagnostics, not only point estimates
|
|
401
|
+
- You need reproducible analysis artifacts for review and communication
|
|
402
|
+
|
|
403
|
+
## When CausalPy is not a fit
|
|
404
|
+
|
|
405
|
+
- You need causal discovery from weakly identified observational data
|
|
406
|
+
- You want fully automated "black box" causal answers without specifying assumptions
|
|
407
|
+
- You primarily need production workflow tooling (pipelines, governance, multi-user collaboration)
|
|
408
|
+
|
|
409
|
+
## Methods and Workflows
|
|
357
410
|
|
|
358
|
-
CausalPy
|
|
411
|
+
CausalPy provides methods for common causal inference decision contexts:
|
|
359
412
|
|
|
360
|
-
|
|
|
413
|
+
| Decision context | Methods |
|
|
414
|
+
|------------------|---------|
|
|
415
|
+
| Focussed testing on certain units (geos, products) | Synthetic control, Geographical lift |
|
|
416
|
+
| Evaluate before/after changes, launches, policy changes | Differences in Differences, Staggered DiD, Interrupted time series |
|
|
417
|
+
| Exploit cutoff rules, score-based eligibility (credit, age) | Regression discontinuity, Regression kink |
|
|
418
|
+
| Can't randomize, correct for selection | Instrumental variables, Inverse propensity weighting |
|
|
419
|
+
| Group differences, control for covariates | ANCOVA |
|
|
420
|
+
|
|
421
|
+
### Available methods
|
|
422
|
+
|
|
423
|
+
| Method | Description |
|
|
361
424
|
|-|-|
|
|
362
|
-
| Synthetic control | Constructs a synthetic version of the treatment group from a weighted combination of control units. Used for causal inference in comparative case studies when a single unit is treated, and there are multiple control units
|
|
425
|
+
| Synthetic control | Constructs a synthetic version of the treatment group from a weighted combination of control units. Used for causal inference in comparative case studies when a single unit is treated, and there are multiple control units. |
|
|
363
426
|
| Geographical lift | Measures the impact of an intervention in a specific geographic area by comparing it to similar areas without the intervention. Commonly used in marketing to assess regional campaigns. |
|
|
364
427
|
| ANCOVA | Analysis of Covariance combines ANOVA and regression to control for the effects of one or more quantitative covariates. Used when comparing group means while controlling for other variables. |
|
|
365
428
|
| Differences in Differences | Compares the changes in outcomes over time between a treatment group and a control group. Used in observational studies to estimate causal effects by accounting for time trends. |
|
|
@@ -370,26 +433,40 @@ CausalPy has a broad range of quasi-experimental methods for causal inference:
|
|
|
370
433
|
| Instrumental variable regression | Addresses endogeneity by using an instrument variable that is correlated with the endogenous explanatory variable but uncorrelated with the error term. Used when explanatory variables are correlated with the error term, providing consistent estimates of causal effects. |
|
|
371
434
|
| Inverse Propensity Score Weighting | Weights observations by the inverse of the probability of receiving the treatment. Used in causal inference to create a synthetic sample where the treatment assignment is independent of measured covariates, helping to adjust for confounding variables in observational studies. |
|
|
372
435
|
|
|
373
|
-
##
|
|
436
|
+
## Diagnostics-first by design
|
|
374
437
|
|
|
375
|
-
|
|
438
|
+
CausalPy emphasizes transparent, uncertainty-aware outputs for rigorous causal analysis:
|
|
376
439
|
|
|
377
|
-
|
|
440
|
+
- **Effect summaries:** Every experiment provides `effect_summary()` returning decision-ready statistics with both tabular and prose formats
|
|
441
|
+
- **Uncertainty quantification:** Bayesian models report HDI (Highest Density Intervals); OLS models report confidence intervals
|
|
442
|
+
- **Practical significance:** ROPE (Region of Practical Equivalence) analysis to assess whether effects exceed meaningful thresholds
|
|
443
|
+
- **Direction testing:** Tail probabilities (e.g., P(effect > 0)) for directional inference
|
|
378
444
|
|
|
379
|
-
##
|
|
445
|
+
## Citing CausalPy
|
|
380
446
|
|
|
381
|
-
|
|
447
|
+
If you use CausalPy in your research, please cite it. A Zenodo DOI for stable releases is planned. In the meantime, you can cite the repository:
|
|
382
448
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
449
|
+
```bibtex
|
|
450
|
+
@software{causalpy,
|
|
451
|
+
author = {{PyMC Labs}},
|
|
452
|
+
title = {CausalPy: Causal inference for quasi-experiments in Python},
|
|
453
|
+
url = {https://github.com/pymc-labs/CausalPy},
|
|
454
|
+
year = {2026}
|
|
455
|
+
}
|
|
456
|
+
```
|
|
386
457
|
|
|
387
|
-
|
|
458
|
+
## Roadmap
|
|
459
|
+
|
|
460
|
+
Plans for the repository can be seen in the [Issues](https://github.com/pymc-labs/CausalPy/issues).
|
|
461
|
+
|
|
462
|
+
## License
|
|
388
463
|
|
|
389
|
-
|
|
464
|
+
[Apache License 2.0](https://github.com/pymc-labs/CausalPy/blob/main/LICENSE)
|
|
390
465
|
|
|
391
|
-
|
|
466
|
+
## Thanks to our contributors
|
|
392
467
|
|
|
393
|
-
|
|
468
|
+
<a href="https://github.com/pymc-labs/CausalPy/graphs/contributors">
|
|
469
|
+
<img src="https://raw.githubusercontent.com/pymc-labs/CausalPy/main/docs/source/_static/contributors.svg" alt="CausalPy contributors" />
|
|
470
|
+
</a>
|
|
394
471
|
|
|
395
|
-
|
|
472
|
+
The contributor image is regenerated weekly by a GitHub Actions workflow (`.github/workflows/contributors.yml`) that opens a PR when the contributor list changes.
|
|
@@ -7,9 +7,14 @@ CausalPy.egg-info/dependency_links.txt
|
|
|
7
7
|
CausalPy.egg-info/requires.txt
|
|
8
8
|
CausalPy.egg-info/top_level.txt
|
|
9
9
|
causalpy/__init__.py
|
|
10
|
+
causalpy/constants.py
|
|
10
11
|
causalpy/custom_exceptions.py
|
|
11
12
|
causalpy/date_utils.py
|
|
13
|
+
causalpy/formula_utils.py
|
|
14
|
+
causalpy/maketables_adapters.py
|
|
15
|
+
causalpy/pipeline.py
|
|
12
16
|
causalpy/plot_utils.py
|
|
17
|
+
causalpy/pymc_forecast_models.py
|
|
13
18
|
causalpy/pymc_models.py
|
|
14
19
|
causalpy/reporting.py
|
|
15
20
|
causalpy/skl_models.py
|
|
@@ -17,29 +22,33 @@ causalpy/transforms.py
|
|
|
17
22
|
causalpy/utils.py
|
|
18
23
|
causalpy/variable_selection_priors.py
|
|
19
24
|
causalpy/version.py
|
|
25
|
+
causalpy/checks/__init__.py
|
|
26
|
+
causalpy/checks/bandwidth.py
|
|
27
|
+
causalpy/checks/base.py
|
|
28
|
+
causalpy/checks/convex_hull.py
|
|
29
|
+
causalpy/checks/leave_one_out.py
|
|
30
|
+
causalpy/checks/mccrary.py
|
|
31
|
+
causalpy/checks/outcome_falsification.py
|
|
32
|
+
causalpy/checks/persistence.py
|
|
33
|
+
causalpy/checks/placebo_in_space.py
|
|
34
|
+
causalpy/checks/placebo_in_time.py
|
|
35
|
+
causalpy/checks/pre_treatment_placebo.py
|
|
36
|
+
causalpy/checks/prior_sensitivity.py
|
|
20
37
|
causalpy/data/AJR2001.csv
|
|
21
38
|
causalpy/data/GDP_in_dollars_billions.csv
|
|
22
39
|
causalpy/data/PISA18sampleScale.csv
|
|
23
40
|
causalpy/data/__init__.py
|
|
24
|
-
causalpy/data/ancova_generated.csv
|
|
25
41
|
causalpy/data/banks.csv
|
|
42
|
+
causalpy/data/california_prop99.csv
|
|
26
43
|
causalpy/data/data_nevo.csv
|
|
27
44
|
causalpy/data/datasets.py
|
|
28
45
|
causalpy/data/deaths_and_temps_england_wales.csv
|
|
29
|
-
causalpy/data/did.csv
|
|
30
46
|
causalpy/data/drinking.csv
|
|
31
|
-
causalpy/data/geolift1.csv
|
|
32
|
-
causalpy/data/geolift_multi_cell.csv
|
|
33
|
-
causalpy/data/gt_social_media_data.csv
|
|
34
|
-
causalpy/data/its.csv
|
|
35
|
-
causalpy/data/its_simple.csv
|
|
36
47
|
causalpy/data/lalonde.csv
|
|
37
48
|
causalpy/data/nets_df.csv
|
|
38
49
|
causalpy/data/nhefs.csv
|
|
39
|
-
causalpy/data/regression_discontinuity.csv
|
|
40
50
|
causalpy/data/schoolingReturns.csv
|
|
41
51
|
causalpy/data/simulate_data.py
|
|
42
|
-
causalpy/data/synthetic_control.csv
|
|
43
52
|
causalpy/data/zipcodes_data.csv
|
|
44
53
|
causalpy/experiments/__init__.py
|
|
45
54
|
causalpy/experiments/base.py
|
|
@@ -47,12 +56,28 @@ causalpy/experiments/diff_in_diff.py
|
|
|
47
56
|
causalpy/experiments/instrumental_variable.py
|
|
48
57
|
causalpy/experiments/interrupted_time_series.py
|
|
49
58
|
causalpy/experiments/inverse_propensity_weighting.py
|
|
59
|
+
causalpy/experiments/model_adapter.py
|
|
60
|
+
causalpy/experiments/panel_regression.py
|
|
50
61
|
causalpy/experiments/piecewise_its.py
|
|
51
62
|
causalpy/experiments/prepostnegd.py
|
|
52
63
|
causalpy/experiments/regression_discontinuity.py
|
|
53
64
|
causalpy/experiments/regression_kink.py
|
|
54
65
|
causalpy/experiments/staggered_did.py
|
|
55
66
|
causalpy/experiments/synthetic_control.py
|
|
67
|
+
causalpy/experiments/synthetic_difference_in_differences.py
|
|
68
|
+
causalpy/skills/__init__.py
|
|
69
|
+
causalpy/steps/__init__.py
|
|
70
|
+
causalpy/steps/estimate_effect.py
|
|
71
|
+
causalpy/steps/report.py
|
|
72
|
+
causalpy/steps/sensitivity.py
|
|
73
|
+
causalpy/templates/report.html
|
|
74
|
+
scripts/_ast_introspection.py
|
|
75
|
+
scripts/check_architecture_inventory.py
|
|
76
|
+
scripts/check_public_exports.py
|
|
77
|
+
scripts/check_rediraffe_redirects.py
|
|
78
|
+
scripts/generate_gallery.py
|
|
79
|
+
scripts/generate_plots.py
|
|
80
|
+
scripts/validate_docstring_lists.py
|
|
56
81
|
scripts/validate_notebooks.py
|
|
57
82
|
scripts/run_notebooks/injected.py
|
|
58
83
|
scripts/run_notebooks/runner.py
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
arviz
|
|
1
|
+
arviz<1.0,>=0.14.0
|
|
2
2
|
graphviz
|
|
3
3
|
ipython!=8.7.0
|
|
4
|
+
jinja2
|
|
4
5
|
matplotlib>=3.5.3
|
|
5
|
-
numpy
|
|
6
|
+
numpy
|
|
6
7
|
pandas
|
|
7
8
|
patsy
|
|
8
|
-
pymc
|
|
9
|
+
pymc<6,>=5.15.1
|
|
10
|
+
pytensor<3,>=2.38.1
|
|
9
11
|
scikit-learn>=1
|
|
10
12
|
scipy
|
|
11
13
|
seaborn>=0.11.2
|
|
@@ -14,15 +16,16 @@ xarray>=v2022.11.0
|
|
|
14
16
|
pymc-extras>=0.3.0
|
|
15
17
|
|
|
16
18
|
[dev]
|
|
17
|
-
|
|
19
|
+
prek
|
|
18
20
|
twine
|
|
19
|
-
interrogate
|
|
20
21
|
codespell
|
|
21
22
|
nbformat
|
|
22
23
|
nbconvert
|
|
24
|
+
PyYAML
|
|
23
25
|
|
|
24
26
|
[docs]
|
|
25
27
|
ipykernel
|
|
28
|
+
maketables
|
|
26
29
|
pymc-marketing>=0.13.1
|
|
27
30
|
daft-pgm
|
|
28
31
|
linkify-it-py
|
|
@@ -37,22 +40,31 @@ sphinx-copybutton
|
|
|
37
40
|
sphinx-rtd-theme
|
|
38
41
|
sphinx-sitemap
|
|
39
42
|
statsmodels
|
|
40
|
-
sphinxcontrib-bibtex
|
|
43
|
+
sphinxcontrib-bibtex>=2.7.0
|
|
41
44
|
sphinx-notfound-page
|
|
42
45
|
ipywidgets
|
|
43
46
|
sphinx-design
|
|
44
47
|
sphinx-togglebutton
|
|
48
|
+
nbformat
|
|
49
|
+
nbconvert
|
|
50
|
+
Pillow
|
|
51
|
+
PyYAML
|
|
52
|
+
sphinxext-rediraffe
|
|
53
|
+
|
|
54
|
+
[forecast]
|
|
55
|
+
pymc-forecast[extras]<0.3,>=0.2
|
|
45
56
|
|
|
46
57
|
[lint]
|
|
47
|
-
|
|
48
|
-
pre-commit
|
|
58
|
+
prek
|
|
49
59
|
ruff
|
|
50
60
|
mypy
|
|
51
61
|
|
|
52
62
|
[test]
|
|
53
63
|
pytest
|
|
54
64
|
pytest-cov
|
|
65
|
+
diff-cover
|
|
55
66
|
codespell
|
|
56
67
|
nbformat
|
|
57
68
|
nbconvert
|
|
58
69
|
papermill
|
|
70
|
+
pymc-forecast[extras]<0.3,>=0.2
|