How to use Causal Impact in Python (Example)
21 August 2023 | By Farkhod Khushvaktov
In this tutorial we will learn how to use Causal Impact in Python programing language
- simple using the yfinance library to load data
- using the pycausalimpact
Causal Impact is a package created by Kay H. Brodersen that uses Bayesian statistics to infer the causal effect of an event.
How to format your data for CausalImpact
causalimpact can be used in two way
- simple pre-post experiment
- using control group
Simple pre-post experiment
Your dataset should be a table with dates and a single y column.
- The
datecolumn - The
ycolumn contains data from a single site.
Using control groups
When comparing against control groups, your dataset should be a table like this:
datesycolumn containing data from the sites which you tested onXncolumns containing data from the sites/subfolders which the test was not turned on. EachXcolumn represents a different feature.
Defining test and control groups
Control groups in causal inference are datasets that are not impacted by an experiment than can used to improve the prediction on your test data.
Get Mr Farkhod Khushaktov’s stories in your inbox
Join Medium for free to get updates from this writer.
Control groups can be different things:
- Independent data such as search trends of a topic in Google Trends
- Different TLD (
example1.com,example2.com) - Different ccTLD (
example.com,example.ca) - Different subdomains (
ca.example.com,au.example.com) - Different subfolders (
example.com/ca,example.com/au)
By convention, the test group is usually labelled as y and the control groups as X.
Getting Start
First install Some Libraries like this
#installing Libraries
!pip install yfinance
!pip install pycausalimpactyou can see that are two libraries
Import modules
So We have some Module to use it
import yfinance as yf
from causalimpact import CausalImpact
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
Set Dates to load data
#Dates
training_start = "2020-09-01"
training_end = "2020-10-19"
treatment_start = "2020-10-20"
treatment_end = "2020-10-23"
end_stock = "2020-10-24"as you can see that there are some dates to load data from yfinance library
Load Financial Data
#Bitcoin
y = ["BTC-USD"]
y = yf.download(tickers=y,
start=training_start,
end=end_stock,
interval="1d")
y = y["Adj Close"].rename("y")
y[:1]this data our Y values as you can see
Load More Data
#Load More Data
Stock = ["ZAL.DE", "SQ", "CRSP", "TRMB", "JD", "KTOS", "GOOG"]
X = yf.download(tickers=Stock,
start = training_start,
end = end_stock,
interval ="1d")in this code example you can see yf library this library can load data from financial site
X.tail()Data Preparation
First we can get data only as size as previous list of data
X = X.iloc[:,:len(Stock)]
X.head(1)
Remove Adj Close and Set Time Zone
Then we can remove Adj Close column from the table
#remove droplevel column
X.columns = X.columns.droplevel()
X.head(1)
#Time Zones
X.index = X.index.tz_localize(None)Add y column to X column
X = pd.concat([y, X], axis=1).dropna()
X.tail()If you do not use dropna() function you will have some error because there will exist some Null Value in top of data
Data Analysis Section
First Split training data
df_training = X.loc[X.index <= training_end]
df_training.tail(2)Change Percentege of Data
differencing = X.pct_change().dropna()
differencingas you can see we use pct_change function to predict better
Let’s Correlate
plt.figure(figsize=(10, 6))
sns.set(font_scale = 1.2)
sns.heatmap(data = differencing.corr(),
annot = True,
fmt = ".2g",
linewidth = 1,
cmap = "PiYG",
linecolor = 'black');Causal Impact Section
We will do some change and split dates
df_final = X.drop(columns = ['ZAL.DE'])
df_final.tail()
pre_period = [training_start, training_end]
post_period = [treatment_start, treatment_end]ready to start to use causal impact
impact = CausalImpact(df_final, pre_period, post_period)Summary
print(impact.summary('report'))OUTPUT>>
Analysis report {CausalImpact}
During the post-intervention period, the response variable had an average value of approx. 12659.36. By contrast, in the absence of an intervention, we would have expected an average response of 11189.03. The 95% interval of this counterfactual prediction is [10935.4, 11453.53]. Subtracting this prediction from the observed response yields an estimate of the causal effect the intervention had on the response variable. This effect is 1470.33 with a 95% interval of [1205.83, 1723.97]. For a discussion of the significance of this effect, see below.
Summing up the individual data points during the post-intervention period (which can only sometimes be meaningfully interpreted), the response variable had an overall value of 50637.46. By contrast, had the intervention not taken place, we would have expected a sum of 44756.14. The 95% interval of this prediction is [43741.58, 45814.14].
The above results are given in terms of absolute numbers. In relative terms, the response variable showed an increase of +13.14%. The 95% interval of this percentage is [10.78%, 15.41%]. This means that the positive effect observed during the intervention period is statistically significant and unlikely to be due to random fluctuations. It should be noted, however, that the question of whether this increase also bears substantive significance can only be answered by comparing the absolute effect (1470.33) to the original goal of the underlying intervention.
The probability of obtaining this effect by chance is very small (Bayesian one-sided tail-area probability p = 0.0). This means the causal effect can be considered statistically significant.








