Skip to content

Commit 670c6d7

Browse files
authored
makes _compute_deviance a private class method for fepois (#1074)
1 parent 49a5478 commit 670c6d7

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

pyfixest/estimation/fepois_.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,23 @@ def to_array(self):
199199
if self._fe.ndim == 1:
200200
self._fe = self._fe.reshape((self._N, 1))
201201

202+
def _compute_deviance(self, Y: np.ndarray, mu: np.ndarray):
203+
"""
204+
Deviance is defined as twice the difference in log likelihood between the
205+
saturated model and the model being fit.
206+
207+
deviance = 2 * (log_likelihood_saturated - log_likelihood_fitted)
208+
209+
See [1] chapter 5.6 for more details.
210+
[1] Dobson, Annette J., and Adrian G. Barnett. An introduction to generalized linear models. Chapman and Hall/CRC, 2018.
211+
"""
212+
with warnings.catch_warnings():
213+
warnings.simplefilter("ignore")
214+
deviance = np.float64(
215+
2 * np.sum(np.where(Y == 0, 0, Y * np.log(Y / mu)) - (Y - mu))
216+
)
217+
return deviance
218+
202219
def get_fit(self) -> None:
203220
"""
204221
Fit a Poisson Regression Model via Iterated Weighted Least Squares (IWLS).
@@ -227,15 +244,6 @@ def get_fit(self) -> None:
227244
Demeaned dependent variable (from the last iteration of the IRLS
228245
algorithm).
229246
"""
230-
231-
def compute_deviance(Y: np.ndarray, mu: np.ndarray):
232-
with warnings.catch_warnings():
233-
warnings.simplefilter("ignore")
234-
deviance = (
235-
2 * np.sum(np.where(Y == 0, 0, Y * np.log(Y / mu)) - (Y - mu))
236-
).flatten()
237-
return deviance
238-
239247
stop_iterating = False
240248
crit = 1
241249

@@ -257,7 +265,7 @@ def compute_deviance(Y: np.ndarray, mu: np.ndarray):
257265
eta = np.log(mu)
258266
Z = eta + self._Y / mu - 1
259267
reg_Z = Z.copy()
260-
last = compute_deviance(self._Y, mu)
268+
last = self._compute_deviance(self._Y, mu)
261269

262270
else:
263271
# update w and Z
@@ -307,9 +315,9 @@ def compute_deviance(Y: np.ndarray, mu: np.ndarray):
307315

308316
# same criterion as fixest
309317
# https://github.com/lrberge/fixest/blob/6b852fa277b947cea0bad8630986225ddb2d6f1b/R/ESTIMATION_FUNS.R#L2746
310-
deviance = compute_deviance(self._Y, mu)
318+
deviance = self._compute_deviance(self._Y, mu)
311319
crit = np.abs(deviance - last) / (0.1 + np.abs(last))
312-
last = deviance.copy()
320+
last = deviance
313321

314322
stop_iterating = crit < self.tol
315323

pyfixest/report/summarize.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,8 @@ def summary(models: ModelInputType, digits: int = 3) -> None:
605605
if not np.isnan(fxst._r2_within):
606606
to_print += f"R2 Within: {np.round(fxst._r2_within, digits)} "
607607
if fxst.deviance is not None:
608-
to_print += f"Deviance: {np.round(fxst.deviance[0], digits)} "
608+
deviance_value = np.asarray(fxst.deviance).squeeze()
609+
to_print += f"Deviance: {np.round(deviance_value, digits)} "
609610

610611
print(to_print)
611612

0 commit comments

Comments
 (0)