def __init__(self, vars=None, num_particles=10, max_stages=5000, chunk="auto", model=None): _log.warning("The BART model is experimental. Use with caution.") model = modelcontext(model) vars = inputvars(vars) self.bart = vars[0].distribution self.tune = True self.idx = 0 self.iter = 0 self.sum_trees = [] self.chunk = chunk if chunk == "auto": self.chunk = max(1, int(self.bart.m * 0.1)) self.bart.chunk = self.chunk self.num_particles = num_particles self.log_num_particles = np.log(num_particles) self.indices = list(range(1, num_particles)) self.max_stages = max_stages self.old_trees_particles_list = [] for i in range(self.bart.m): p = ParticleTree(self.bart.trees[i], self.bart.prior_prob_leaf_node) self.old_trees_particles_list.append(p) shared = make_shared_replacements(vars, model) self.likelihood_logp = logp([model.datalogpt], vars, shared) super().__init__(vars, shared)
def __init__(self, vars=None, w=1.0, tune=True, model=None, iter_limit=np.inf, **kwargs): self.model = modelcontext(model) self.w = w self.tune = tune self.n_tunes = 0.0 self.iter_limit = iter_limit if vars is None: vars = self.model.cont_vars vars = inputvars(vars) super().__init__(vars, [self.model.fastlogp], **kwargs)
def __init__(self, vars=None, prior_cov=None, prior_chol=None, model=None, **kwargs): self.model = modelcontext(model) chol = get_chol(prior_cov, prior_chol) self.prior_chol = at.as_tensor_variable(chol) if vars is None: vars = self.model.cont_vars vars = inputvars(vars) super().__init__(vars, [self.model.fastlogp], **kwargs)
def __new__(cls, *args, **kwargs): blocked = kwargs.get("blocked") if blocked is None: # Try to look up default value from class blocked = getattr(cls, "default_blocked", True) kwargs["blocked"] = blocked model = modelcontext(kwargs.get("model")) kwargs.update({"model": model}) # vars can either be first arg or a kwarg if "vars" not in kwargs and len(args) >= 1: vars = args[0] args = args[1:] elif "vars" in kwargs: vars = kwargs.pop("vars") else: # Assume all model variables vars = model.vars # get the actual inputs from the vars vars = inputvars(vars) if len(vars) == 0: raise ValueError("No free random variables to sample.") if not blocked and len(vars) > 1: # In this case we create a separate sampler for each var # and append them to a CompoundStep steps = [] for var in vars: step = super().__new__(cls) # If we don't return the instance we have to manually # call __init__ step.__init__([var], *args, **kwargs) # Hack for creating the class correctly when unpickling. step.__newargs = ([var], ) + args, kwargs steps.append(step) return CompoundStep(steps) else: step = super().__new__(cls) # Hack for creating the class correctly when unpickling. step.__newargs = (vars, ) + args, kwargs return step
def __init__( self, draws=2000, kernel="metropolis", n_steps=25, start=None, tune_steps=True, p_acc_rate=0.85, threshold=0.5, save_sim_data=False, save_log_pseudolikelihood=True, model=None, random_seed=-1, chain=0, ): self.draws = draws self.kernel = kernel.lower() self.n_steps = n_steps self.start = start self.tune_steps = tune_steps self.p_acc_rate = p_acc_rate self.threshold = threshold self.save_sim_data = save_sim_data self.save_log_pseudolikelihood = save_log_pseudolikelihood self.model = model self.random_seed = random_seed self.chain = chain self.model = modelcontext(model) if self.random_seed != -1: np.random.seed(self.random_seed) self.beta = 0 self.max_steps = n_steps self.proposed = draws * n_steps self.acc_rate = 1 self.variables = inputvars(self.model.value_vars) self.weights = np.ones(self.draws) / self.draws self.log_marginal_likelihood = 0 self.sim_data = [] self.log_pseudolikelihood = []
def __init__(self, model=None): # Get the model self.model = pm.modelcontext(model) # Get the variables self.varnames = get_default_varnames(self.model.unobserved_RVs, False) # Get the starting point self.start = Point(self.model.test_point, model=self.model) self.ndim = len(self.start) self.mean = None self.cov = None # Compile the log probability function self.vars = inputvars(self.model.cont_vars) self.bij = DictToArrayBijection(ArrayOrdering(self.vars), self.start) self.func = get_theano_function_for_var( self.model.logpt, model=self.model )
def fixed_hessian(point, vars=None, model=None): """ Returns a fixed Hessian for any chain location. Parameters ---------- model: Model (optional if in `with` context) point: dict vars: list Variables for which Hessian is to be calculated. """ model = modelcontext(model) if vars is None: vars = model.cont_vars vars = inputvars(vars) point = Point(point, model=model) rval = np.ones(DictToArrayBijection.map(point).size) / 10 return rval
def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False, model=None, blocked=True, potential=None, dtype=None, Emax=1000, target_accept=0.8, gamma=0.05, k=0.75, t0=10, adapt_step_size=True, step_rand=None, **aesara_kwargs): """Set up Hamiltonian samplers with common structures. Parameters ---------- vars: list of aesara variables scaling: array_like, ndim = {1,2} Scaling for momentum distribution. 1d arrays interpreted matrix diagonal. step_scale: float, default=0.25 Size of steps to take, automatically scaled down by 1/n**(1/4) is_cov: bool, default=False Treat scaling as a covariance matrix/vector if True, else treat it as a precision matrix/vector model: pymc3 Model instance blocked: bool, default=True potential: Potential, optional An object that represents the Hamiltonian with methods `velocity`, `energy`, and `random` methods. **aesara_kwargs: passed to aesara functions """ self._model = modelcontext(model) if vars is None: vars = self._model.cont_vars vars = inputvars(vars) super().__init__(vars, blocked=blocked, model=model, dtype=dtype, **aesara_kwargs) self.adapt_step_size = adapt_step_size self.Emax = Emax self.iter_count = 0 size = self._logp_dlogp_func.size self.step_size = step_scale / (size**0.25) self.step_adapt = step_sizes.DualAverageAdaptation( self.step_size, target_accept, gamma, k, t0) self.target_accept = target_accept self.tune = True if scaling is None and potential is None: mean = floatX(np.zeros(size)) var = floatX(np.ones(size)) potential = QuadPotentialDiagAdapt(size, mean, var, 10) if isinstance(scaling, dict): point = Point(scaling, model=model) scaling = guess_scaling(point, model=model, vars=vars) if scaling is not None and potential is not None: raise ValueError("Can not specify both potential and scaling.") if potential is not None: self.potential = potential else: self.potential = quad_potential(scaling, is_cov) self.integrator = integration.CpuLeapfrogIntegrator( self.potential, self._logp_dlogp_func) self._step_rand = step_rand self._warnings = [] self._samples_after_tune = 0 self._num_divs_sample = 0
def find_MAP( start=None, vars=None, method="L-BFGS-B", return_raw=False, include_transformed=True, progressbar=True, maxeval=5000, model=None, *args, **kwargs ): """ Finds the local maximum a posteriori point given a model. find_MAP should not be used to initialize the NUTS sampler. Simply call pymc3.sample() and it will automatically initialize NUTS in a better way. Parameters ---------- start: `dict` of parameter values (Defaults to `model.test_point`) vars: list List of variables to optimize and set to optimum (Defaults to all continuous). method: string or callable Optimization algorithm (Defaults to 'L-BFGS-B' unless discrete variables are specified in `vars`, then `Powell` which will perform better). For instructions on use of a callable, refer to SciPy's documentation of `optimize.minimize`. return_raw: bool Whether to return the full output of scipy.optimize.minimize (Defaults to `False`) include_transformed: bool, optional defaults to True Flag for reporting automatically transformed variables in addition to original variables. progressbar: bool, optional defaults to True Whether or not to display a progress bar in the command line. maxeval: int, optional, defaults to 5000 The maximum number of times the posterior distribution is evaluated. model: Model (optional if in `with` context) *args, **kwargs Extra args passed to scipy.optimize.minimize Notes ----- Older code examples used find_MAP() to initialize the NUTS sampler, but this is not an effective way of choosing starting values for sampling. As a result, we have greatly enhanced the initialization of NUTS and wrapped it inside pymc3.sample() and you should thus avoid this method. """ model = modelcontext(model) if vars is None: vars = model.cont_vars if not vars: raise ValueError("Model has no unobserved continuous variables.") vars = inputvars(vars) disc_vars = list(typefilter(vars, discrete_types)) allinmodel(vars, model) start = copy.deepcopy(start) if start is None: start = model.test_point else: update_start_vals(start, model.test_point, model) check_start_vals(start, model) start = Point(start, model=model) bij = DictToArrayBijection(ArrayOrdering(vars), start) logp_func = bij.mapf(model.fastlogp_nojac) x0 = bij.map(start) try: dlogp_func = bij.mapf(model.fastdlogp_nojac(vars)) compute_gradient = True except (AttributeError, NotImplementedError, tg.NullTypeGradError): compute_gradient = False if disc_vars or not compute_gradient: pm._log.warning( "Warning: gradient not available." + "(E.g. vars contains discrete variables). MAP " + "estimates may not be accurate for the default " + "parameters. Defaulting to non-gradient minimization " + "'Powell'." ) method = "Powell" if compute_gradient: cost_func = CostFuncWrapper(maxeval, progressbar, logp_func, dlogp_func) else: cost_func = CostFuncWrapper(maxeval, progressbar, logp_func) try: opt_result = minimize(cost_func, x0, method=method, jac=compute_gradient, *args, **kwargs) mx0 = opt_result["x"] # r -> opt_result except (KeyboardInterrupt, StopIteration) as e: mx0, opt_result = cost_func.previous_x, None if isinstance(e, StopIteration): pm._log.info(e) finally: last_v = cost_func.n_eval if progressbar: assert isinstance(cost_func.progress, ProgressBar) cost_func.progress.total = last_v cost_func.progress.update(last_v) print() vars = get_default_varnames(model.unobserved_RVs, include_transformed) mx = {var.name: value for var, value in zip(vars, model.fastfn(vars)(bij.rmap(mx0)))} if return_raw: return mx, opt_result else: return mx