Categories → Study Design, Tutorial
This tutorial will demonstrate the Fixed-Effects models available in Causal Wizard with 3 examples.
To illustrate and explain the Fixed-Effects models available in Causal Wizard, we will work through 3 of the examples described in Matheus Facure's excellent Python Causality Handbook - "Causal Inference for the Brave and True". Each example has a downloadable dataset - just upload it and create a new Study against it.
To understand the methods and ideas explored in these tutorials, it would help to read:
To summarize, Fixed-Effects models are commonly used in Econometrics to conduct a "quasi-experiment" to obtain a causal effect estimate, or to establish a cause-and-effect relationship.
Usually, several Entities (maybe individuals, but often groups) are observed over a period of time, resulting in multiple measurements of each Entity or group. This is a more generalized form of the popular Difference-in-Differences (DiD) technique, where the number of groups and time periods is relaxed from 2, to any number. Given this experiment design, the data is typically in Panel Data format.
Introduction & objectives
Imagine you wanted to explore the effect of Treatment: "marketing costs" on Outcome: "purchases" across four cities where you have shops.
This example utilizes a synthetic dataset to illustrate how misleading a simple regression model can be. Simply fitting a regression line to all the data predicts that higher marketing spend causes fewer purchases! What?!
But this picture is misleading, because as we can see, the data is grouped into four cities, and within each city, higher marketing spend causes more purchases!
If we add a "fixed-effect" to the model for each city (city indicated by dot colour), the resulting regression model predicts these straight purple lines, which indicate the effect of marketing spend has reversed:
This example shows that Entity Fixed-Effects (in this case, the Entities are cities) improve the regression model to more accurately predict purchases given marketing spend. In fact, this is an example of Simpson's Paradox.
We can reproduce the same result in Causal Wizard.
Steps
Reviewing the result
Causal Wizard's notebook provides a range of analyses of your data and model, but scroll down to the Outcomes plots section, to the scatter plot of predicted vs actual outcomes:

This plot looks a lot like the correct model in the second image from Matheus Facure's original article! Great.
There are some other sections of the notebook worth a look:
Challenge
What would happen if you leave Entity column unset? (Tip: The model would behave similarly to the first regression model displayed in the introduction - the incorrect one.)
Introduction & objectives
This example creates a Two-Way Fixed Effects (TWFE) model with both Entities and Time. The experiment design is Binary (Case/Control groups). From the original article, the problem is described as follows (emphasis added):
"Panel data methods are often used in government policy evaluation, but we can easily make an argument about why they are also incredibly useful for the (tech) industry. Companies often track user data across multiple periods of time, which results in a rich panel data structure. Not only that, sometimes experimentation is not possible, so we have to rely on other identification strategies. To explore that idea further, let’s consider a hypothetical example of a young tech company that tracks the number of people that installed its app across multiple cities.
At some point in 2021, the tech company launched a new feature in their app. It now wants to know how many new users that feature brought to the company. The rollout was gradual. Some cities got the feature in 2021-06-01. Others, in 2021-07-15. The full rollout to the rest of the cities only happens in 2022. Since our data only goes up until 2021-07-31, this last group can be considered the control group. In causal inference terms, rolling out this feature can be seen as the treatment and number of installs can be seen as the outcome. We want to know the treatment effect on the outcome, that is, the effect of the new feature on the number of installs."
In the data provided, the variable treat indicates whether users in a city received the feature (1 = yes, 0 = no).
Steps
Reviewing the result
In this case, the data is synthetic and we know the true causal effect, which is 1. In the Findings section, you should see this reported - verify the result is correct. As in the previous tutorial, we should also check our validation and refutation tests.
Since this example includes Time, we next want to have a look at the Outcomes over time plot. This includes a plot, which at first will look very busy - because we are currently modelling individual fixed effects for each of the many units, and every one of them is plotted.
These plots are generated using Plotly.js. We can select series by clicking in the Legend; double-clicking a series will cycle through hiding it, showing it, and showing all series. By selecting only the series for one unit we can see 4 series for it:
For a unit that switches from Control to Treated partway through the data, you should be able to see the predicted and observed values track from the Control level up to the Treated level, at the point the unit was actually treated.
Additional Analysis
There are numerous other results to review. You could also simplify the plot by re-running with a coarser Entity column - if your data has a city/cohort column, set Entity column to that instead of unit, re-check, re-download the config, and re-run. This produces a plot more similar to the one in Matheus Facure's book, with one line per city rather than per individual unit - but the estimated causal effect will be a little different, because you're no longer controlling for the same effects. You could consider this model "wrong" because it isn't controlling for the same effects as the unit-level one, but it's a good idea to explore a range of related model configurations to ensure they all behave as you'd expect.
Introduction & objectives
This third example is actually the simplest. It is introduced in Chapter 13 to show the equivalence of DiD and regression under certain conditions, namely binary treatment design, 2 time periods, and 2 groups of entities with one group treated in the second time period. We will use it for the same purpose, to show how a DiD result can be obtained in Causal Wizard.
The data has 4 columns:
poa * jul i.e. 1 iff post-intervention and city Porto Alegre. These samples are the only ones which are treated. If you use Causal Wizard for DiD on your own data, you'll also need to add an interaction term like this.With that data, we want to estimate the effect of Treatment on Outcome: deposits. Note that both poa and jul only take 2 values each, so many individual samples (bank branches) share the same entity and time - that's completely fine for a Fixed Effects model; see Panel Data format for why repeated entity/time combinations don't need to be unique.
Steps
Reviewing the result
In this case we have a "correct" result from Matheus Facure's article, which we expect to obtain: 6.52. This is the value of the interaction coefficient (treated variable) he obtained from both the simple DiD calculation, and OLS regression.
Your result should be somewhere close to this, but probably not exactly right. Why is that?
As part of Validation, Causal Wizard's notebook automatically holds back some data for generalization testing, by default a random 20% of your data. To reproduce the original result exactly, we must use all our data for training the model.
The new causal effect should now be 6.52 (or very close to it).
Parallel Trends plot
One of the important assumptions to check in a DiD study is the parallel trends assumption: absent treatment, both/all Entity groups would have experienced the same change in Outcome. The Outcomes over time plot is intended to visualise this and help you confirm it. It has up to 4 series per Entity:
In the case of DiD, we want to confirm that the trend for the Treated entity (city of POA) is similar to the trend for the Control entity (city FL). Since we only have 2 time points, we can't verify this visually here - but in your own data, you may have multiple time periods, and the Causal Wizard model will work just as well; you'll see all time points in the chart, and duplicate entity/time rows are automatically averaged before plotting.
The plot shows counterfactuals and predictions so you can compare model predictive behaviour to observations, and visualize the effect of your intervention (treatment).
Above: the outcome-over-time plot should show the prediction for city POA (entity=1) rising from the Control level to the Treated level between May and July. The actual data should match this behaviour closely. In contrast, city FL's (entity=0) prediction line should remain at the Control level throughout, since it was never treated.