Skip to content

Commit 273daa2

Browse files
authored
Merge pull request #462 from pymc-labs/obs_ind
fix bug: obs_indx -> obs_ind and improve `PyMCModel._data_setter`
2 parents 88d535c + 71b6a8a commit 273daa2

File tree

7 files changed

+20
-10
lines changed

7 files changed

+20
-10
lines changed

causalpy/experiments/diff_in_diff.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def __init__(
104104

105105
# fit model
106106
if isinstance(self.model, PyMCModel):
107-
COORDS = {"coeffs": self.labels, "obs_indx": np.arange(self.X.shape[0])}
107+
COORDS = {"coeffs": self.labels, "obs_ind": np.arange(self.X.shape[0])}
108108
self.model.fit(X=self.X, y=self.y, coords=COORDS)
109109
elif isinstance(self.model, RegressorMixin):
110110
self.model.fit(X=self.X, y=self.y)

causalpy/experiments/interrupted_time_series.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def __init__(
110110

111111
# fit the model to the observed (pre-intervention) data
112112
if isinstance(self.model, PyMCModel):
113-
COORDS = {"coeffs": self.labels, "obs_indx": np.arange(self.pre_X.shape[0])}
113+
COORDS = {"coeffs": self.labels, "obs_ind": np.arange(self.pre_X.shape[0])}
114114
self.model.fit(X=self.pre_X, y=self.pre_y, coords=COORDS)
115115
elif isinstance(self.model, RegressorMixin):
116116
self.model.fit(X=self.pre_X, y=self.pre_y)

causalpy/experiments/prepostnegd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def __init__(
113113

114114
# fit the model to the observed (pre-intervention) data
115115
if isinstance(self.model, PyMCModel):
116-
COORDS = {"coeffs": self.labels, "obs_indx": np.arange(self.X.shape[0])}
116+
COORDS = {"coeffs": self.labels, "obs_ind": np.arange(self.X.shape[0])}
117117
self.model.fit(X=self.X, y=self.y, coords=COORDS)
118118
elif isinstance(self.model, RegressorMixin):
119119
raise NotImplementedError("Not implemented for OLS model")

causalpy/experiments/regression_discontinuity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ def __init__(
124124
# fit model
125125
if isinstance(self.model, PyMCModel):
126126
# fit the model to the observed (pre-intervention) data
127-
COORDS = {"coeffs": self.labels, "obs_indx": np.arange(self.X.shape[0])}
127+
COORDS = {"coeffs": self.labels, "obs_ind": np.arange(self.X.shape[0])}
128128
self.model.fit(X=self.X, y=self.y, coords=COORDS)
129129
elif isinstance(self.model, RegressorMixin):
130130
self.model.fit(X=self.X, y=self.y)

causalpy/experiments/regression_kink.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def __init__(
8484
self.y, self.X = np.asarray(y), np.asarray(X)
8585
self.outcome_variable_name = y.design_info.column_names[0]
8686

87-
COORDS = {"coeffs": self.labels, "obs_indx": np.arange(self.X.shape[0])}
87+
COORDS = {"coeffs": self.labels, "obs_ind": np.arange(self.X.shape[0])}
8888
self.model.fit(X=self.X, y=self.y, coords=COORDS)
8989

9090
# score the goodness of fit to all data

causalpy/experiments/synthetic_control.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def __init__(
105105

106106
# fit the model to the observed (pre-intervention) data
107107
if isinstance(self.model, PyMCModel):
108-
COORDS = {"coeffs": self.labels, "obs_indx": np.arange(self.pre_X.shape[0])}
108+
COORDS = {"coeffs": self.labels, "obs_ind": np.arange(self.pre_X.shape[0])}
109109
self.model.fit(X=self.pre_X, y=self.pre_y, coords=COORDS)
110110
elif isinstance(self.model, RegressorMixin):
111111
self.model.fit(X=self.pre_X, y=self.pre_y)

causalpy/pymc_models.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,20 @@ def _data_setter(self, X) -> None:
8787
8888
This method is used internally to register new data for the model for
8989
prediction.
90+
91+
NOTE: We are actively changing the `X`. Often, this matrix will have a different
92+
number of rows than the original data. So to make the shapes work, we need to
93+
update all data nodes in the model to have the correct shape. The values are not
94+
used, so we set them to 0. In our case, we just have data nodes X and y, but if
95+
in the future we get more complex models with more data nodes, then we'll need
96+
to update all of them - ideally programmatically.
9097
"""
98+
new_no_of_observations = X.shape[0]
9199
with self:
92-
pm.set_data({"X": X})
100+
pm.set_data(
101+
{"X": X, "y": np.zeros(new_no_of_observations)},
102+
coords={"obs_ind": np.arange(new_no_of_observations)},
103+
)
93104

94105
def fit(self, X, y, coords: Optional[Dict[str, Any]] = None) -> None:
95106
"""Draw samples from posterior, prior predictive, and posterior predictive
@@ -117,7 +128,6 @@ def predict(self, X):
117128
118129
.. caution::
119130
Results in KeyError if model hasn't been fit.
120-
121131
"""
122132

123133
# Ensure random_seed is used in sample_prior_predictive() and
@@ -206,7 +216,7 @@ class LinearRegression(PyMCModel):
206216
>>> lr = LinearRegression(sample_kwargs={"progressbar": False})
207217
>>> lr.fit(X, y, coords={
208218
... 'coeffs': ['x', 'treated'],
209-
... 'obs_indx': np.arange(rd.shape[0])
219+
... 'obs_ind': np.arange(rd.shape[0])
210220
... },
211221
... )
212222
Inference data...
@@ -451,7 +461,7 @@ class PropensityScore(PyMCModel):
451461
>>> ps = PropensityScore(sample_kwargs={"progressbar": False})
452462
>>> ps.fit(X, t, coords={
453463
... 'coeffs': ['age', 'race'],
454-
... 'obs_indx': np.arange(df.shape[0])
464+
... 'obs_ind': np.arange(df.shape[0])
455465
... },
456466
... )
457467
Inference...

0 commit comments

Comments
 (0)