28
28
29
29
30
30
class PyMCModel (pm .Model ):
31
+ """A wraper class for PyMC models. This provides a scikit-learn like interface with
32
+ methods like `fit`, `predict`, and `score`. It also provides other methods which are
33
+ useful for causal inference.
34
+
35
+ Example
36
+ -------
37
+ >>> import causalpy as cp
38
+ >>> import numpy as np
39
+ >>> import pymc as pm
40
+ >>> from causalpy.pymc_models import ModelBuilder
41
+ >>> class MyToyModel(ModelBuilder):
42
+ ... def build_model(self, X, y, coords):
43
+ ... with self:
44
+ ... X_ = pm.Data(name="X", value=X)
45
+ ... y_ = pm.Data(name="y", value=y)
46
+ ... beta = pm.Normal("beta", mu=0, sigma=1, shape=X_.shape[1])
47
+ ... sigma = pm.HalfNormal("sigma", sigma=1)
48
+ ... mu = pm.Deterministic("mu", pm.math.dot(X_, beta))
49
+ ... pm.Normal("y_hat", mu=mu, sigma=sigma, observed=y_)
50
+ >>> rng = np.random.default_rng(seed=42)
51
+ >>> X = rng.normal(loc=0, scale=1, size=(20, 2))
52
+ >>> y = rng.normal(loc=0, scale=1, size=(20,))
53
+ >>> model = MyToyModel(
54
+ ... sample_kwargs={
55
+ ... "chains": 2,
56
+ ... "draws": 2000,
57
+ ... "progressbar": False,
58
+ ... "random_seed": rng,
59
+ ... }
60
+ ... )
61
+ >>> model.fit(X, y)
62
+ Inference data...
63
+ >>> X_new = rng.normal(loc=0, scale=1, size=(20,2))
64
+ >>> model.predict(X_new)
65
+ Inference data...
66
+ >>> model.score(X, y)
67
+ r2 0.390344
68
+ r2_std 0.081135
69
+ dtype: float64
70
+ """
71
+
31
72
def __init__ (self , sample_kwargs : Optional [Dict [str , Any ]] = None ):
32
73
"""
33
74
:param sample_kwargs: A dictionary of kwargs that get unpacked and passed to the
@@ -147,6 +188,37 @@ def print_row(
147
188
148
189
149
190
class LinearRegression (PyMCModel ):
191
+ """
192
+ Custom PyMC model for linear regression.
193
+
194
+ Defines the PyMC model
195
+
196
+ .. math::
197
+ \\ beta &\sim \mathrm{Normal}(0, 50)
198
+
199
+ \sigma &\sim \mathrm{HalfNormal}(1)
200
+
201
+ \mu &= X * \\ beta
202
+
203
+ y &\sim \mathrm{Normal}(\mu, \sigma)
204
+
205
+ Example
206
+ --------
207
+ >>> import causalpy as cp
208
+ >>> import numpy as np
209
+ >>> from causalpy.pymc_models import LinearRegression
210
+ >>> rd = cp.load_data("rd")
211
+ >>> X = rd[["x", "treated"]]
212
+ >>> y = np.asarray(rd["y"]).reshape((rd["y"].shape[0],1))
213
+ >>> lr = LinearRegression(sample_kwargs={"progressbar": False})
214
+ >>> lr.fit(X, y, coords={
215
+ ... 'coeffs': ['x', 'treated'],
216
+ ... 'obs_indx': np.arange(rd.shape[0])
217
+ ... },
218
+ ... )
219
+ Inference data...
220
+ """ # noqa: W605
221
+
150
222
def build_model (self , X , y , coords ):
151
223
"""
152
224
Defines the PyMC model
@@ -162,6 +234,34 @@ def build_model(self, X, y, coords):
162
234
163
235
164
236
class WeightedSumFitter (PyMCModel ):
237
+ """
238
+ Used for synthetic control experiments.
239
+
240
+ Defines the PyMC model:
241
+
242
+ .. math::
243
+
244
+ \sigma &\sim \mathrm{HalfNormal}(1)
245
+
246
+ \\ beta &\sim \mathrm{Dirichlet}(1,...,1)
247
+
248
+ \mu &= X * \\ beta
249
+
250
+ y &\sim \mathrm{Normal}(\mu, \sigma)
251
+
252
+ Example
253
+ --------
254
+ >>> import causalpy as cp
255
+ >>> import numpy as np
256
+ >>> from causalpy.pymc_models import WeightedSumFitter
257
+ >>> sc = cp.load_data("sc")
258
+ >>> X = sc[['a', 'b', 'c', 'd', 'e', 'f', 'g']]
259
+ >>> y = np.asarray(sc['actual']).reshape((sc.shape[0], 1))
260
+ >>> wsf = WeightedSumFitter(sample_kwargs={"progressbar": False})
261
+ >>> wsf.fit(X,y)
262
+ Inference data...
263
+ """ # noqa: W605
264
+
165
265
def build_model (self , X , y , coords ):
166
266
"""
167
267
Defines the PyMC model
0 commit comments