def get_model(n_obs=50, true_params=None, seed_obs=None): """Return a complete Gaussian noise model. Parameters ---------- n_obs : int, optional the number of observations true_params : list, optional true_params[0] corresponds to the mean, true_params[1] corresponds to the standard deviation seed_obs : int, optional seed for the observed data generation Returns ------- m : elfi.ElfiModel """ if true_params is None: true_params = [10, 2] y_obs = Gauss(*true_params, n_obs=n_obs, random_state=np.random.RandomState(seed_obs)) sim_fn = partial(Gauss, n_obs=n_obs) m = elfi.ElfiModel() elfi.Prior('uniform', -10, 50, model=m, name='mu') elfi.Prior('truncnorm', 0.01, 5, model=m, name='sigma') elfi.Simulator(sim_fn, m['mu'], m['sigma'], observed=y_obs, name='Gauss') elfi.Summary(ss_mean, m['Gauss'], name='S1') elfi.Summary(ss_var, m['Gauss'], name='S2') elfi.Distance('euclidean', m['S1'], m['S2'], name='d') return m
def get_model(self, n_obs=100, true_params=None, seed_obs=None): """Return a complete MA2 model in inference task. Parameters ---------- n_obs : int, optional observation length of the MA2 process true_params : list, optional parameters with which the observed data is generated seed_obs : int, optional seed for the observed data generation Returns ------- m : elfi.ElfiModel """ if true_params is None: true_params = [60] y_obs = self.func(*true_params, random_state=np.random.RandomState(seed_obs)) m = elfi.ElfiModel() elfi.Prior(ss.uniform, 0, 100, model=m, name='t1') elfi.Simulator(self.func, m['t1'], observed=y_obs, name='sim') elfi.Distance('euclidean', m['sim'], name='dist') return m
def get_model(n_obs=100, true_params=None, seed_obs=None): """Returns a complete MA2 model in inference task Parameters ---------- n_obs : int observation length of the MA2 process true_params : list parameters with which the observed data is generated seed_obs : None, int seed for the observed data generation Returns ------- m : elfi.ElfiModel """ if true_params is None: true_params = [.6, .2] y = MA2(*true_params, n_obs=n_obs, random_state=np.random.RandomState(seed_obs)) sim_fn = partial(MA2, n_obs=n_obs) m = elfi.ElfiModel(set_current=False) elfi.Prior(CustomPrior1, 2, model=m, name='t1') elfi.Prior(CustomPrior2, m['t1'], 1, name='t2') elfi.Simulator(sim_fn, m['t1'], m['t2'], observed=y, name='MA2') elfi.Summary(autocov, m['MA2'], name='S1') elfi.Summary(autocov, m['MA2'], 2, name='S2') elfi.Distance('euclidean', m['S1'], m['S2'], name='d') return m
def get_model(self, n_obs=100, true_params=None, seed_obs=None): """Return a complete model in inference task. Parameters ---------- n_obs : int, optional observation length of the MA2 process true_params : list, optional parameters with which the observed data is generated seed_obs : int, optional seed for the observed data generation Returns ------- m : elfi.ElfiModel """ m = elfi.ElfiModel() if true_params is None: elfi.Prior('uniform', -20.0, 20.0, model=m, name='white') elfi.Prior('uniform', -20.0, 20.0, model=m, name='yellow') elfi.Prior('uniform', -20.0, 20.0, model=m, name='red') elfi.Prior('uniform', -20.0, 20.0, model=m, name='green') elfi.Prior('uniform', -20.0, 20.0, model=m, name='purple') params = [ m['white'], m['yellow'], m['red'], m['green'], m['purple'] ] y_obs = self.get_observed_data() elfi.Simulator(self.func, *params, observed=y_obs, name='sim') elfi.Distance('euclidean', m['sim'], name='dist') # elfi.Distance(self.discrepancyII, m['DGP'], name='d') return m
def test_list_output(): vsim = elfi.tools.vectorize(lsimulator) vsum = elfi.tools.vectorize(lsummary) v = vsim(np.array([[.2, .8], [.3, .7]])) assert is_array(v) assert not isinstance(v[0], list) vsim = elfi.tools.vectorize(lsimulator, dtype=False) v = vsim(np.array([[.2, .8], [.3, .7]])) assert is_array(v) assert isinstance(v[0], list) obs = lsimulator([.2, .8]) elfi.new_model() p = elfi.Prior('dirichlet', [2, 2]) sim = elfi.Simulator(vsim, p, observed=obs) S = elfi.Summary(vsum, sim) d = elfi.Distance('euclidean', S) pool = elfi.OutputPool(['sim']) rej = elfi.Rejection(d, batch_size=100, pool=pool, output_names=['sim']) sample = rej.sample(100, n_sim=1000) mean = np.mean(sample.samples['p'], axis=0) # Crude test assert mean[1] > mean[0]
def test_single_parameter_linear_adjustment(): """A regression test against values obtained in the notebook.""" seed = 20170616 n_obs = 50 batch_size = 100 mu, sigma = (5, 1) # Hyperparameters mu0, sigma0 = (10, 100) y_obs = gauss.Gauss( mu, sigma, n_obs=n_obs, batch_size=1, random_state=np.random.RandomState(seed)) sim_fn = partial(gauss.Gauss, sigma=sigma, n_obs=n_obs) # Posterior n = y_obs.shape[1] mu1 = (mu0 / sigma0**2 + y_obs.sum() / sigma**2) / (1 / sigma0**2 + n / sigma**2) sigma1 = (1 / sigma0**2 + n / sigma**2)**(-0.5) # Model m = elfi.ElfiModel() elfi.Prior('norm', mu0, sigma0, model=m, name='mu') elfi.Simulator(sim_fn, m['mu'], observed=y_obs, name='Gauss') elfi.Summary(lambda x: x.mean(axis=1), m['Gauss'], name='S1') elfi.Distance('euclidean', m['S1'], name='d') res = elfi.Rejection(m['d'], output_names=['S1'], seed=seed).sample(1000, threshold=1) adj = elfi.adjust_posterior(model=m, sample=res, parameter_names=['mu'], summary_names=['S1']) assert np.allclose(_statistics(adj.outputs['mu']), (4.9772879640569778, 0.02058680115402544))
def get_model(n_obs=100, true_params=None, seed_obs=None, n_lags=5): """Return a complete ARCH(1) model. Parameters ---------- n_obs: int Observation length of the ARCH(1) process. true_params: list, optinal Parameters with which the observed data are generated. seed_obs: int, optional Seed for the observed data generation. n_lags: int, optional Number of lags in summary statistics. Returns ------- elfi.ElfiModel """ if true_params is None: true_params = [0.3, 0.7] logger.info( f'true_params were not given. Now using [t1, t2] = {true_params}.') # elfi model m = elfi.ElfiModel() # priors t1 = elfi.Prior('uniform', -1, 2, model=m) t2 = elfi.Prior('uniform', 0, 1, model=m) priors = [t1, t2] # observations y_obs = arch(*true_params, n_obs=n_obs, random_state=np.random.RandomState(seed_obs)) # simulator Y = elfi.Simulator(arch, *priors, observed=y_obs) # summary statistics ss = [] ss.append(elfi.Summary(sample_mean, Y, name='MU', model=m)) ss.append(elfi.Summary(sample_variance, Y, name='VAR', model=m)) for i in range(1, n_lags + 1): ss.append(elfi.Summary(autocorr, Y, i, name=f'AC_{i}', model=m)) for i, j in combinations(range(1, n_lags + 1), 2): ss.append( elfi.Summary(pairwise_autocorr, Y, i, j, name=f'PW_{i}_{j}', model=m)) # distance elfi.Distance('euclidean', *ss, name='d', model=m) return m
def get_model(alpha=0.2, delta=0, tau=0.198, N=20, seed_obs=None): """Returns the example model used in Lintusaari et al. 2016. Here we infer alpha using the summary statistic T1. We expect the executable `bdm` be available in the working directory. Parameters ---------- alpha : float birth rate delta : float death rate tau : float mutation rate N : int size of the population seed_obs : None, int Seed for the observed data generation. None gives the same data as in Lintusaari et al. 2016 Returns ------- m : elfi.ElfiModel """ if seed_obs is None and N == 20: y = np.zeros(N, dtype='int16') data = np.array([6, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1], dtype='int16') y[0:len(data)] = data else: y = BDM(alpha, delta, tau, N, random_state=np.random.RandomState(seed_obs)) m = elfi.ElfiModel(name='bdm') elfi.Prior('uniform', .005, 2, model=m, name='alpha') elfi.Simulator(BDM, m['alpha'], delta, tau, N, observed=y, name='BDM') elfi.Summary(T1, m['BDM'], name='T1') elfi.Distance('minkowski', m['T1'], p=1, name='d') m['BDM'].uses_meta = True # Warn the user if the executable is not present if not os.path.isfile('bdm') and not os.path.isfile('bdm.exe'): cpp_path = get_sources_path() warnings.warn( "This model uses an external simulator `bdm` implemented in C++ " "that needs to be compiled and copied to your working directory. " "We could not find it from your current working directory. Please" "copy the folder `{}` to your working directory " "and compile the source.".format(cpp_path), RuntimeWarning) return m
def get_model(n_obs=50, true_params=None, seed_obs=None, stochastic=True): """Returns a complete Ricker model in inference task. This is a simplified example that achieves reasonable predictions. For more extensive treatment and description using 13 summary statistics, see: Wood, S. N. (2010) Statistical inference for noisy nonlinear ecological dynamic systems, Nature 466, 1102–1107. Parameters ---------- n_obs : int, optional Number of observations. true_params : list, optional Parameters with which the observed data is generated. seed_obs : None, int, optional Seed for the observed data generation. stochastic : bool, optional Whether to use the stochastic or deterministic Ricker model. Returns ------- m : elfi.ElfiModel """ if stochastic: simulator = partial(stochastic_ricker, n_obs=n_obs) if true_params is None: true_params = [3.8, 0.3, 10.] else: simulator = partial(ricker, n_obs=n_obs) if true_params is None: true_params = [3.8] m = elfi.ElfiModel() y_obs = simulator(*true_params, n_obs=n_obs, random_state=np.random.RandomState(seed_obs)) sim_fn = partial(simulator, n_obs=n_obs) sumstats = [] if stochastic: elfi.Prior(ss.expon, np.e, 2, model=m, name='t1') elfi.Prior(ss.truncnorm, 0, 5, model=m, name='t2') elfi.Prior(ss.uniform, 0, 100, model=m, name='t3') elfi.Simulator(sim_fn, m['t1'], m['t2'], m['t3'], observed=y_obs, name='Ricker') sumstats.append(elfi.Summary(partial(np.mean, axis=1), m['Ricker'], name='Mean')) sumstats.append(elfi.Summary(partial(np.var, axis=1), m['Ricker'], name='Var')) sumstats.append(elfi.Summary(num_zeros, m['Ricker'], name='#0')) elfi.Discrepancy(chi_squared, *sumstats, name='d') else: # very simple deterministic case elfi.Prior(ss.expon, np.e, model=m, name='t1') elfi.Simulator(sim_fn, m['t1'], observed=y_obs, name='Ricker') sumstats.append(elfi.Summary(partial(np.mean, axis=1), m['Ricker'], name='Mean')) elfi.Distance('euclidean', *sumstats, name='d') return m
def build(self, model, pattern, prior_pos, prior_cov=64, r_bound=47.9, pmt_mask=np.ones(127)): ### Build Priors px = elfi.Prior(BoundedNormal_x, r_bound, prior_pos, prior_cov) py = elfi.Prior(BoundedNormal_y, px, r_bound, prior_pos, prior_cov) ### Build Model model = elfi.tools.vectorize(model) Y = elfi.Simulator(model, px, py, observed=np.array([pattern])) # TODO implement PMT mask here #def summarize(data, key): # # Select either energy or time for model output. # return np.array([v[key] for v in data]) def summarize(data): return np.array( [list(v['energy']) + list(v['time']) for v in data]) # Build summary stat for energy and time #S1 = elfi.Summary(summarize, Y, 'energy') #S2 = elfi.Summary(summarize, Y, 'time') S1 = elfi.Summary(summarize, Y) d = elfi.Distance('braycurtis', S1) log_d = elfi.Operation(np.log, d) # set the ELFI model so we can remove it later self.model = px.model ### Setup BOLFI bounds = {'px': (-r_bound, r_bound), 'py': (-r_bound, r_bound)} target_model = GPyRegression(log_d.model.parameter_names, bounds=bounds) acquisition_method = ConstraintLCBSC(target_model, prior=ModelPrior(log_d.model), noise_var=[1, 1], exploration_rate=10) bolfi = elfi.BOLFI( log_d, batch_size=1, initial_evidence=50, update_interval=1, # bounds=bounds, # Not used when using target_model target_model=target_model, # acq_noise_var=[0.1, 0.1], # Not used when using acq method acquisition_method=acquisition_method, ) return bolfi
def multivariate_model(request): ndim = request.param m = elfi.ElfiModel() elfi.Prior(ss.multivariate_normal, [0] * ndim, model=m, name='t1') elfi.Simulator(rowsummer, m['t1'], observed=np.array([[0]]), model=m, name='sim') elfi.Distance('euclidean', m['sim'], model=m, name='d') return m
def new_sample(MA2, t_prior, t_prior_name, N=500, y_obs=y_obs): # ELFI also supports giving the scipy.stats distributions as strings Y = elfi.Simulator(MA2, t_prior, observed=y_obs) S1 = elfi.Summary(autocov, Y) S2 = elfi.Summary(autocov, Y, 2) # the optional keyword lag is given the value 2 d = elfi.Distance('euclidean', S1, S2) rej = elfi.Rejection(d, batch_size=5000, seed=np.random.randint(10**5)) result = rej.sample(N, quantile=0.01) return result.samples[t_prior_name].mean(axis=0)
def multivariate_model(request): ndim = request.param def fun(x, batch_size, random_state): return np.sum(x, keepdims=True, axis=1) m = elfi.ElfiModel() elfi.Prior(ss.multivariate_normal, [0] * ndim, model=m, name='t1') elfi.Simulator(fun, m['t1'], observed=np.array([[0]]), model=m, name='sim') elfi.Distance('euclidean', m['sim'], model=m, name='d') return m
def sleep_model(request): """The true param will be half of the given sleep time.""" ub_sec = request.param or .5 m = elfi.ElfiModel() elfi.Constant(ub_sec, model=m, name='ub') elfi.Prior('uniform', 0, m['ub'], model=m, name='sec') elfi.Simulator(sleeper, m['sec'], model=m, name='slept') elfi.Summary(no_op, m['slept'], model=m, name='summary') elfi.Distance('euclidean', m['summary'], model=m, name='d') m.observed['slept'] = ub_sec / 2 return m
def predict(self, data_test): elfi.new_model("SMC") prior = elfi.Prior(MVUniform, self.p_lower, self.p_upper) sim = elfi.Simulator(self.simulator, prior, observed=data_test, name='sim') SS = elfi.Summary(self.identity, sim, name='identity') d = elfi.Distance('euclidean', SS, name='d') smc = elfi.SMC(d, batch_size=1, seed=42) samples = smc.sample(self.n_particles, [self.threshold]) return samples.samples_array
def get_model(n_obs=50, true_params=None, seed_obs=None, **kwargs): """Return a complete Lotka-Volterra model in inference task. Parameters ---------- n_obs : int, optional Number of observations. true_params : list, optional Parameters with which the observed data is generated. seed_obs : int, optional Seed for the observed data generation. Returns ------- m : elfi.ElfiModel """ logger = logging.getLogger() if true_params is None: true_params = [1.0, 0.005, 0.6, 50, 100, 10.] kwargs['n_obs'] = n_obs y_obs = lotka_volterra(*true_params, random_state=np.random.RandomState(seed_obs), **kwargs) m = elfi.ElfiModel() sim_fn = partial(lotka_volterra, **kwargs) priors = [] sumstats = [] priors.append(elfi.Prior(ExpUniform, -6., 2., model=m, name='r1')) priors.append(elfi.Prior(ExpUniform, -6., 2., model=m, name='r2')) # easily kills populations priors.append(elfi.Prior(ExpUniform, -6., 2., model=m, name='r3')) priors.append(elfi.Prior('poisson', 50, model=m, name='prey0')) priors.append(elfi.Prior('poisson', 100, model=m, name='predator0')) priors.append( elfi.Prior(ExpUniform, np.log(0.5), np.log(50), model=m, name='sigma')) elfi.Simulator(sim_fn, *priors, observed=y_obs, name='LV') sumstats.append( elfi.Summary(partial(pick_stock, species=0), m['LV'], name='prey')) sumstats.append( elfi.Summary(partial(pick_stock, species=1), m['LV'], name='predator')) elfi.Distance('sqeuclidean', *sumstats, name='d') logger.info( "Generated %i observations with true parameters r1: %.1f, r2: %.3f, r3: %.1f, " "prey0: %i, predator0: %i, sigma: %.1f.", n_obs, *true_params) return m
def get_model(self, n_obs=100, true_params=None, seed_obs=None): """Return a complete model in inference task. Parameters ---------- n_obs : int, optional observation length of the MA2 process true_params : list, optional parameters with which the observed data is generated seed_obs : int, optional seed for the observed data generation Returns ------- m : elfi.ElfiModel """ m = elfi.ElfiModel() if true_params is None and self.env_name == "CartPole-v0": # gravity, masscart, masspole, length, force_mag true_params = [[9.8], [1.0], [0.1], [0.5], [10.0]] elfi.Prior('uniform', 5.0, 10.0, model=m, name='gravity') elfi.Prior('uniform', 0.1, 5, model=m, name='masscart') elfi.Prior('uniform', 0.1, 5, model=m, name='masspole') elfi.Prior('uniform', 0.1, 5, model=m, name='length') elfi.Prior('uniform', 5.0, 10.0, model=m, name='force_mag') params = [ m['gravity'], m['masscart'], m['masspole'], m['length'], m['force_mag'] ] elif true_params is None and self.env_name == "MountainCar-v0": # goal_position, goal_velocity, force, gravity true_params = [0.5, 0, 0.001, 0.0025] elfi.Prior('uniform', -1.2, 0.6, model=m, name='goal_position') elfi.Prior('uniform', 0, 5.0, model=m, name='goal_velocity') elfi.Prior('uniform', 0.0001, 0.01, model=m, name='force') elfi.Prior('uniform', 0.0001, 0.01, model=m, name='gravity') params = [ m['goal_position'], m['goal_velocity'], m['force'], m['gravity'] ] y_obs = self.func(*true_params, random_state=np.random.RandomState(seed_obs)) elfi.Simulator(self.func, *params, observed=y_obs, name='DGP') elfi.Distance('euclidean', m['DGP'], name='d') return m
def get_model(self, n_obs=100, true_params=None, seed_obs=None): m = elfi.new_model() elfi.Prior('uniform', -2, 4, name='x') elfi.Prior('uniform', -2, 4, name='y') params = [m['x'], m['y']] if true_params is None: true_params = [[1.5, 1]] y_obs = self.func(*true_params, random_state=np.random.RandomState(seed_obs)) y_obs = [np.mean(y_obs), np.std(y_obs)] elfi.Simulator(self.func, *params, observed=y_obs, name='sim') # elfi.Summary(partial(np.mean, axis=1), m['sim'], name='Mean') # elfi.Summary(partial(np.std, axis=1), m['sim'], name='Std') elfi.Distance('euclidean', m['sim'], name='dist') return m
def build(self, model, pattern, prior_pos, prior_cov=25, r_bound=47.9, pmt_mask=np.ones(127)): ### Build Priors px = elfi.Prior(BoundedNormal_x, r_bound, prior_pos, prior_cov) py = elfi.Prior(BoundedNormal_y, px, r_bound, prior_pos, prior_cov) ### Build Model model = elfi.tools.vectorize(model) Y = elfi.Simulator(model, px, py, observed=np.array([pattern])) # TODO implement PMT mask here d = elfi.Distance('braycurtis', Y) log_d = elfi.Operation(np.log, d) # set the ELFI model so we can remove it later self.model = px.model ### Setup BOLFI bounds = {'px': (-r_bound, r_bound), 'py': (-r_bound, r_bound)} target_model = GPyRegression(log_d.model.parameter_names, bounds=bounds) acquisition_method = ConstraintLCBSC(target_model, prior=ModelPrior(log_d.model), noise_var=[5, 5], exploration_rate=10) bolfi = elfi.BOLFI( log_d, batch_size=1, initial_evidence=50, update_interval=1, # bounds=bounds, # Not used when using target_model target_model=target_model, # acq_noise_var=[0.1, 0.1], # Not used when using acq method acquisition_method=acquisition_method, ) return bolfi
def _obtain_accepted_thetas(self, set_ss, n_sim, n_acc, batch_size): """Perform the ABC-rejection sampling and identify `closest' parameters. The sampling is performed using the initialised simulator. Parameters ---------- set_ss : List Summary-statistics combination to be used in the rejection sampling. n_sim : int Number of the iterations of the rejection sampling. n_acc : int Number of the accepted parameters. batch_size : int Number of samples per batch. Returns ------- array_like Accepted parameters. """ # Initialise the distance function. m = self.simulator.model.copy() list_ss = [] for ss in set_ss: list_ss.append(elfi.Summary(ss, m[self.simulator.name], model=m)) if isinstance(self.fn_distance, str): d = elfi.Distance(self.fn_distance, *list_ss, model=m) else: d = elfi.Discrepancy(self.fn_distance, *list_ss, model=m) # Run the simulations. # TODO: include different distance functions in the summary-statistics combinations. sampler_rejection = elfi.Rejection(d, batch_size=batch_size, seed=self.seed, pool=self.pool) result = sampler_rejection.sample(n_acc, n_sim=n_sim) # Extract the accepted parameters. thetas_acc = result.samples_array return thetas_acc
def test_dict_output(): vsim = elfi.tools.vectorize(simulator) vsum = elfi.tools.vectorize(summary) obs = simulator([.2, .8]) elfi.new_model() p = elfi.Prior('dirichlet', [2, 2]) sim = elfi.Simulator(vsim, p, observed=obs) S = elfi.Summary(vsum, sim) d = elfi.Distance('euclidean', S) pool = elfi.OutputPool(['sim']) rej = elfi.Rejection(d, batch_size=100, pool=pool, output_names=['sim']) sample = rej.sample(100, n_sim=1000) mean = np.mean(sample.samples['p'], axis=0) # Crude test assert mean[1] > mean[0]
def get_model(self, n_obs=10, true_params=None, seed_obs=None): m = elfi.new_model() # Parameters: ns, kc, alpha, r_star, As # priors from Sinha and Souradeep 2006. elfi.Prior('uniform', 0.5, 1.0, name='ns') elfi.Prior('uniform', 1e-7, 1e-3, name='kc') elfi.Prior('uniform', 0., 10., name='alpha') elfi.Prior('uniform', 0., 1., name='r_star') elfi.Prior('uniform', 2.7, 1.3, name='As') params = [m['ns'], m['kc'], m['alpha'], m['r_star'], m['As']] if true_params is None: true_params = [[0.96, 0.0003, 0.58, 0.75, 3.35]] y_obs = self.func(*true_params, random_state=np.random.RandomState(seed_obs)) elfi.Simulator(self.func, *params, observed=y_obs, name='sim') elfi.Distance('euclidean', m['sim'], name='dist') return m
def predict(self, data_test): elfi.new_model("BOLFI") prior = elfi.Prior(MVUniform, self.p_lower, self.p_upper) sim = elfi.Simulator(self.simulator, prior, observed=data_test, name='sim') SS = elfi.Summary(self.identity, sim, name='identity') d = elfi.Distance('euclidean', SS, name='d') log_d = elfi.Operation(np.log, d) bolfi = elfi.BOLFI(log_d, batch_size=1, initial_evidence=20, update_interval=10, acq_noise_var=self.p_lower.size * [0.1], bounds=None, seed=42) bolfi.fit(n_evidence=self.n_particles) post = bolfi.extract_posterior(-1.) samples = post.model.X return samples
def main(): global eng datadir = Path('/home/ben/phd/stfp/abc_results/gradientNet') eng = matlab.engine.start_matlab() eng.addpath(eng.genpath('~/phd/stfp/abc_code')) eng.addpath(eng.genpath('~/phd/easySim')) maxConnProbOB2E_prior = elfi.Prior('uniform', 0, 1) maxConnProbOB2I_prior = elfi.Prior('uniform', 0, 1) maxConnProbGC2E_prior = elfi.Prior('uniform', 0, 1) maxConnProbGC2I_prior = elfi.Prior('uniform', 0, 1) sigmaOB2PC_prior = elfi.Prior('uniform', 1e-6, 1000e-6) sigmaGC2PC_prior = elfi.Prior('uniform', 1e-6, 1000e-6) sim = elfi.Simulator(simulator, maxConnProbOB2E_prior, maxConnProbOB2I_prior, maxConnProbGC2E_prior, maxConnProbGC2I_prior, sigmaOB2PC_prior, sigmaGC2PC_prior, observed=0) S = elfi.Summary(score_network, sim) d = elfi.Distance('euclidean', S) #log_d = elfi.Operation(np.log, d) pool = elfi.OutputPool([ 'connProbOB2E_prior', 'connProbOB2I_prior', 'connProbGC2E_prior', 'connProbGC2I_prior', 'sigmaOB2PC_prior', 'sigmaGC2PC_prior', 'S', 'd' ]) ie_maxConnProbOB2E, ie_maxConnProbOB2I, ie_maxConnProbGC2E, ie_maxConnProbGC2I, ie_sigmaOB2PC, ie_sigmaGC2PC, ie_scores = eng.load_initial_evidence_gradientNet( '/home/ben/phd/stfp/abc_results/gradientNet', nargout=7) ie_maxConnProbOB2E = np.asarray(ie_maxConnProbOB2E) ie_maxConnProbOB2I = np.asarray(ie_maxConnProbOB2I) ie_maxConnProbGC2E = np.asarray(ie_maxConnProbGC2E) ie_maxConnProbGC2I = np.asarray(ie_maxConnProbGC2I) ie_sigmaOB2PC = np.asarray(ie_sigmaOB2PC) ie_sigmaGC2PC = np.asarray(ie_sigmaGC2PC) ie_scores = np.asarray(ie_scores) #ie_log_scores = np.log(ie_scores) if not ie_maxConnProbOB2E.any(): ie = 10 print('0 prior runs detected') else: ie = { 'maxConnProbOB2E_prior': ie_maxConnProbOB2E, 'maxConnProbOB2I_prior': ie_maxConnProbOB2I, 'maxConnProbGC2E_prior': ie_maxConnProbGC2E, 'maxConnProbGC2I_prior': ie_maxConnProbGC2I, 'sigmaOB2PC_prior': ie_sigmaOB2PC, 'sigmaGC2PC_prior': ie_sigmaGC2PC, 'd': ie_scores } print( str(ie_maxConnProbOB2E.size) + ' prior runs detected... using as initial evidence') bolfi = elfi.BOLFI(d, batch_size=1, initial_evidence=ie, update_interval=1, bounds={ 'maxConnProbOB2E_prior': (0, 1), 'maxConnProbOB2I_prior': (0, 1), 'maxConnProbGC2E_prior': (0, 1), 'maxConnProbGC2I_prior': (0, 1), 'sigmaOB2PC_prior': (1e-6, 1000e-6), 'sigmaGC2PC_prior': (1e-6, 1000e-6) }, acq_noise_var=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], pool=pool) posterior = bolfi.fit(n_evidence=500) with open(datadir / 'bolfi_result.pkl', 'wb') as fname: pickle.dump(bolfi, fname) #bolfi.plot_state() bolfi.plot_discrepancy() plt.show(block=True)
# Set the generating parameters that we will try to infer mean0 = 1 std0 = 3 alpha0 = 3.5 # Generate some data (using a fixed seed here) np.random.seed(20170525) y0 = simulator(mean0, std0, alpha0) print(y0) # Add the simulator node and observed data to the model sim = elfi.Simulator(simulator, mu, sigma, alpha, observed=y0) # Add summary statistics to the model S1 = elfi.Summary(mean, sim) S2 = elfi.Summary(var, sim) # Specify distance as euclidean between summary vectors (S1, S2) from simulated and # observed data d = elfi.Distance('euclidean', S1, S2) #### Plot the complete model (requires graphviz) # elfi.draw(d) rej = elfi.Rejection(d, batch_size=10000, seed=30052017) res = rej.sample(10000, threshold=.5) print(res) import matplotlib.pyplot as plt res.plot_marginals() plt.show()
def get_model(true_params=None, seed_obs=None, initial_state=None, n_obs=40, f=10., phi=0.984, total_duration=4): """Return a complete Lorenz model in inference task. This is a simplified example that achieves reasonable predictions. Hakkarainen, J., Ilin, A., Solonen, A., Laine, M., Haario, H., Tamminen, J., Oja, E., and Järvinen, H. (2012). On closure parameter estimation in chaotic systems. Nonlinear Processes in Geophysics, 19(1), 127–143. Parameters ---------- true_params : list, optional Parameters with which the observed data is generated. seed_obs : int, optional Seed for the observed data generation. initial_state : ndarray Initial state value of the time-series. n_obs : int, optional Number of observed variables f : float, optional Force term phi : float, optional This value is used to express stochastic forcing term. It should be configured according to force term and eventually impacts to the result of eta. More details in Wilks (2005) et al. total_duration : float, optional Returns ------- m : elfi.ElfiModel """ simulator = partial(forecast_lorenz, initial_state=initial_state, f=f, n_obs=n_obs, phi=phi, total_duration=total_duration) if not true_params: true_params = [2.0, 0.1] m = elfi.ElfiModel() y_obs = simulator(*true_params, random_state=np.random.RandomState(seed_obs)) sumstats = [] elfi.Prior('uniform', 0.5, 3., model=m, name='theta1') elfi.Prior('uniform', 0, 0.3, model=m, name='theta2') elfi.Simulator(simulator, m['theta1'], m['theta2'], observed=y_obs, name='Lorenz') sumstats.append(elfi.Summary(mean, m['Lorenz'], name='Mean')) sumstats.append(elfi.Summary(var, m['Lorenz'], name='Var')) sumstats.append(elfi.Summary(autocov, m['Lorenz'], name='Autocov')) sumstats.append(elfi.Summary(cov, m['Lorenz'], name='Cov')) sumstats.append(elfi.Summary(xcov, m['Lorenz'], True, name='CrosscovPrev')) sumstats.append(elfi.Summary(xcov, m['Lorenz'], False, name='CrosscovNext')) elfi.Distance('euclidean', *sumstats, name='d') return m
############# DEFINE ELFI MODEL ################## def simulator(theta, dim, batch_size=10000, random_state=None): likelihood = Likelihood() theta = np.repeat(theta, dim, -1) return likelihood.rvs(theta, seed=random_state) elfi.new_model("1D_example") elfi_prior = elfi.Prior(Prior(), name="theta") elfi_simulator = elfi.Simulator(simulator, elfi_prior, dim, observed=np.expand_dims(data, 0), name="simulator") dist = elfi.Distance('euclidean', elfi_simulator, name="dist") bounds = [(-2.5, 2.5)] dim = data.shape[-1] # Defines the ROMC inference method romc = elfi.ROMC(dist, bounds) romc1 = elfi.ROMC(dist, bounds) romc2 = elfi.ROMC(dist, bounds) romc3 = elfi.ROMC(dist, bounds) ############# Gradients ################### seed = 21 eps = 1 n1 = np.linspace(1, 101, 10) solve_grad = []
prior_args = [m[name] for name in m.parameter_names] elfi.Simulator(elfi_sim, *prior_args, m["length"], m["recombination_rate"], m["mutation_rate"], priors, name="sim", model=m) elfi.Summary(elfi_sum, m["sim"], name="sum", model=m) elfi.Summary(elfi_sum_scaler, m["sum"], None, name="sum_scaler") # Placeholder (no scaling yet) elfi.Distance('euclidean', m["sum_scaler"], name='d', model=m) # Rejection to "train" sum stat scaler start_time = time.time() pool = elfi.OutputPool(['sum']) rej = elfi.Rejection(m['d'], batch_size=1, seed=1, pool=pool) rej.sample(train_scaler_n_sim, quantile=1, bar=False) # Accept all sum_stats = pool.get_store('sum') sum_stats = np.array(list(sum_stats.values())) sum_stats = sum_stats.reshape(-1, sum_stats.shape[2]) # Drop batches axis scaler = StandardScaler() scaler.fit(sum_stats) elapsed_time = time.time() - start_time logging.info( f"{train_scaler_n_sim} simulations to train standard scaler completed in {elapsed_time/60:.2f} minutes" )
X, N, K, r, alphaprior1, alphaprior2, alphaprior3, alphaprior4, alphaprior5, alphaprior6, tau, measurement_idx, observed=observeddata) summary = elfi.Summary(logdestack, simulator_results) d = elfi.Distance('euclidean', summary) #log_d = elfi.Operation(np.log, d) bolfi = elfi.BOLFI(d, batch_size=1, initial_evidence=100, update_interval=10, bounds={ 'alphaprior1': (0, 5), 'alphaprior2': (0, 5), 'alphaprior3': (0, 5), 'alphaprior4': (0, 5), 'alphaprior5': (0, 5), 'alphaprior6': (0, 5) }, acq_noise_var=[0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
def main(base, output, number_processes): # generate null (should only execute once) use = 'BOLFI' #use = 'SINGLE' if use != 'SINGLE': click.secho('Generating null dataset', fg='yellow') subprocess.check_call( ["snakemake", "null", "--profile", "elfi_profile"]) click.secho('Creating environments', fg='yellow') subprocess.check_call( ["snakemake", "--profile", "elfi_profile", "--create-envs-only"]) click.secho('Starting BOLFI', fg='yellow') if base: global base_output base_output = base if output: global summary_output summary_output = output # setup priors elfi.set_client(multiprocessing.Client(num_processes=number_processes)) model = elfi.ElfiModel(name='msprime') elfi.Prior('uniform', 0, 0.5, model=model, name='n1') elfi.Prior('uniform', 0, 0.5, model=model, name='n2') elfi.Prior('uniform', 0, 1, model=model, name='split_prop') elfi.Prior('uniform', 1, 1861, model=model, name='split_size') snake_sim = elfi.tools.external_operation(command, prepare_inputs=prepare_inputs, process_result=process_result, stdout=False) vec_snake = elfi.tools.vectorize(snake_sim) empirical = np.array([ 0, # desert MSE 0.291761, 0.328705, 0.335145, # pi 0.12985, 0.156539, 0.0921547, # fst 0.023, 0.019 ]) # admix snake_node = elfi.Simulator(vec_snake, model['n1'], model['n2'], model['split_prop'], model['split_size'], observed=empirical, name='snake_sim') snake_node.uses_meta = True distance = elfi.Distance('euclidean', snake_node, name='dist') if use == 'SINGLE': print( snake_sim(0.1, 0.1, 0.1, 100, seed=2, meta={ 'model_name': 'test', 'batch_index': 1, 'submission_index': 2 })) return elif use == 'BOLFI': pool = elfi.ArrayPool( ['n1', 'n2', 'split_prop', 'split_size', 'snake_sim'], name='bolfi_pool') bolfi = elfi.BOLFI(distance, batch_size=1, initial_evidence=20, update_interval=3, bounds={ 'n1': (0, 0.5), 'n2': (0, 0.5), 'split_prop': (0, 1), 'split_size': (1, 1861) }, pool=pool) post = bolfi.fit(n_evidence=10, bar=False) click.secho('Saving results', fg='yellow') pool.save() post.save() click.secho('Done', fg='green') return