Skip to content

Commit e392335

Browse files
committed
Added IV examples after rebasing
1 parent 5d6c8eb commit e392335

File tree

5 files changed

+88
-4
lines changed

5 files changed

+88
-4
lines changed

causalpy/pymc_experiments.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,40 @@ class InstrumentalVariable(ExperimentalDesign):
13011301
"lkj_sd": 2,
13021302
}
13031303
1304+
Example
1305+
--------
1306+
>>> import pandas as pd
1307+
>>> import causalpy as cp
1308+
>>> from causalpy.pymc_experiments import InstrumentalVariable
1309+
>>> from causalpy.pymc_models import InstrumentalVariableRegression
1310+
>>> import numpy as np
1311+
>>> N = 100
1312+
>>> e1 = np.random.normal(0, 3, N)
1313+
>>> e2 = np.random.normal(0, 1, N)
1314+
>>> Z = np.random.uniform(0, 1, N)
1315+
>>> ## Ensure the endogeneity of the the treatment variable
1316+
>>> X = -1 + 4 * Z + e2 + 2 * e1
1317+
>>> y = 2 + 3 * X + 3 * e1
1318+
>>> test_data = pd.DataFrame({"y": y, "X": X, "Z": Z})
1319+
>>> sample_kwargs = {
1320+
... "tune": 10,
1321+
... "draws": 20,
1322+
... "chains": 4,
1323+
... "cores": 4,
1324+
... "target_accept": 0.95,
1325+
... "progressbar": False,
1326+
... }
1327+
>>> instruments_formula = "X ~ 1 + Z"
1328+
>>> formula = "y ~ 1 + X"
1329+
>>> instruments_data = test_data[["X", "Z"]]
1330+
>>> data = test_data[["y", "X"]]
1331+
>>> iv = InstrumentalVariable(
1332+
... instruments_data=instruments_data,
1333+
... data=data,
1334+
... instruments_formula=instruments_formula,
1335+
... formula=formula,
1336+
... model=InstrumentalVariableRegression(sample_kwargs=sample_kwargs),
1337+
... )
13041338
"""
13051339

13061340
def __init__(
@@ -1355,6 +1389,12 @@ def __init__(
13551389
)
13561390

13571391
def get_2SLS_fit(self):
1392+
"""
1393+
Two Stage Least Squares Fit
1394+
1395+
This function is called by the experiment, results are used for
1396+
priors if none are provided.
1397+
"""
13581398
first_stage_reg = sk_lin_reg().fit(self.Z, self.t)
13591399
fitted_Z_values = first_stage_reg.predict(self.Z)
13601400
X2 = self.data.copy(deep=True)
@@ -1371,6 +1411,11 @@ def get_2SLS_fit(self):
13711411
self.second_stage_reg = second_stage_reg
13721412

13731413
def get_naive_OLS_fit(self):
1414+
"""
1415+
Naive Ordinary Least Squares
1416+
1417+
This function is called by the experiment.
1418+
"""
13741419
ols_reg = sk_lin_reg().fit(self.X, self.y)
13751420
beta_params = list(ols_reg.coef_[0][1:])
13761421
beta_params.insert(0, ols_reg.intercept_[0])

causalpy/pymc_models.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,42 @@ def build_model(self, X, y, coords):
303303

304304

305305
class InstrumentalVariableRegression(ModelBuilder):
306-
"""Custom PyMC model for instrumental linear regression"""
306+
"""Custom PyMC model for instrumental linear regression
307+
308+
Example
309+
--------
310+
>>> import causalpy as cp
311+
>>> import numpy as np
312+
>>> from causalpy.pymc_models import InstrumentalVariableRegression
313+
>>> N = 10
314+
>>> e1 = np.random.normal(0, 3, N)
315+
>>> e2 = np.random.normal(0, 1, N)
316+
>>> Z = np.random.uniform(0, 1, N)
317+
>>> ## Ensure the endogeneity of the the treatment variable
318+
>>> X = -1 + 4 * Z + e2 + 2 * e1
319+
>>> y = 2 + 3 * X + 3 * e1
320+
>>> t = X.reshape(10,1)
321+
>>> y = y.reshape(10,1)
322+
>>> Z = np.asarray([[1, Z[i]] for i in range(0,10)])
323+
>>> X = np.asarray([[1, X[i]] for i in range(0,10)])
324+
>>> COORDS = {'instruments': ['Intercept', 'Z'], 'covariates': ['Intercept', 'X']}
325+
>>> sample_kwargs = {
326+
... "tune": 5,
327+
... "draws": 10,
328+
... "chains": 2,
329+
... "cores": 2,
330+
... "target_accept": 0.95,
331+
... "progressbar": False,
332+
... }
333+
>>> iv_reg = InstrumentalVariableRegression(sample_kwargs=sample_kwargs)
334+
>>> iv_reg.fit(X, Z,y, t, COORDS, {
335+
... "mus": [[-2,4], [0.5, 3]],
336+
... "sigmas": [1, 1],
337+
... "eta": 2,
338+
... "lkj_sd": 2,
339+
... })
340+
Inference data...
341+
"""
307342

308343
def build_model(self, X, Z, y, t, coords, priors):
309344
"""Specify model with treatment regression and focal regression data and priors

causalpy/tests/test_input_validation.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Input validation tests"""
2+
13
import pandas as pd
24
import pytest
35

@@ -205,6 +207,7 @@ def test_rd_validation_treated_is_dummy():
205207

206208

207209
def test_iv_treatment_var_is_present():
210+
"""Test the treatment variable is present for Instrumental Variable experiment"""
208211
data = pd.DataFrame({"x": [1, 2, 3], "y": [2, 4, 5]})
209212
instruments_formula = "risk ~ 1 + logmort0"
210213
formula = "loggdp ~ 1 + risk"

causalpy/version.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
"""CausalPy Version"""
12
__version__ = "0.1.0"

docs/source/_static/interrogate_badge.svg

Lines changed: 3 additions & 3 deletions
Loading

0 commit comments

Comments
 (0)