@@ -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
0 commit comments