Causal Inference in Python

Causal Inference in Python, or Causalinference in short, is a software package that implements various statistical and econometric methods used in the field variously known as Causal Inference, Program Evaluation, or Treatment Effect Analysis.

Through a series of blog posts on this page, I will illustrate the use of Causalinference, as well as provide high-level summaries of the underlying econometric theory with the non-specialist audience in mind. Source code for the package can be found at its GitHub page, and detailed documentation is available at


Whether an econometric methodology can yield good estimates of treatment effects depends crucially on the setting of the problem. The tools provided by Causalinference do not automatically yield causal estimates that work under every possible setting, so it is important to spell out the assumptions that we are operating under.

For example, one setting under which Causalinference will work is when we have a completely randomized experiment. Under this setting, we say that the treatment assignment is independent of each subject's potential outcomes, expressed mathematically as $$(Y(0), Y(1)) \perp D.$$

Because subjects are assigned to treatment or control group on the basis of a coin flip, there is no reason to believe that the two groups of individuals are going to be different in any fundamental way other than the treatment they receive. Consequently, the simple difference between the sample averages of the observed outcomes of the two groups will be a consistent estimator of the average treatment effect. Causalinference provides this difference, but since \((Y(0), Y(1)) \perp D\) is such a strong assumption, the other estimators included in the package will yield consistent estimates as well.

More broadly, the key assumption that Causalinference relies on is the so-called unconfoundedness assumption: $$(Y(0), Y(1)) \perp D \; | \; X.$$

This says that although the treatment assignment mechanism may not be completely independent of potential outcomes, it is unconfounded in the sense that this dependence is only through something we observe, namely the covariates \(X\).

Thus under unconfoundedness if we control for \(X\), i.e., look across subjects with similar levels of \(X\), whether an individual gets treatment or not should be indistinguishable from random assignment. The difference between those who got treated and those who did not should then be attributable to the treatment itself, much like it was the case in randomized experiments.

This insight suggests many viable ways of constructing estimators of the average treatment effect. We will go through these estimators next and see how they can be invoked easily using Causalinference.