def fit(self, bounds=None, start=None): """Fit incidence function parameters.""" start_vals = start['beta'].flatten() bound_vals = bounds['beta'].flatten().reshape((4, 2)) start_transformed = fitting.logit_transform(start_vals, bound_vals) init_state = np.sum(self.parent_fitter.parent_fitter.data['init_state'][0].reshape((3, 6)), axis=0) model_params = { 'birth_rate': self.parent_fitter.parent_fitter.sim_params['birth_rate'], 'death_rate': self.parent_fitter.parent_fitter.sim_params['death_rate'], 'removal_rate': self.parent_fitter.parent_fitter.sim_params['removal_rate'], 'recov_rate': self.parent_fitter.parent_fitter.sim_params['recov_rate'], 'state_init': init_state, 'times': self.parent_fitter.parent_fitter.data['dpc_times'], 'max_control_rate': 0, 'high_alloc_cost': 0, 'low_alloc_cost': 0 } model = risk_model.RiskModel(model_params, self) # Minimise SSE param_fit_transformed = minimize( self.sse, start_transformed, method="L-BFGS-B", options={'ftol': 1e-12}, args=(bound_vals, model)) param_fit = fitting.reverse_logit_transform(param_fit_transformed.x, bound_vals) self.data['beta'] = np.array(param_fit).reshape((2, 2))
def fit(self, bounds=None, start=None): """Fit incidence function parameters.""" # Fit parameters associated with each risk group separately since log likelihood separates for risk in Risk: start_vals = start['beta'][risk] bound_vals = bounds['beta'][risk] param_dict_tmp = { 'beta': np.zeros((2, 2)) } start_transformed = fitting.logit_transform(start_vals, bound_vals) def neg_loglik(params, risk, bounds, param_dict): """Calculate negative log likelihood from transformed optimisation parameters.""" # First reverse logit transform parameters _params_rev_trans = fitting.reverse_logit_transform(params, bounds) param_dict['beta'][risk] = _params_rev_trans val = self._calc_likelihood(param_dict, [risk]) return np.nan_to_num(-val) # Minimise negative log likelihood param_fit_transformed = minimize( neg_loglik, start_transformed, method="L-BFGS-B", options={'ftol': 1e-12}, args=(risk, bound_vals, param_dict_tmp)) param_fit = fitting.reverse_logit_transform(param_fit_transformed.x, bound_vals) if 'beta' not in self.data: self.data['beta'] = np.zeros((2, 2)) self.data['beta'][risk] = param_fit
def sse(self, params, bounds, model): """Calculate sum squared errors from transformed optimisation parameters.""" # First reverse logit transform parameters _params_rev_trans = fitting.reverse_logit_transform(params, bounds) self.data['sigma'][[0, 1, 1, 2, 2], [0, 0, 1, 1, 2]] = _params_rev_trans[0:5] self.data['rho'][[0, 1, 1], [1, 0, 1]] = _params_rev_trans[5:] # Run ODE model with parameters ode_run = model.run_policy(space_model.no_control_policy) dpc_data = self.parent_fitter.parent_fitter.data['dpc_inf'] dpc_times = self.parent_fitter.parent_fitter.data['dpc_times'] # Calculate SSE sse = 0 for i in range(dpc_data.shape[3]): for region in range(3): sse += np.sum( np.square(dpc_data[region, 0, :, i] - np.array( [ode_run.state(t)[6 * region + 1] for t in dpc_times]))) sse += np.sum( np.square(dpc_data[region, 1, :, i] - np.array( [ode_run.state(t)[6 * region + 4] for t in dpc_times]))) return sse
def neg_loglik(params, risk, bounds, param_dict): """Calculate negative log likelihood from transformed optimisation parameters.""" # First reverse logit transform parameters _params_rev_trans = fitting.reverse_logit_transform(params, bounds) param_dict['beta'][risk] = _params_rev_trans val = self._calc_likelihood(param_dict, [risk]) return np.nan_to_num(-val)
def neg_loglik(params, bounds, param_dict): """Calculate neg log likelihood from transformed optimisation parameters.""" # First reverse logit transform parameters _params_rev_trans = fitting.reverse_logit_transform(params, bounds) param_dict['sigma'][[0, 1, 1, 2, 2], [0, 0, 1, 1, 2]] = _params_rev_trans[0:5] param_dict['rho'][[0, 1, 1], [1, 0, 1]] = _params_rev_trans[5:] val = self._calc_likelihood(param_dict) return np.nan_to_num(-val)
def fit(self, bounds=None, start=None): """Fit incidence function parameters.""" nparams = 8 start_vals = np.zeros(nparams) bound_vals = np.zeros((nparams, 2)) start_vals[0:5] = start['sigma'].flatten()[[0, 3, 4, 7, 8]] bound_vals[0:5, :] = bounds['sigma'].reshape(9, 2)[[0, 3, 4, 7, 8]] start_vals[5:] = [ start['rho'][0, 1], start['rho'][1, 0], start['rho'][1, 1] ] bound_vals[5:, :] = bounds['rho'].reshape(4, 2)[[1, 2, 3]] param_dict_tmp = {'sigma': np.zeros((3, 3)), 'rho': np.zeros((2, 2))} param_dict_tmp['rho'][0, 0] = 1 param_dict_tmp['sigma'][0, 2] = 0 param_dict_tmp['sigma'][2, 0] = 0 param_dict_tmp['sigma'][0, 1] = 0 param_dict_tmp['sigma'][1, 0] = 0 start_transformed = fitting.logit_transform(start_vals, bound_vals) def neg_loglik(params, bounds, param_dict): """Calculate neg log likelihood from transformed optimisation parameters.""" # First reverse logit transform parameters _params_rev_trans = fitting.reverse_logit_transform(params, bounds) param_dict['sigma'][[0, 1, 1, 2, 2], [0, 0, 1, 1, 2]] = _params_rev_trans[0:5] param_dict['rho'][[0, 1, 1], [1, 0, 1]] = _params_rev_trans[5:] val = self._calc_likelihood(param_dict) return np.nan_to_num(-val) param_fit_transformed = minimize(neg_loglik, start_transformed, method="L-BFGS-B", options={'ftol': 1e-12}, args=(bound_vals, param_dict_tmp)) param_fit = fitting.reverse_logit_transform(param_fit_transformed.x, bound_vals) if 'sigma' not in self.data: self.data['sigma'] = np.zeros((3, 3)) if 'rho' not in self.data: self.data['rho'] = np.ones((2, 2)) self.data['sigma'][[0, 1, 1, 2, 2], [0, 0, 1, 1, 2]] = param_fit[0:5] self.data['rho'][[0, 1, 1], [1, 0, 1]] = param_fit[5:]
def sse(self, params, bounds, model): """Calculate sum squared errors from transformed optimisation parameters.""" # First reverse logit transform parameters _params_rev_trans = fitting.reverse_logit_transform(params, bounds) self.data['beta'] = np.array(_params_rev_trans).reshape((2, 2)) # Run ODE model with parameters ode_run = model.run_policy(risk_model.no_control_policy) dpc_data = self.parent_fitter.parent_fitter.data['dpc_inf'] dpc_times = self.parent_fitter.parent_fitter.data['dpc_times'] # Calculate SSE sse = 0 for i in range(dpc_data.shape[3]): sse += np.sum(np.square(np.sum( dpc_data[:, 0, :, i], axis=0) - np.array([ode_run.state(t)[1] for t in dpc_times]))) sse += np.sum(np.square(np.sum( dpc_data[:, 1, :, i], axis=0) - np.array([ode_run.state(t)[4] for t in dpc_times]))) return sse
def fit(self, bounds=None, start=None): """Fit incidence function parameters.""" nparams = 8 start_vals = np.zeros(nparams) bound_vals = np.zeros((nparams, 2)) start_vals[0:5] = start['sigma'].flatten()[[0, 3, 4, 7, 8]] bound_vals[0:5, :] = bounds['sigma'].reshape(9, 2)[[0, 3, 4, 7, 8]] start_vals[5:] = [ start['rho'][0, 1], start['rho'][1, 0], start['rho'][1, 1] ] bound_vals[5:, :] = bounds['rho'].reshape(4, 2)[[1, 2, 3]] self.data['sigma'] = np.zeros((3, 3), dtype=float) self.data['rho'] = np.ones((2, 2), dtype=float) start_transformed = fitting.logit_transform(start_vals, bound_vals) init_state = self.parent_fitter.parent_fitter.data['init_state'][0] model_params = { 'birth_rate': self.parent_fitter.parent_fitter.sim_params['birth_rate'], 'death_rate': self.parent_fitter.parent_fitter.sim_params['death_rate'], 'removal_rate': self.parent_fitter.parent_fitter.sim_params['removal_rate'], 'recov_rate': self.parent_fitter.parent_fitter.sim_params['recov_rate'], 'state_init': init_state, 'times': self.parent_fitter.parent_fitter.data['dpc_times'], 'max_control_rate': 0, 'high_alloc_cost': 0, 'low_alloc_cost': 0 } model = space_model.SpaceModel(model_params, self) param_fit_transformed = minimize(self.sse, start_transformed, method="L-BFGS-B", options={'ftol': 1e-12}, args=(bound_vals, model)) param_fit = fitting.reverse_logit_transform(param_fit_transformed.x, bound_vals) if 'sigma' not in self.data: self.data['sigma'] = np.zeros((3, 3), dtype=float) if 'rho' not in self.data: self.data['rho'] = np.ones((2, 2), dtype=float) self.data['sigma'][[0, 1, 1, 2, 2], [0, 0, 1, 1, 2]] = param_fit[0:5] self.data['rho'][[0, 1, 1], [1, 0, 1]] = param_fit[5:]