11import abc
2+ import logging
23import numpy as np
4+ import pprint
35import scipy
46import scipy .optimize
57
68from .external import _EstimatorGLM , pkg_constants
79from .training_strategies import TrainingStrategies
810
11+ logger = logging .getLogger ("batchglm" )
12+
913
1014class EstimatorGlm (_EstimatorGLM , metaclass = abc .ABCMeta ):
1115 """
@@ -18,6 +22,8 @@ def __init__(
1822 input_data ,
1923 dtype ,
2024 ):
25+ if input_data .design_scale .shape [1 ] != 1 :
26+ raise ValueError ("cannot model more than one scale parameter with numpy backend right now." )
2127 _EstimatorGLM .__init__ (
2228 self = self ,
2329 model = model ,
@@ -32,9 +38,17 @@ def __init__(
3238 def initialize (self ):
3339 pass
3440
35- def train_sequence (self , training_strategy : str ):
41+ def train_sequence (
42+ self ,
43+ training_strategy : str = "DEFAULT"
44+ ):
3645 if isinstance (training_strategy , str ):
3746 training_strategy = self .TrainingStrategies [training_strategy ].value [0 ]
47+
48+ if training_strategy is None :
49+ training_strategy = self .TrainingStrategies .DEFAULT .value
50+
51+ logging .getLogger ("batchglm" ).info ("training strategy:\n %s" , pprint .pformat (training_strategy ))
3852 self .train (** training_strategy )
3953
4054 def train (
@@ -44,17 +58,17 @@ def train(
4458 ):
4559 # Iterate until conditions are fulfilled.
4660 train_step = 0
47- delayed_b_converged = np .tile (False , self .model .model_vars .n_features )
61+ delayed_converged = np .tile (False , self .model .model_vars .n_features )
4862
4963 ll_current = - self .model .ll_byfeature
50- print ("iter %i: ll=%f" % (0 , np .sum (ll_current )))
51- while ( np .any (np .logical_not (self . model . converged )) or np . any ( np . logical_not ( delayed_b_converged ) )) and \
64+ logging . getLogger ( "batchglm" ). debug ("iter %i: ll=%f" % (0 , np .sum (ll_current )))
65+ while np .any (np .logical_not (delayed_converged )) and \
5266 train_step < max_steps :
5367 # Update parameters:
5468 # Line search step for scale model:
5569 if train_step % update_b_freq == 0 and train_step > 0 :
5670 b_var_cache = self .model .b_var .copy ()
57- self .model .b_var = self .b_step (idx = np .where (np .logical_not (delayed_b_converged ))[0 ])
71+ self .model .b_var = self .b_step (idx = np .where (np .logical_not (delayed_converged ))[0 ])
5872 # Reverse update by feature if update leads to worse loss:
5973 ll_proposal = - self .model .ll_byfeature
6074 b_var_new = self .model .b_var .copy ()
@@ -71,10 +85,14 @@ def train(
7185 # Location model convergence status has to be updated if b model was updated
7286 if train_step % update_b_freq == 0 and train_step > 0 :
7387 self .model .converged = converged_f
88+ delayed_converged = converged_f
7489 else :
7590 self .model .converged = np .logical_or (self .model .converged , converged_f )
7691 train_step += 1
77- print ("iter %i: ll=%f, converged: %i" % (train_step , np .sum (ll_current ), np .sum (self .model .converged )))
92+ logging .getLogger ("batchglm" ).debug (
93+ "iter %i: ll=%f, converged: %i" %
94+ (train_step , np .sum (ll_current ), np .sum (self .model .converged ))
95+ )
7896 self .lls .append (ll_current )
7997
8098 def iwls_step (self ) -> np .ndarray :
@@ -167,10 +185,11 @@ def finalize(self):
167185 transfers relevant attributes.
168186 """
169187 # Read from numpy-IRLS estimator specific model:
170- self ._hessian = - self .model .fim
188+
189+ self ._hessian = self .model .hessian
171190 self ._fisher_inv = np .linalg .inv (- self ._hessian )
172- self ._jacobian = self .model .jac
173- self ._log_likelihood = self .model .ll
191+ self ._jacobian = np . sum ( np . abs ( self .model .jac / self . model . x . shape [ 0 ]), axis = 1 )
192+ self ._log_likelihood = self .model .ll_byfeature
174193 self ._loss = np .sum (self ._log_likelihood )
175194
176195 @abc .abstractmethod
0 commit comments