Repository files navigation


BuildCode style: blackPyPI versionGitHub Repo starsRead the DocsPyPI - DownloadsInterrogatecodecov

CausalPy

A Python package focussing on causal inference in quasi-experimental settings. The package allows for sophisticated Bayesian model fitting methods to be used in addition to traditional OLS.

STATUS: Feel free to explore and experiment with the repository, and we very much welcome feedback (via Issues). But be aware that this code is very alpha! Expect the codebase and API to change for a while, so it is not appropriate to rely on this package for in-production or research pipelines.

Comparison to related packages

Rather than focussing on one particular quasi-experimental setting, this package aims to have broad applicability.

Another distinctive feature of this package is the ability to use different models. Currently, users can fit with scikit-learn models or Bayesian models with PyMC.

CausalImpact from GoogleGeoLift from MetaCausalPy from PyMC Labs
Synthetic control
Regression discontinuity
Difference in differences
LanguageR (but see tfcausalimpact)RPython
ModelsBayesian structural timeseriesAugmented synthetic controlFlexible: Traditional OLS and Bayesian models

Installation

To get the latest release:

pip install CausalPy

Alternatively, if you want the very latest version of the package you can install from GitHub:

pip install git+https://github.com/pymc-labs/CausalPy.git

Quickstart

importcausalpyascp# Import and process datadf= (
cp.load_data("drinking")
.rename(columns={"agecell": "age"})
.assign(treated=lambdadf_: df_.age>21)
)
# Run the analysisresult=cp.pymc_experiments.RegressionDiscontinuity(
df,
formula="all ~ 1 + age + treated",
running_variable_name="age",
model=cp.pymc_models.LinearRegression(),
treatment_threshold=21,
)
# Visualize outputsfig, ax=result.plot();
# Get a results summaryresult.summary()

Roadmap

Plans for the repository can be seen in the Issues.

Videos

Click on the thumbnail below to watch a video about CausalPy on YouTube. Youtube video thumbnail image

Overview of package capabilities

Synthetic control

This is appropriate when you have multiple units, one of which is treated. You build a synthetic control as a weighted combination of the untreated units.

TimeOutcomeControl 1Control 2Control 3
0$y_0$$x_{1,0}$$x_{2,0}$$x_{3,0}$
1$y_1$$x_{1,1}$$x_{2,1}$$x_{3,1}$
$\ldots$$\ldots$$\ldots$$\ldots$$\ldots$
T$y_T$$x_{1,T}$$x_{2,T}$$x_{3,T}$
FrequentistBayesian

The data (treated and untreated units), pre-treatment model fit, and counterfactual (i.e. the synthetic control) are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Geographical lift (Geolift)

We can also use synthetic control methods to analyse data from geographical lift studies. For example, we can try to evaluate the causal impact of an intervention (e.g. a marketing campaign) run in one geographical area by using control geographical areas which are similar to the intervention area but which did not recieve the specific marketing intervention.

ANCOVA

This is appropriate for non-equivalent group designs when you have a single pre and post intervention measurement and have a treament and a control group.

Groupprepost
0$x_1$$y_1$
0$x_2$$y_2$
1$x_3$$y_3$
1$x_4$$y_4$
FrequentistBayesian
coming soon

The data from the control and treatment group are plotted, along with posterior predictive 94% credible intervals. The lower panel shows the estimated treatment effect.

Difference in Differences

This is appropriate for non-equivalent group designs when you have pre and post intervention measurement and have a treament and a control group. Unlike the ANCOVA approach, difference in differences is appropriate when there are multiple pre and/or post treatment measurements.

Data is expected to be in the following form. Shown are just two units - one in the treated group (group=1) and one in the untreated group (group=0), but there can of course be multiple units per group. This is panel data (also known as repeated measures) where each unit is measured at 2 time points.

UnitTimeGroupOutcome
000$y_{0,0}$
010$y_{0,0}$
101$y_{1,0}$
111$y_{1,1}$
FrequentistBayesian

The data, model fit, and counterfactual are plotted. Frequentist model fits result in points estimates, but the Bayesian analysis results in posterior distributions, represented by the violin plots. The causal impact is the difference between the counterfactual prediction (treated group, post treatment) and the observed values for the treated group, post treatment.

Regression discontinuity designs

Regression discontinuity designs are used when treatment is applied to units according to a cutoff on the running variable (e.g. $x$) which is typically not time. By looking for the presence of a discontinuity at the precise point of the treatment cutoff then we can make causal claims about the potential impact of the treatment.

Running variableOutcomeTreated
$x_0$$y_0$False
$x_1$$y_0$False
$\ldots$$\ldots$$\ldots$
$x_{N-1}$$y_{N-1}$True
$x_N$$y_N$True
FrequentistBayesian

The data, model fit, and counterfactual are plotted (top). Frequentist analysis shows the causal impact with the blue shaded region, but this is not shown in the Bayesian analysis to avoid a cluttered chart. Instead, the Bayesian analysis shows shaded Bayesian credible regions of the model fits. The Frequentist analysis visualises the point estimate of the causal impact, but the Bayesian analysis also plots the posterior distribution of the regression discontinuity effect (bottom).

Interrupted time series

Interrupted time series analysis is appropriate when you have a time series of observations which undergo treatment at a particular point in time. This kind of analysis has no control group and looks for the presence of a change in the outcome measure at or soon after the treatment time. Multiple predictors can be included.

TimeOutcomeTreatedPredictor
$t_0$$y_0$False$x_0$
$t_1$$y_0$False$x_1$
$\ldots$$\ldots$$\ldots$$\ldots$
$t_{N-1}$$y_{N-1}$True$x_{N-1}$
$t_N$$y_N$True$x_N$
FrequentistBayesian
coming soon

The data, pre-treatment model fit, and counterfactual are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Learning resources

Here are some general resources about causal inference:

  • The official PyMC examples gallery has a set of examples specifically relating to causal inference.
  • Angrist, J. D., & Pischke, J. S. (2009). Mostly harmless econometrics: An empiricist's companion. Princeton university press.
  • Angrist, J. D., & Pischke, J. S. (2014). Mastering'metrics: The path from cause to effect. Princeton university press.
  • Cunningham, S. (2021). Causal inference: The Mixtape. Yale University Press.
  • Huntington-Klein, N. (2021). The effect: An introduction to research design and causality. Chapman and Hall/CRC.
  • Reichardt, C. S. (2019). Quasi-experimentation: A guide to design and analysis. Guilford Publications.

License

Apache License 2.0


Support

This repository is supported by PyMC Labs.

If you are interested in seeing what PyMC Labs can do for you, then please email ben.vincent@pymc-labs.io. We work with companies at a variety of scales and with varying levels of existing modeling capacity. We also run corporate workshop training events and can provide sessions ranging from introduction to Bayes to more advanced topics.

About

A Python package for causal inference in quasi-experimental settings

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation


BuildCode style: blackPyPI versionGitHub Repo starsRead the DocsPyPI - DownloadsInterrogatecodecov

CausalPy

A Python package focussing on causal inference in quasi-experimental settings. The package allows for sophisticated Bayesian model fitting methods to be used in addition to traditional OLS.

STATUS: Feel free to explore and experiment with the repository, and we very much welcome feedback (via Issues). But be aware that this code is very alpha! Expect the codebase and API to change for a while, so it is not appropriate to rely on this package for in-production or research pipelines.

Comparison to related packages

Rather than focussing on one particular quasi-experimental setting, this package aims to have broad applicability.

Another distinctive feature of this package is the ability to use different models. Currently, users can fit with scikit-learn models or Bayesian models with PyMC.

CausalImpact from GoogleGeoLift from MetaCausalPy from PyMC Labs
Synthetic control
Regression discontinuity
Difference in differences
LanguageR (but see tfcausalimpact)RPython
ModelsBayesian structural timeseriesAugmented synthetic controlFlexible: Traditional OLS and Bayesian models

Installation

To get the latest release:

pip install CausalPy

Alternatively, if you want the very latest version of the package you can install from GitHub:

pip install git+https://github.com/pymc-labs/CausalPy.git

Quickstart

importcausalpyascp# Import and process datadf= (
cp.load_data("drinking")
.rename(columns={"agecell": "age"})
.assign(treated=lambdadf_: df_.age>21)
)
# Run the analysisresult=cp.pymc_experiments.RegressionDiscontinuity(
df,
formula="all ~ 1 + age + treated",
running_variable_name="age",
model=cp.pymc_models.LinearRegression(),
treatment_threshold=21,
)
# Visualize outputsfig, ax=result.plot();
# Get a results summaryresult.summary()

Roadmap

Plans for the repository can be seen in the Issues.

Videos

Click on the thumbnail below to watch a video about CausalPy on YouTube. Youtube video thumbnail image

Overview of package capabilities

Synthetic control

This is appropriate when you have multiple units, one of which is treated. You build a synthetic control as a weighted combination of the untreated units.

TimeOutcomeControl 1Control 2Control 3
0$y_0$$x_{1,0}$$x_{2,0}$$x_{3,0}$
1$y_1$$x_{1,1}$$x_{2,1}$$x_{3,1}$
$\ldots$$\ldots$$\ldots$$\ldots$$\ldots$
T$y_T$$x_{1,T}$$x_{2,T}$$x_{3,T}$
FrequentistBayesian

The data (treated and untreated units), pre-treatment model fit, and counterfactual (i.e. the synthetic control) are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Geographical lift (Geolift)

We can also use synthetic control methods to analyse data from geographical lift studies. For example, we can try to evaluate the causal impact of an intervention (e.g. a marketing campaign) run in one geographical area by using control geographical areas which are similar to the intervention area but which did not recieve the specific marketing intervention.

ANCOVA

This is appropriate for non-equivalent group designs when you have a single pre and post intervention measurement and have a treament and a control group.

Groupprepost
0$x_1$$y_1$
0$x_2$$y_2$
1$x_3$$y_3$
1$x_4$$y_4$
FrequentistBayesian
coming soon

The data from the control and treatment group are plotted, along with posterior predictive 94% credible intervals. The lower panel shows the estimated treatment effect.

Difference in Differences

This is appropriate for non-equivalent group designs when you have pre and post intervention measurement and have a treament and a control group. Unlike the ANCOVA approach, difference in differences is appropriate when there are multiple pre and/or post treatment measurements.

Data is expected to be in the following form. Shown are just two units - one in the treated group (group=1) and one in the untreated group (group=0), but there can of course be multiple units per group. This is panel data (also known as repeated measures) where each unit is measured at 2 time points.

UnitTimeGroupOutcome
000$y_{0,0}$
010$y_{0,0}$
101$y_{1,0}$
111$y_{1,1}$
FrequentistBayesian

The data, model fit, and counterfactual are plotted. Frequentist model fits result in points estimates, but the Bayesian analysis results in posterior distributions, represented by the violin plots. The causal impact is the difference between the counterfactual prediction (treated group, post treatment) and the observed values for the treated group, post treatment.

Regression discontinuity designs

Regression discontinuity designs are used when treatment is applied to units according to a cutoff on the running variable (e.g. $x$) which is typically not time. By looking for the presence of a discontinuity at the precise point of the treatment cutoff then we can make causal claims about the potential impact of the treatment.

Running variableOutcomeTreated
$x_0$$y_0$False
$x_1$$y_0$False
$\ldots$$\ldots$$\ldots$
$x_{N-1}$$y_{N-1}$True
$x_N$$y_N$True
FrequentistBayesian

The data, model fit, and counterfactual are plotted (top). Frequentist analysis shows the causal impact with the blue shaded region, but this is not shown in the Bayesian analysis to avoid a cluttered chart. Instead, the Bayesian analysis shows shaded Bayesian credible regions of the model fits. The Frequentist analysis visualises the point estimate of the causal impact, but the Bayesian analysis also plots the posterior distribution of the regression discontinuity effect (bottom).

Interrupted time series

Interrupted time series analysis is appropriate when you have a time series of observations which undergo treatment at a particular point in time. This kind of analysis has no control group and looks for the presence of a change in the outcome measure at or soon after the treatment time. Multiple predictors can be included.

TimeOutcomeTreatedPredictor
$t_0$$y_0$False$x_0$
$t_1$$y_0$False$x_1$
$\ldots$$\ldots$$\ldots$$\ldots$
$t_{N-1}$$y_{N-1}$True$x_{N-1}$
$t_N$$y_N$True$x_N$
FrequentistBayesian
coming soon

The data, pre-treatment model fit, and counterfactual are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Learning resources

Here are some general resources about causal inference:

  • The official PyMC examples gallery has a set of examples specifically relating to causal inference.
  • Angrist, J. D., & Pischke, J. S. (2009). Mostly harmless econometrics: An empiricist's companion. Princeton university press.
  • Angrist, J. D., & Pischke, J. S. (2014). Mastering'metrics: The path from cause to effect. Princeton university press.
  • Cunningham, S. (2021). Causal inference: The Mixtape. Yale University Press.
  • Huntington-Klein, N. (2021). The effect: An introduction to research design and causality. Chapman and Hall/CRC.
  • Reichardt, C. S. (2019). Quasi-experimentation: A guide to design and analysis. Guilford Publications.

License

Apache License 2.0


Support

This repository is supported by PyMC Labs.

If you are interested in seeing what PyMC Labs can do for you, then please email ben.vincent@pymc-labs.io. We work with companies at a variety of scales and with varying levels of existing modeling capacity. We also run corporate workshop training events and can provide sessions ranging from introduction to Bayes to more advanced topics.

About

A Python package for causal inference in quasi-experimental settings

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation


BuildCode style: blackPyPI versionGitHub Repo starsRead the DocsPyPI - DownloadsInterrogatecodecov

CausalPy

A Python package focussing on causal inference in quasi-experimental settings. The package allows for sophisticated Bayesian model fitting methods to be used in addition to traditional OLS.

STATUS: Feel free to explore and experiment with the repository, and we very much welcome feedback (via Issues). But be aware that this code is very alpha! Expect the codebase and API to change for a while, so it is not appropriate to rely on this package for in-production or research pipelines.

Comparison to related packages

Rather than focussing on one particular quasi-experimental setting, this package aims to have broad applicability.

Another distinctive feature of this package is the ability to use different models. Currently, users can fit with scikit-learn models or Bayesian models with PyMC.

CausalImpact from GoogleGeoLift from MetaCausalPy from PyMC Labs
Synthetic control
Regression discontinuity
Difference in differences
LanguageR (but see tfcausalimpact)RPython
ModelsBayesian structural timeseriesAugmented synthetic controlFlexible: Traditional OLS and Bayesian models

Installation

To get the latest release:

pip install CausalPy

Alternatively, if you want the very latest version of the package you can install from GitHub:

pip install git+https://github.com/pymc-labs/CausalPy.git

Quickstart

importcausalpyascp# Import and process datadf= (
cp.load_data("drinking")
.rename(columns={"agecell": "age"})
.assign(treated=lambdadf_: df_.age>21)
)
# Run the analysisresult=cp.pymc_experiments.RegressionDiscontinuity(
df,
formula="all ~ 1 + age + treated",
running_variable_name="age",
model=cp.pymc_models.LinearRegression(),
treatment_threshold=21,
)
# Visualize outputsfig, ax=result.plot();
# Get a results summaryresult.summary()

Roadmap

Plans for the repository can be seen in the Issues.

Videos

Click on the thumbnail below to watch a video about CausalPy on YouTube. Youtube video thumbnail image

Overview of package capabilities

Synthetic control

This is appropriate when you have multiple units, one of which is treated. You build a synthetic control as a weighted combination of the untreated units.

TimeOutcomeControl 1Control 2Control 3
0$y_0$$x_{1,0}$$x_{2,0}$$x_{3,0}$
1$y_1$$x_{1,1}$$x_{2,1}$$x_{3,1}$
$\ldots$$\ldots$$\ldots$$\ldots$$\ldots$
T$y_T$$x_{1,T}$$x_{2,T}$$x_{3,T}$
FrequentistBayesian

The data (treated and untreated units), pre-treatment model fit, and counterfactual (i.e. the synthetic control) are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Geographical lift (Geolift)

We can also use synthetic control methods to analyse data from geographical lift studies. For example, we can try to evaluate the causal impact of an intervention (e.g. a marketing campaign) run in one geographical area by using control geographical areas which are similar to the intervention area but which did not recieve the specific marketing intervention.

ANCOVA

This is appropriate for non-equivalent group designs when you have a single pre and post intervention measurement and have a treament and a control group.

Groupprepost
0$x_1$$y_1$
0$x_2$$y_2$
1$x_3$$y_3$
1$x_4$$y_4$
FrequentistBayesian
coming soon

The data from the control and treatment group are plotted, along with posterior predictive 94% credible intervals. The lower panel shows the estimated treatment effect.

Difference in Differences

This is appropriate for non-equivalent group designs when you have pre and post intervention measurement and have a treament and a control group. Unlike the ANCOVA approach, difference in differences is appropriate when there are multiple pre and/or post treatment measurements.

Data is expected to be in the following form. Shown are just two units - one in the treated group (group=1) and one in the untreated group (group=0), but there can of course be multiple units per group. This is panel data (also known as repeated measures) where each unit is measured at 2 time points.

UnitTimeGroupOutcome
000$y_{0,0}$
010$y_{0,0}$
101$y_{1,0}$
111$y_{1,1}$
FrequentistBayesian

The data, model fit, and counterfactual are plotted. Frequentist model fits result in points estimates, but the Bayesian analysis results in posterior distributions, represented by the violin plots. The causal impact is the difference between the counterfactual prediction (treated group, post treatment) and the observed values for the treated group, post treatment.

Regression discontinuity designs

Regression discontinuity designs are used when treatment is applied to units according to a cutoff on the running variable (e.g. $x$) which is typically not time. By looking for the presence of a discontinuity at the precise point of the treatment cutoff then we can make causal claims about the potential impact of the treatment.

Running variableOutcomeTreated
$x_0$$y_0$False
$x_1$$y_0$False
$\ldots$$\ldots$$\ldots$
$x_{N-1}$$y_{N-1}$True
$x_N$$y_N$True
FrequentistBayesian

The data, model fit, and counterfactual are plotted (top). Frequentist analysis shows the causal impact with the blue shaded region, but this is not shown in the Bayesian analysis to avoid a cluttered chart. Instead, the Bayesian analysis shows shaded Bayesian credible regions of the model fits. The Frequentist analysis visualises the point estimate of the causal impact, but the Bayesian analysis also plots the posterior distribution of the regression discontinuity effect (bottom).

Interrupted time series

Interrupted time series analysis is appropriate when you have a time series of observations which undergo treatment at a particular point in time. This kind of analysis has no control group and looks for the presence of a change in the outcome measure at or soon after the treatment time. Multiple predictors can be included.

TimeOutcomeTreatedPredictor
$t_0$$y_0$False$x_0$
$t_1$$y_0$False$x_1$
$\ldots$$\ldots$$\ldots$$\ldots$
$t_{N-1}$$y_{N-1}$True$x_{N-1}$
$t_N$$y_N$True$x_N$
FrequentistBayesian
coming soon

The data, pre-treatment model fit, and counterfactual are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Learning resources

Here are some general resources about causal inference:

  • The official PyMC examples gallery has a set of examples specifically relating to causal inference.
  • Angrist, J. D., & Pischke, J. S. (2009). Mostly harmless econometrics: An empiricist's companion. Princeton university press.
  • Angrist, J. D., & Pischke, J. S. (2014). Mastering'metrics: The path from cause to effect. Princeton university press.
  • Cunningham, S. (2021). Causal inference: The Mixtape. Yale University Press.
  • Huntington-Klein, N. (2021). The effect: An introduction to research design and causality. Chapman and Hall/CRC.
  • Reichardt, C. S. (2019). Quasi-experimentation: A guide to design and analysis. Guilford Publications.

License

Apache License 2.0


Support

This repository is supported by PyMC Labs.

If you are interested in seeing what PyMC Labs can do for you, then please email ben.vincent@pymc-labs.io. We work with companies at a variety of scales and with varying levels of existing modeling capacity. We also run corporate workshop training events and can provide sessions ranging from introduction to Bayes to more advanced topics.

About

A Python package for causal inference in quasi-experimental settings

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation


BuildCode style: blackPyPI versionGitHub Repo starsRead the DocsPyPI - DownloadsInterrogatecodecov

CausalPy

A Python package focussing on causal inference in quasi-experimental settings. The package allows for sophisticated Bayesian model fitting methods to be used in addition to traditional OLS.

STATUS: Feel free to explore and experiment with the repository, and we very much welcome feedback (via Issues). But be aware that this code is very alpha! Expect the codebase and API to change for a while, so it is not appropriate to rely on this package for in-production or research pipelines.

Comparison to related packages

Rather than focussing on one particular quasi-experimental setting, this package aims to have broad applicability.

Another distinctive feature of this package is the ability to use different models. Currently, users can fit with scikit-learn models or Bayesian models with PyMC.

CausalImpact from GoogleGeoLift from MetaCausalPy from PyMC Labs
Synthetic control
Regression discontinuity
Difference in differences
LanguageR (but see tfcausalimpact)RPython
ModelsBayesian structural timeseriesAugmented synthetic controlFlexible: Traditional OLS and Bayesian models

Installation

To get the latest release:

pip install CausalPy

Alternatively, if you want the very latest version of the package you can install from GitHub:

pip install git+https://github.com/pymc-labs/CausalPy.git

Quickstart

importcausalpyascp# Import and process datadf= (
cp.load_data("drinking")
.rename(columns={"agecell": "age"})
.assign(treated=lambdadf_: df_.age>21)
)
# Run the analysisresult=cp.pymc_experiments.RegressionDiscontinuity(
df,
formula="all ~ 1 + age + treated",
running_variable_name="age",
model=cp.pymc_models.LinearRegression(),
treatment_threshold=21,
)
# Visualize outputsfig, ax=result.plot();
# Get a results summaryresult.summary()

Roadmap

Plans for the repository can be seen in the Issues.

Videos

Click on the thumbnail below to watch a video about CausalPy on YouTube. Youtube video thumbnail image

Overview of package capabilities

Synthetic control

This is appropriate when you have multiple units, one of which is treated. You build a synthetic control as a weighted combination of the untreated units.

TimeOutcomeControl 1Control 2Control 3
0$y_0$$x_{1,0}$$x_{2,0}$$x_{3,0}$
1$y_1$$x_{1,1}$$x_{2,1}$$x_{3,1}$
$\ldots$$\ldots$$\ldots$$\ldots$$\ldots$
T$y_T$$x_{1,T}$$x_{2,T}$$x_{3,T}$
FrequentistBayesian

The data (treated and untreated units), pre-treatment model fit, and counterfactual (i.e. the synthetic control) are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Geographical lift (Geolift)

We can also use synthetic control methods to analyse data from geographical lift studies. For example, we can try to evaluate the causal impact of an intervention (e.g. a marketing campaign) run in one geographical area by using control geographical areas which are similar to the intervention area but which did not recieve the specific marketing intervention.

ANCOVA

This is appropriate for non-equivalent group designs when you have a single pre and post intervention measurement and have a treament and a control group.

Groupprepost
0$x_1$$y_1$
0$x_2$$y_2$
1$x_3$$y_3$
1$x_4$$y_4$
FrequentistBayesian
coming soon

The data from the control and treatment group are plotted, along with posterior predictive 94% credible intervals. The lower panel shows the estimated treatment effect.

Difference in Differences

This is appropriate for non-equivalent group designs when you have pre and post intervention measurement and have a treament and a control group. Unlike the ANCOVA approach, difference in differences is appropriate when there are multiple pre and/or post treatment measurements.

Data is expected to be in the following form. Shown are just two units - one in the treated group (group=1) and one in the untreated group (group=0), but there can of course be multiple units per group. This is panel data (also known as repeated measures) where each unit is measured at 2 time points.

UnitTimeGroupOutcome
000$y_{0,0}$
010$y_{0,0}$
101$y_{1,0}$
111$y_{1,1}$
FrequentistBayesian

The data, model fit, and counterfactual are plotted. Frequentist model fits result in points estimates, but the Bayesian analysis results in posterior distributions, represented by the violin plots. The causal impact is the difference between the counterfactual prediction (treated group, post treatment) and the observed values for the treated group, post treatment.

Regression discontinuity designs

Regression discontinuity designs are used when treatment is applied to units according to a cutoff on the running variable (e.g. $x$) which is typically not time. By looking for the presence of a discontinuity at the precise point of the treatment cutoff then we can make causal claims about the potential impact of the treatment.

Running variableOutcomeTreated
$x_0$$y_0$False
$x_1$$y_0$False
$\ldots$$\ldots$$\ldots$
$x_{N-1}$$y_{N-1}$True
$x_N$$y_N$True
FrequentistBayesian

The data, model fit, and counterfactual are plotted (top). Frequentist analysis shows the causal impact with the blue shaded region, but this is not shown in the Bayesian analysis to avoid a cluttered chart. Instead, the Bayesian analysis shows shaded Bayesian credible regions of the model fits. The Frequentist analysis visualises the point estimate of the causal impact, but the Bayesian analysis also plots the posterior distribution of the regression discontinuity effect (bottom).

Interrupted time series

Interrupted time series analysis is appropriate when you have a time series of observations which undergo treatment at a particular point in time. This kind of analysis has no control group and looks for the presence of a change in the outcome measure at or soon after the treatment time. Multiple predictors can be included.

TimeOutcomeTreatedPredictor
$t_0$$y_0$False$x_0$
$t_1$$y_0$False$x_1$
$\ldots$$\ldots$$\ldots$$\ldots$
$t_{N-1}$$y_{N-1}$True$x_{N-1}$
$t_N$$y_N$True$x_N$
FrequentistBayesian
coming soon

The data, pre-treatment model fit, and counterfactual are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Learning resources

Here are some general resources about causal inference:

  • The official PyMC examples gallery has a set of examples specifically relating to causal inference.
  • Angrist, J. D., & Pischke, J. S. (2009). Mostly harmless econometrics: An empiricist's companion. Princeton university press.
  • Angrist, J. D., & Pischke, J. S. (2014). Mastering'metrics: The path from cause to effect. Princeton university press.
  • Cunningham, S. (2021). Causal inference: The Mixtape. Yale University Press.
  • Huntington-Klein, N. (2021). The effect: An introduction to research design and causality. Chapman and Hall/CRC.
  • Reichardt, C. S. (2019). Quasi-experimentation: A guide to design and analysis. Guilford Publications.

License

Apache License 2.0


Support

This repository is supported by PyMC Labs.

If you are interested in seeing what PyMC Labs can do for you, then please email ben.vincent@pymc-labs.io. We work with companies at a variety of scales and with varying levels of existing modeling capacity. We also run corporate workshop training events and can provide sessions ranging from introduction to Bayes to more advanced topics.

About

A Python package for causal inference in quasi-experimental settings

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation


BuildCode style: blackPyPI versionGitHub Repo starsRead the DocsPyPI - DownloadsInterrogatecodecov

CausalPy

A Python package focussing on causal inference in quasi-experimental settings. The package allows for sophisticated Bayesian model fitting methods to be used in addition to traditional OLS.

STATUS: Feel free to explore and experiment with the repository, and we very much welcome feedback (via Issues). But be aware that this code is very alpha! Expect the codebase and API to change for a while, so it is not appropriate to rely on this package for in-production or research pipelines.

Comparison to related packages

Rather than focussing on one particular quasi-experimental setting, this package aims to have broad applicability.

Another distinctive feature of this package is the ability to use different models. Currently, users can fit with scikit-learn models or Bayesian models with PyMC.

CausalImpact from GoogleGeoLift from MetaCausalPy from PyMC Labs
Synthetic control
Regression discontinuity
Difference in differences
LanguageR (but see tfcausalimpact)RPython
ModelsBayesian structural timeseriesAugmented synthetic controlFlexible: Traditional OLS and Bayesian models

Installation

To get the latest release:

pip install CausalPy

Alternatively, if you want the very latest version of the package you can install from GitHub:

pip install git+https://github.com/pymc-labs/CausalPy.git

Quickstart

importcausalpyascp# Import and process datadf= (
cp.load_data("drinking")
.rename(columns={"agecell": "age"})
.assign(treated=lambdadf_: df_.age>21)
)
# Run the analysisresult=cp.pymc_experiments.RegressionDiscontinuity(
df,
formula="all ~ 1 + age + treated",
running_variable_name="age",
model=cp.pymc_models.LinearRegression(),
treatment_threshold=21,
)
# Visualize outputsfig, ax=result.plot();
# Get a results summaryresult.summary()

Roadmap

Plans for the repository can be seen in the Issues.

Videos

Click on the thumbnail below to watch a video about CausalPy on YouTube. Youtube video thumbnail image

Overview of package capabilities

Synthetic control

This is appropriate when you have multiple units, one of which is treated. You build a synthetic control as a weighted combination of the untreated units.

TimeOutcomeControl 1Control 2Control 3
0$y_0$$x_{1,0}$$x_{2,0}$$x_{3,0}$
1$y_1$$x_{1,1}$$x_{2,1}$$x_{3,1}$
$\ldots$$\ldots$$\ldots$$\ldots$$\ldots$
T$y_T$$x_{1,T}$$x_{2,T}$$x_{3,T}$
FrequentistBayesian

The data (treated and untreated units), pre-treatment model fit, and counterfactual (i.e. the synthetic control) are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Geographical lift (Geolift)

We can also use synthetic control methods to analyse data from geographical lift studies. For example, we can try to evaluate the causal impact of an intervention (e.g. a marketing campaign) run in one geographical area by using control geographical areas which are similar to the intervention area but which did not recieve the specific marketing intervention.

ANCOVA

This is appropriate for non-equivalent group designs when you have a single pre and post intervention measurement and have a treament and a control group.

Groupprepost
0$x_1$$y_1$
0$x_2$$y_2$
1$x_3$$y_3$
1$x_4$$y_4$
FrequentistBayesian
coming soon

The data from the control and treatment group are plotted, along with posterior predictive 94% credible intervals. The lower panel shows the estimated treatment effect.

Difference in Differences

This is appropriate for non-equivalent group designs when you have pre and post intervention measurement and have a treament and a control group. Unlike the ANCOVA approach, difference in differences is appropriate when there are multiple pre and/or post treatment measurements.

Data is expected to be in the following form. Shown are just two units - one in the treated group (group=1) and one in the untreated group (group=0), but there can of course be multiple units per group. This is panel data (also known as repeated measures) where each unit is measured at 2 time points.

UnitTimeGroupOutcome
000$y_{0,0}$
010$y_{0,0}$
101$y_{1,0}$
111$y_{1,1}$
FrequentistBayesian

The data, model fit, and counterfactual are plotted. Frequentist model fits result in points estimates, but the Bayesian analysis results in posterior distributions, represented by the violin plots. The causal impact is the difference between the counterfactual prediction (treated group, post treatment) and the observed values for the treated group, post treatment.

Regression discontinuity designs

Regression discontinuity designs are used when treatment is applied to units according to a cutoff on the running variable (e.g. $x$) which is typically not time. By looking for the presence of a discontinuity at the precise point of the treatment cutoff then we can make causal claims about the potential impact of the treatment.

Running variableOutcomeTreated
$x_0$$y_0$False
$x_1$$y_0$False
$\ldots$$\ldots$$\ldots$
$x_{N-1}$$y_{N-1}$True
$x_N$$y_N$True
FrequentistBayesian

The data, model fit, and counterfactual are plotted (top). Frequentist analysis shows the causal impact with the blue shaded region, but this is not shown in the Bayesian analysis to avoid a cluttered chart. Instead, the Bayesian analysis shows shaded Bayesian credible regions of the model fits. The Frequentist analysis visualises the point estimate of the causal impact, but the Bayesian analysis also plots the posterior distribution of the regression discontinuity effect (bottom).

Interrupted time series

Interrupted time series analysis is appropriate when you have a time series of observations which undergo treatment at a particular point in time. This kind of analysis has no control group and looks for the presence of a change in the outcome measure at or soon after the treatment time. Multiple predictors can be included.

TimeOutcomeTreatedPredictor
$t_0$$y_0$False$x_0$
$t_1$$y_0$False$x_1$
$\ldots$$\ldots$$\ldots$$\ldots$
$t_{N-1}$$y_{N-1}$True$x_{N-1}$
$t_N$$y_N$True$x_N$
FrequentistBayesian
coming soon

The data, pre-treatment model fit, and counterfactual are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Learning resources

Here are some general resources about causal inference:

  • The official PyMC examples gallery has a set of examples specifically relating to causal inference.
  • Angrist, J. D., & Pischke, J. S. (2009). Mostly harmless econometrics: An empiricist's companion. Princeton university press.
  • Angrist, J. D., & Pischke, J. S. (2014). Mastering'metrics: The path from cause to effect. Princeton university press.
  • Cunningham, S. (2021). Causal inference: The Mixtape. Yale University Press.
  • Huntington-Klein, N. (2021). The effect: An introduction to research design and causality. Chapman and Hall/CRC.
  • Reichardt, C. S. (2019). Quasi-experimentation: A guide to design and analysis. Guilford Publications.

License

Apache License 2.0


Support

This repository is supported by PyMC Labs.

If you are interested in seeing what PyMC Labs can do for you, then please email ben.vincent@pymc-labs.io. We work with companies at a variety of scales and with varying levels of existing modeling capacity. We also run corporate workshop training events and can provide sessions ranging from introduction to Bayes to more advanced topics.

About

A Python package for causal inference in quasi-experimental settings

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation


BuildCode style: blackPyPI versionGitHub Repo starsRead the DocsPyPI - DownloadsInterrogatecodecov

CausalPy

A Python package focussing on causal inference in quasi-experimental settings. The package allows for sophisticated Bayesian model fitting methods to be used in addition to traditional OLS.

STATUS: Feel free to explore and experiment with the repository, and we very much welcome feedback (via Issues). But be aware that this code is very alpha! Expect the codebase and API to change for a while, so it is not appropriate to rely on this package for in-production or research pipelines.

Comparison to related packages

Rather than focussing on one particular quasi-experimental setting, this package aims to have broad applicability.

Another distinctive feature of this package is the ability to use different models. Currently, users can fit with scikit-learn models or Bayesian models with PyMC.

CausalImpact from GoogleGeoLift from MetaCausalPy from PyMC Labs
Synthetic control
Regression discontinuity
Difference in differences
LanguageR (but see tfcausalimpact)RPython
ModelsBayesian structural timeseriesAugmented synthetic controlFlexible: Traditional OLS and Bayesian models

Installation

To get the latest release:

pip install CausalPy

Alternatively, if you want the very latest version of the package you can install from GitHub:

pip install git+https://github.com/pymc-labs/CausalPy.git

Quickstart

importcausalpyascp# Import and process datadf= (
cp.load_data("drinking")
.rename(columns={"agecell": "age"})
.assign(treated=lambdadf_: df_.age>21)
)
# Run the analysisresult=cp.pymc_experiments.RegressionDiscontinuity(
df,
formula="all ~ 1 + age + treated",
running_variable_name="age",
model=cp.pymc_models.LinearRegression(),
treatment_threshold=21,
)
# Visualize outputsfig, ax=result.plot();
# Get a results summaryresult.summary()

Roadmap

Plans for the repository can be seen in the Issues.

Videos

Click on the thumbnail below to watch a video about CausalPy on YouTube. Youtube video thumbnail image

Overview of package capabilities

Synthetic control

This is appropriate when you have multiple units, one of which is treated. You build a synthetic control as a weighted combination of the untreated units.

TimeOutcomeControl 1Control 2Control 3
0$y_0$$x_{1,0}$$x_{2,0}$$x_{3,0}$
1$y_1$$x_{1,1}$$x_{2,1}$$x_{3,1}$
$\ldots$$\ldots$$\ldots$$\ldots$$\ldots$
T$y_T$$x_{1,T}$$x_{2,T}$$x_{3,T}$
FrequentistBayesian

The data (treated and untreated units), pre-treatment model fit, and counterfactual (i.e. the synthetic control) are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Geographical lift (Geolift)

We can also use synthetic control methods to analyse data from geographical lift studies. For example, we can try to evaluate the causal impact of an intervention (e.g. a marketing campaign) run in one geographical area by using control geographical areas which are similar to the intervention area but which did not recieve the specific marketing intervention.

ANCOVA

This is appropriate for non-equivalent group designs when you have a single pre and post intervention measurement and have a treament and a control group.

Groupprepost
0$x_1$$y_1$
0$x_2$$y_2$
1$x_3$$y_3$
1$x_4$$y_4$
FrequentistBayesian
coming soon

The data from the control and treatment group are plotted, along with posterior predictive 94% credible intervals. The lower panel shows the estimated treatment effect.

Difference in Differences

This is appropriate for non-equivalent group designs when you have pre and post intervention measurement and have a treament and a control group. Unlike the ANCOVA approach, difference in differences is appropriate when there are multiple pre and/or post treatment measurements.

Data is expected to be in the following form. Shown are just two units - one in the treated group (group=1) and one in the untreated group (group=0), but there can of course be multiple units per group. This is panel data (also known as repeated measures) where each unit is measured at 2 time points.

UnitTimeGroupOutcome
000$y_{0,0}$
010$y_{0,0}$
101$y_{1,0}$
111$y_{1,1}$
FrequentistBayesian

The data, model fit, and counterfactual are plotted. Frequentist model fits result in points estimates, but the Bayesian analysis results in posterior distributions, represented by the violin plots. The causal impact is the difference between the counterfactual prediction (treated group, post treatment) and the observed values for the treated group, post treatment.

Regression discontinuity designs

Regression discontinuity designs are used when treatment is applied to units according to a cutoff on the running variable (e.g. $x$) which is typically not time. By looking for the presence of a discontinuity at the precise point of the treatment cutoff then we can make causal claims about the potential impact of the treatment.

Running variableOutcomeTreated
$x_0$$y_0$False
$x_1$$y_0$False
$\ldots$$\ldots$$\ldots$
$x_{N-1}$$y_{N-1}$True
$x_N$$y_N$True
FrequentistBayesian

The data, model fit, and counterfactual are plotted (top). Frequentist analysis shows the causal impact with the blue shaded region, but this is not shown in the Bayesian analysis to avoid a cluttered chart. Instead, the Bayesian analysis shows shaded Bayesian credible regions of the model fits. The Frequentist analysis visualises the point estimate of the causal impact, but the Bayesian analysis also plots the posterior distribution of the regression discontinuity effect (bottom).

Interrupted time series

Interrupted time series analysis is appropriate when you have a time series of observations which undergo treatment at a particular point in time. This kind of analysis has no control group and looks for the presence of a change in the outcome measure at or soon after the treatment time. Multiple predictors can be included.

TimeOutcomeTreatedPredictor
$t_0$$y_0$False$x_0$
$t_1$$y_0$False$x_1$
$\ldots$$\ldots$$\ldots$$\ldots$
$t_{N-1}$$y_{N-1}$True$x_{N-1}$
$t_N$$y_N$True$x_N$
FrequentistBayesian
coming soon

The data, pre-treatment model fit, and counterfactual are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Learning resources

Here are some general resources about causal inference:

  • The official PyMC examples gallery has a set of examples specifically relating to causal inference.
  • Angrist, J. D., & Pischke, J. S. (2009). Mostly harmless econometrics: An empiricist's companion. Princeton university press.
  • Angrist, J. D., & Pischke, J. S. (2014). Mastering'metrics: The path from cause to effect. Princeton university press.
  • Cunningham, S. (2021). Causal inference: The Mixtape. Yale University Press.
  • Huntington-Klein, N. (2021). The effect: An introduction to research design and causality. Chapman and Hall/CRC.
  • Reichardt, C. S. (2019). Quasi-experimentation: A guide to design and analysis. Guilford Publications.

License

Apache License 2.0


Support

This repository is supported by PyMC Labs.

If you are interested in seeing what PyMC Labs can do for you, then please email ben.vincent@pymc-labs.io. We work with companies at a variety of scales and with varying levels of existing modeling capacity. We also run corporate workshop training events and can provide sessions ranging from introduction to Bayes to more advanced topics.

About

A Python package for causal inference in quasi-experimental settings

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation


BuildCode style: blackPyPI versionGitHub Repo starsRead the DocsPyPI - DownloadsInterrogatecodecov

CausalPy

A Python package focussing on causal inference in quasi-experimental settings. The package allows for sophisticated Bayesian model fitting methods to be used in addition to traditional OLS.

STATUS: Feel free to explore and experiment with the repository, and we very much welcome feedback (via Issues). But be aware that this code is very alpha! Expect the codebase and API to change for a while, so it is not appropriate to rely on this package for in-production or research pipelines.

Comparison to related packages

Rather than focussing on one particular quasi-experimental setting, this package aims to have broad applicability.

Another distinctive feature of this package is the ability to use different models. Currently, users can fit with scikit-learn models or Bayesian models with PyMC.

CausalImpact from GoogleGeoLift from MetaCausalPy from PyMC Labs
Synthetic control
Regression discontinuity
Difference in differences
LanguageR (but see tfcausalimpact)RPython
ModelsBayesian structural timeseriesAugmented synthetic controlFlexible: Traditional OLS and Bayesian models

Installation

To get the latest release:

pip install CausalPy

Alternatively, if you want the very latest version of the package you can install from GitHub:

pip install git+https://github.com/pymc-labs/CausalPy.git

Quickstart

importcausalpyascp# Import and process datadf= (
cp.load_data("drinking")
.rename(columns={"agecell": "age"})
.assign(treated=lambdadf_: df_.age>21)
)
# Run the analysisresult=cp.pymc_experiments.RegressionDiscontinuity(
df,
formula="all ~ 1 + age + treated",
running_variable_name="age",
model=cp.pymc_models.LinearRegression(),
treatment_threshold=21,
)
# Visualize outputsfig, ax=result.plot();
# Get a results summaryresult.summary()

Roadmap

Plans for the repository can be seen in the Issues.

Videos

Click on the thumbnail below to watch a video about CausalPy on YouTube. Youtube video thumbnail image

Overview of package capabilities

Synthetic control

This is appropriate when you have multiple units, one of which is treated. You build a synthetic control as a weighted combination of the untreated units.

TimeOutcomeControl 1Control 2Control 3
0$y_0$$x_{1,0}$$x_{2,0}$$x_{3,0}$
1$y_1$$x_{1,1}$$x_{2,1}$$x_{3,1}$
$\ldots$$\ldots$$\ldots$$\ldots$$\ldots$
T$y_T$$x_{1,T}$$x_{2,T}$$x_{3,T}$
FrequentistBayesian

The data (treated and untreated units), pre-treatment model fit, and counterfactual (i.e. the synthetic control) are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Geographical lift (Geolift)

We can also use synthetic control methods to analyse data from geographical lift studies. For example, we can try to evaluate the causal impact of an intervention (e.g. a marketing campaign) run in one geographical area by using control geographical areas which are similar to the intervention area but which did not recieve the specific marketing intervention.

ANCOVA

This is appropriate for non-equivalent group designs when you have a single pre and post intervention measurement and have a treament and a control group.

Groupprepost
0$x_1$$y_1$
0$x_2$$y_2$
1$x_3$$y_3$
1$x_4$$y_4$
FrequentistBayesian
coming soon

The data from the control and treatment group are plotted, along with posterior predictive 94% credible intervals. The lower panel shows the estimated treatment effect.

Difference in Differences

This is appropriate for non-equivalent group designs when you have pre and post intervention measurement and have a treament and a control group. Unlike the ANCOVA approach, difference in differences is appropriate when there are multiple pre and/or post treatment measurements.

Data is expected to be in the following form. Shown are just two units - one in the treated group (group=1) and one in the untreated group (group=0), but there can of course be multiple units per group. This is panel data (also known as repeated measures) where each unit is measured at 2 time points.

UnitTimeGroupOutcome
000$y_{0,0}$
010$y_{0,0}$
101$y_{1,0}$
111$y_{1,1}$
FrequentistBayesian

The data, model fit, and counterfactual are plotted. Frequentist model fits result in points estimates, but the Bayesian analysis results in posterior distributions, represented by the violin plots. The causal impact is the difference between the counterfactual prediction (treated group, post treatment) and the observed values for the treated group, post treatment.

Regression discontinuity designs

Regression discontinuity designs are used when treatment is applied to units according to a cutoff on the running variable (e.g. $x$) which is typically not time. By looking for the presence of a discontinuity at the precise point of the treatment cutoff then we can make causal claims about the potential impact of the treatment.

Running variableOutcomeTreated
$x_0$$y_0$False
$x_1$$y_0$False
$\ldots$$\ldots$$\ldots$
$x_{N-1}$$y_{N-1}$True
$x_N$$y_N$True
FrequentistBayesian

The data, model fit, and counterfactual are plotted (top). Frequentist analysis shows the causal impact with the blue shaded region, but this is not shown in the Bayesian analysis to avoid a cluttered chart. Instead, the Bayesian analysis shows shaded Bayesian credible regions of the model fits. The Frequentist analysis visualises the point estimate of the causal impact, but the Bayesian analysis also plots the posterior distribution of the regression discontinuity effect (bottom).

Interrupted time series

Interrupted time series analysis is appropriate when you have a time series of observations which undergo treatment at a particular point in time. This kind of analysis has no control group and looks for the presence of a change in the outcome measure at or soon after the treatment time. Multiple predictors can be included.

TimeOutcomeTreatedPredictor
$t_0$$y_0$False$x_0$
$t_1$$y_0$False$x_1$
$\ldots$$\ldots$$\ldots$$\ldots$
$t_{N-1}$$y_{N-1}$True$x_{N-1}$
$t_N$$y_N$True$x_N$
FrequentistBayesian
coming soon

The data, pre-treatment model fit, and counterfactual are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Learning resources

Here are some general resources about causal inference:

  • The official PyMC examples gallery has a set of examples specifically relating to causal inference.
  • Angrist, J. D., & Pischke, J. S. (2009). Mostly harmless econometrics: An empiricist's companion. Princeton university press.
  • Angrist, J. D., & Pischke, J. S. (2014). Mastering'metrics: The path from cause to effect. Princeton university press.
  • Cunningham, S. (2021). Causal inference: The Mixtape. Yale University Press.
  • Huntington-Klein, N. (2021). The effect: An introduction to research design and causality. Chapman and Hall/CRC.
  • Reichardt, C. S. (2019). Quasi-experimentation: A guide to design and analysis. Guilford Publications.

License

Apache License 2.0


Support

This repository is supported by PyMC Labs.

If you are interested in seeing what PyMC Labs can do for you, then please email ben.vincent@pymc-labs.io. We work with companies at a variety of scales and with varying levels of existing modeling capacity. We also run corporate workshop training events and can provide sessions ranging from introduction to Bayes to more advanced topics.

About

A Python package for causal inference in quasi-experimental settings

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation


BuildCode style: blackPyPI versionGitHub Repo starsRead the DocsPyPI - DownloadsInterrogatecodecov

CausalPy

A Python package focussing on causal inference in quasi-experimental settings. The package allows for sophisticated Bayesian model fitting methods to be used in addition to traditional OLS.

STATUS: Feel free to explore and experiment with the repository, and we very much welcome feedback (via Issues). But be aware that this code is very alpha! Expect the codebase and API to change for a while, so it is not appropriate to rely on this package for in-production or research pipelines.

Comparison to related packages

Rather than focussing on one particular quasi-experimental setting, this package aims to have broad applicability.

Another distinctive feature of this package is the ability to use different models. Currently, users can fit with scikit-learn models or Bayesian models with PyMC.

CausalImpact from GoogleGeoLift from MetaCausalPy from PyMC Labs
Synthetic control
Regression discontinuity
Difference in differences
LanguageR (but see tfcausalimpact)RPython
ModelsBayesian structural timeseriesAugmented synthetic controlFlexible: Traditional OLS and Bayesian models

Installation

To get the latest release:

pip install CausalPy

Alternatively, if you want the very latest version of the package you can install from GitHub:

pip install git+https://github.com/pymc-labs/CausalPy.git

Quickstart

importcausalpyascp# Import and process datadf= (
cp.load_data("drinking")
.rename(columns={"agecell": "age"})
.assign(treated=lambdadf_: df_.age>21)
)
# Run the analysisresult=cp.pymc_experiments.RegressionDiscontinuity(
df,
formula="all ~ 1 + age + treated",
running_variable_name="age",
model=cp.pymc_models.LinearRegression(),
treatment_threshold=21,
)
# Visualize outputsfig, ax=result.plot();
# Get a results summaryresult.summary()

Roadmap

Plans for the repository can be seen in the Issues.

Videos

Click on the thumbnail below to watch a video about CausalPy on YouTube. Youtube video thumbnail image

Overview of package capabilities

Synthetic control

This is appropriate when you have multiple units, one of which is treated. You build a synthetic control as a weighted combination of the untreated units.

TimeOutcomeControl 1Control 2Control 3
0$y_0$$x_{1,0}$$x_{2,0}$$x_{3,0}$
1$y_1$$x_{1,1}$$x_{2,1}$$x_{3,1}$
$\ldots$$\ldots$$\ldots$$\ldots$$\ldots$
T$y_T$$x_{1,T}$$x_{2,T}$$x_{3,T}$
FrequentistBayesian

The data (treated and untreated units), pre-treatment model fit, and counterfactual (i.e. the synthetic control) are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Geographical lift (Geolift)

We can also use synthetic control methods to analyse data from geographical lift studies. For example, we can try to evaluate the causal impact of an intervention (e.g. a marketing campaign) run in one geographical area by using control geographical areas which are similar to the intervention area but which did not recieve the specific marketing intervention.

ANCOVA

This is appropriate for non-equivalent group designs when you have a single pre and post intervention measurement and have a treament and a control group.

Groupprepost
0$x_1$$y_1$
0$x_2$$y_2$
1$x_3$$y_3$
1$x_4$$y_4$
FrequentistBayesian
coming soon

The data from the control and treatment group are plotted, along with posterior predictive 94% credible intervals. The lower panel shows the estimated treatment effect.

Difference in Differences

This is appropriate for non-equivalent group designs when you have pre and post intervention measurement and have a treament and a control group. Unlike the ANCOVA approach, difference in differences is appropriate when there are multiple pre and/or post treatment measurements.

Data is expected to be in the following form. Shown are just two units - one in the treated group (group=1) and one in the untreated group (group=0), but there can of course be multiple units per group. This is panel data (also known as repeated measures) where each unit is measured at 2 time points.

UnitTimeGroupOutcome
000$y_{0,0}$
010$y_{0,0}$
101$y_{1,0}$
111$y_{1,1}$
FrequentistBayesian

The data, model fit, and counterfactual are plotted. Frequentist model fits result in points estimates, but the Bayesian analysis results in posterior distributions, represented by the violin plots. The causal impact is the difference between the counterfactual prediction (treated group, post treatment) and the observed values for the treated group, post treatment.

Regression discontinuity designs

Regression discontinuity designs are used when treatment is applied to units according to a cutoff on the running variable (e.g. $x$) which is typically not time. By looking for the presence of a discontinuity at the precise point of the treatment cutoff then we can make causal claims about the potential impact of the treatment.

Running variableOutcomeTreated
$x_0$$y_0$False
$x_1$$y_0$False
$\ldots$$\ldots$$\ldots$
$x_{N-1}$$y_{N-1}$True
$x_N$$y_N$True
FrequentistBayesian

The data, model fit, and counterfactual are plotted (top). Frequentist analysis shows the causal impact with the blue shaded region, but this is not shown in the Bayesian analysis to avoid a cluttered chart. Instead, the Bayesian analysis shows shaded Bayesian credible regions of the model fits. The Frequentist analysis visualises the point estimate of the causal impact, but the Bayesian analysis also plots the posterior distribution of the regression discontinuity effect (bottom).

Interrupted time series

Interrupted time series analysis is appropriate when you have a time series of observations which undergo treatment at a particular point in time. This kind of analysis has no control group and looks for the presence of a change in the outcome measure at or soon after the treatment time. Multiple predictors can be included.

TimeOutcomeTreatedPredictor
$t_0$$y_0$False$x_0$
$t_1$$y_0$False$x_1$
$\ldots$$\ldots$$\ldots$$\ldots$
$t_{N-1}$$y_{N-1}$True$x_{N-1}$
$t_N$$y_N$True$x_N$
FrequentistBayesian
coming soon

The data, pre-treatment model fit, and counterfactual are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).

Learning resources

Here are some general resources about causal inference:

  • The official PyMC examples gallery has a set of examples specifically relating to causal inference.
  • Angrist, J. D., & Pischke, J. S. (2009). Mostly harmless econometrics: An empiricist's companion. Princeton university press.
  • Angrist, J. D., & Pischke, J. S. (2014). Mastering'metrics: The path from cause to effect. Princeton university press.
  • Cunningham, S. (2021). Causal inference: The Mixtape. Yale University Press.
  • Huntington-Klein, N. (2021). The effect: An introduction to research design and causality. Chapman and Hall/CRC.
  • Reichardt, C. S. (2019). Quasi-experimentation: A guide to design and analysis. Guilford Publications.

License

Apache License 2.0


Support

This repository is supported by PyMC Labs.

If you are interested in seeing what PyMC Labs can do for you, then please email ben.vincent@pymc-labs.io. We work with companies at a variety of scales and with varying levels of existing modeling capacity. We also run corporate workshop training events and can provide sessions ranging from introduction to Bayes to more advanced topics.

About

A Python package for causal inference in quasi-experimental settings

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages