def _iter_sample(draws, step, start=None, trace=None, chain=0, tune=None, model=None, random_seed=-1): """Modified from :func:`pymc3.sampling._iter_sample` to be more efficient with SMC algorithm.""" model = modelcontext(model) draws = int(draws) if draws < 1: raise ValueError('Argument `draws` should be above 0.') if start is None: start = {} if random_seed != -1: nr.seed(random_seed) try: step = pm.step_methods.CompoundStep(step) except TypeError: pass point = pm.Point(start, model=model) step.chain_index = chain trace.setup(draws, chain) for i in range(draws): if i == tune: step = pm.sampling.stop_tuning(step) point, out_list = step.step(point) trace.record(out_list) yield trace
def pymc3_random_discrete(dist, paramdomains, valuedomain=Domain([0]), ref_rand=None, size=100000, alpha=0.05, fails=20): model = build_model(dist, valuedomain, paramdomains) domains = paramdomains.copy() for pt in product(domains, n_samples=100): pt = pm.Point(pt, model=model) p = alpha # Allow Chisq test to fail (i.e., the samples be different) # a certain number of times. f = fails while p <= alpha and f > 0: o = model.named_vars['value'].random(size=size, point=pt) e = ref_rand(size=size, **pt) o = np.atleast_1d(o).flatten() e = np.atleast_1d(e).flatten() observed = dict(zip(*np.unique(o, return_counts=True))) expected = dict(zip(*np.unique(e, return_counts=True))) for e in expected.keys(): expected[e] = (observed.get(e, 0), expected[e]) k = np.array([v for v in expected.values()]) if np.all(k[:, 0] == k[:, 1]): p = 1. else: _, p = st.chisquare(k[:, 0], k[:, 1]) f -= 1 assert p > alpha, str(pt)
def _initial_population(draws, model, variables, start): """ Create an initial population from the prior """ population = [] var_info = OrderedDict() if start is None: init_rnd = pm.sample_prior_predictive( draws, var_names=[v.name for v in model.unobserved_RVs], model=model ) else: init_rnd = start init = model.test_point for v in variables: var_info[v.name] = (init[v.name].shape, init[v.name].size) for i in range(draws): point = pm.Point({v.name: init_rnd[v.name][i] for v in variables}, model=model) population.append(model.dict_to_array(point)) return np.array(floatX(population)), var_info
def pymc3_random(dist, paramdomains, ref_rand, valuedomain=Domain([0]), size=10000, alpha=0.05, fails=10, extra_args=None, model_args=None): if model_args is None: model_args = {} model = build_model(dist, valuedomain, paramdomains, extra_args) domains = paramdomains.copy() for pt in product(domains, n_samples=100): pt = pm.Point(pt, model=model) pt.update(model_args) p = alpha # Allow KS test to fail (i.e., the samples be different) # a certain number of times. Crude, but necessary. f = fails while p <= alpha and f > 0: s0 = model.named_vars['value'].random(size=size, point=pt) s1 = ref_rand(size=size, **pt) _, p = st.ks_2samp( np.atleast_1d(s0).flatten(), np.atleast_1d(s1).flatten()) f -= 1 assert p > alpha, str(pt)
def __init__(self, vars=None, covariance=None, scaling=1., n_chains=100, tune=True, tune_interval=100, model=None, check_bound=True, likelihood_name='like', proposal_dist=MvNPd, coef_variation=1., **kwargs): model = pm.modelcontext(model) if vars is None: vars = model.vars vars = pm.inputvars(vars) if covariance is None: self.covariance = np.eye(sum(v.dsize for v in vars)) self.scaling = np.atleast_1d(scaling) self.tune = tune self.check_bnd = check_bound self.tune_interval = tune_interval self.steps_until_tune = tune_interval self.proposal_dist = proposal_dist(self.covariance) self.proposal_samples_array = self.proposal_dist(n_chains) self.stage_sample = 0 self.accepted = 0 self.beta = 0 self.stage = 0 self.coef_variation = coef_variation self.n_chains = n_chains self.likelihoods = [] self.likelihood_name = likelihood_name self.discrete = np.concatenate( [[v.dtype in pm.discrete_types] * (v.dsize or 1) for v in vars]) self.any_discrete = self.discrete.any() self.all_discrete = self.discrete.all() # create initial population self.population = [] self.array_population = np.zeros(n_chains) for i in range(self.n_chains): dummy = pm.Point({v.name: v.random() for v in vars}, model=model) self.population.append(dummy) shared = make_shared_replacements(vars, model) self.logp_forw = logp_forw(model.logpt, vars, shared) self.check_bnd = logp_forw(model.varlogpt, vars, shared) self.delta_logp = pm.metropolis.delta_logp(model.logpt, vars, shared) super(ATMCMC, self).__init__(vars, shared)
def _initial_population(draws, model, variables): """ Create an initial population from the prior """ population = [] var_info = {} start = model.test_point init_rnd = pm.sample_prior_predictive(draws, model=model) for v in variables: var_info[v.name] = (start[v.name].shape, start[v.name].size) for i in range(draws): point = pm.Point({v.name: init_rnd[v.name][i] for v in variables}, model=model) population.append(model.dict_to_array(point)) return np.array(floatX(population)), var_info
def too_slow(self): model = self.build_model() with model: start = pm.Point({ 'groupmean': self.obs_means.mean(), 'groupsd_interval__': 0, 'sd_interval__': 0, 'means': np.array(self.obs_means), 'u_m': np.array([.72]), 'floor_m': 0., }) start = pm.find_MAP(start, model.vars[:-1]) H = model.fastd2logp() h = np.diag(H(start)) step = pm.HamiltonianMC(model.vars, h) pm.sample(50, step=step, start=start)
def too_slow(self): model = self.build_model() with model: start = pm.Point({ "groupmean": self.obs_means.mean(), "groupsd_interval__": 0, "sd_interval__": 0, "means": np.array(self.obs_means), "u_m": np.array([0.72]), "floor_m": 0.0, }) start = pm.find_MAP(start, model.vars[:-1]) H = model.fastd2logp() h = np.diag(H(start)) step = pm.HamiltonianMC(model.vars, h) pm.sample(50, step=step, start=start)
def _initial_population(samples, chains, model, variables): """ Create an initial population from the prior """ population = [] init_rnd = {} start = model.test_point for v in variables: if pm.util.is_transformed_name(v.name): trans = v.distribution.transform_used.forward_val init_rnd[v.name] = trans(v.distribution.dist.random(size=chains, point=start)) else: init_rnd[v.name] = v.random(size=chains, point=start) for i in range(chains): population.append(pm.Point({v.name: init_rnd[v.name][i] for v in variables}, model=model)) return population
def __init__(self, vars=None, out_vars=None, n_chains=100, scaling=1., covariance=None, likelihood_name='like', proposal_name='MultivariateNormal', tune=True, tune_interval=100, coef_variation=1., check_bound=True, model=None, random_seed=-1): warnings.warn(EXPERIMENTAL_WARNING) if random_seed != -1: nr.seed(random_seed) model = modelcontext(model) if vars is None: vars = model.vars vars = inputvars(vars) if out_vars is None: out_vars = model.unobserved_RVs out_varnames = [out_var.name for out_var in out_vars] if covariance is None and proposal_name == 'MultivariateNormal': self.covariance = np.eye(sum(v.dsize for v in vars)) scale = self.covariance elif covariance is None: scale = np.ones(sum(v.dsize for v in vars)) else: scale = covariance self.scaling = np.atleast_1d(scaling) self.tune = tune self.check_bnd = check_bound self.tune_interval = tune_interval self.steps_until_tune = tune_interval self.proposal_name = proposal_name self.proposal_dist = choose_proposal(self.proposal_name, scale=scale) self.proposal_samples_array = self.proposal_dist(n_chains) self.stage_sample = 0 self.accepted = 0 self.beta = 0 self.stage = 0 self.chain_index = 0 self.resampling_indexes = np.arange(n_chains) self.coef_variation = coef_variation self.n_chains = n_chains self.likelihoods = np.zeros(n_chains) self.likelihood_name = likelihood_name self._llk_index = out_varnames.index(likelihood_name) self.discrete = np.concatenate( [[v.dtype in discrete_types] * (v.dsize or 1) for v in vars]) self.any_discrete = self.discrete.any() self.all_discrete = self.discrete.all() # create initial population self.population = [] self.array_population = np.zeros(n_chains) for _ in range(self.n_chains): self.population.append( pm.Point({v.name: v.random() for v in vars}, model=model)) self.chain_previous_lpoint = copy.deepcopy(self.population) shared = make_shared_replacements(vars, model) self.logp_forw = logp_forw(out_vars, vars, shared) self.check_bnd = logp_forw([model.varlogpt], vars, shared) super(SMC, self).__init__(vars, out_vars, shared)
def __init__(self, vars=None, out_vars=None, samples=1000, n_chains=100, n_steps=25, scaling=1., covariance=None, likelihood_name='l_like__', proposal_name='MultivariateNormal', tune_interval=10, threshold=0.5, check_bound=True, model=None, random_seed=-1): warnings.warn(EXPERIMENTAL_WARNING) if random_seed != -1: nr.seed(random_seed) model = modelcontext(model) if vars is None: vars = model.vars vars = inputvars(vars) if out_vars is None: if not any(likelihood_name == RV.name for RV in model.unobserved_RVs): pm._log.info('Adding model likelihood to RVs!') with model: llk = pm.Deterministic(likelihood_name, model.logpt) else: pm._log.info('Using present model likelihood!') out_vars = model.unobserved_RVs out_varnames = [out_var.name for out_var in out_vars] if covariance is None and proposal_name == 'MultivariateNormal': self.covariance = np.eye(sum(v.dsize for v in vars)) scale = self.covariance elif covariance is None: scale = np.ones(sum(v.dsize for v in vars)) else: scale = covariance self.proposal_name = proposal_name self.proposal_dist = choose_proposal(self.proposal_name, scale=scale) self.scaling = np.atleast_1d(scaling) self.check_bnd = check_bound self.tune_interval = tune_interval self.steps_until_tune = tune_interval self.proposal_samples_array = self.proposal_dist(n_chains) self.samples = samples self.n_steps = n_steps self.stage_sample = 0 self.accepted = 0 self.beta = 0 self.sjs = 1 self.stage = 0 self.chain_index = 0 self.resampling_indexes = np.arange(n_chains) self.threshold = threshold self.n_chains = n_chains self.likelihoods = np.zeros(n_chains) self.likelihood_name = likelihood_name self._llk_index = out_varnames.index(likelihood_name) self.discrete = np.concatenate( [[v.dtype in discrete_types] * (v.dsize or 1) for v in vars]) self.any_discrete = self.discrete.any() self.all_discrete = self.discrete.all() # create initial population self.population = [] self.array_population = np.zeros(n_chains) start = model.test_point init_rnd = {} for v in vars: if pm.util.is_transformed_name(v.name): trans = v.distribution.transform_used.forward rnd = trans( v.distribution.dist.random(size=self.n_chains, point=start)) init_rnd[v.name] = rnd.eval() else: init_rnd[v.name] = v.random(size=self.n_chains, point=start) for i in range(self.n_chains): self.population.append( pm.Point({v.name: init_rnd[v.name][i] for v in vars}, model=model)) self.chain_previous_lpoint = copy.deepcopy(self.population) shared = make_shared_replacements(vars, model) self.logp_forw = logp_forw(out_vars, vars, shared) self.check_bnd = logp_forw([model.varlogpt], vars, shared) super(SMC, self).__init__(vars, out_vars, shared)