Inference and posterior products#

Every inference method returns the common SamplerResult interface for diagnostics, posterior component draws, and power-spectrum stacks.

Inference methods and posterior products for ML-GPR.

Each sampler explores a MultiGPRegressor and returns the same SamplerResult interface:

res = MCMCSampler(gp, n_walkers=40).run(n_steps=300)
res.plot_corner()
ps = res.get_ps_stack(ps_gen, kbins, kern_name='eor*')

Use MCMCSampler as the general-purpose default, NestedSampler for evidence or multimodal posteriors, MAPOptimizer for a fast local approximation, and NUTSSampler for gradient-based posterior sampling.

class ps_eor.ml_gpr.samplers.MCMCSamples(samples, log_prob, n_burn=50, clip_nsigma=6, discard_walkers_nsigma=10, autocorr_time=None)[source]#

Bases: object

Raw chains produced by MCMCSampler.

get() removes burn-in, poorly converged walkers, and outliers.

get()[source]#

Return filtered posterior samples and log probabilities.

save(filename)[source]#

Save the chains and filtering settings to HDF5.

static load(filename)[source]#

Load chains saved with save().

class ps_eor.ml_gpr.samplers.NestedSamples(d)[source]#

Bases: Results

Dynesty results with the common sample-container interface.

get() returns equal-weight samples by default. logz contains the Bayesian evidence.

get(resample_equal=True)[source]#

Return posterior samples and likelihoods, optionally equal-weighted.

save(filename)[source]#

Save serializable Dynesty results to HDF5.

static load(filename)[source]#

Load nested-sampling results saved with save().

class ps_eor.ml_gpr.samplers.MAPSamples(samples, log_prob)[source]#

Bases: object

MAP point followed by draws from its Laplace approximation.

Row zero is the MAP. Remaining rows approximate uncertainty and should not be interpreted as exact posterior samples.

get()[source]#

Return samples and their MAP/Laplace log probabilities.

save(filename)[source]#

Save samples to HDF5.

static load(filename)[source]#

Load samples saved with save().

class ps_eor.ml_gpr.samplers.NUTSSamples(samples, log_prob)[source]#

Bases: object

Posterior draws produced by NUTSSampler.

get()[source]#

Return posterior samples and log probabilities.

save(filename)[source]#

Save posterior samples to HDF5.

static load(filename)[source]#

Load posterior samples saved with save().

class ps_eor.ml_gpr.samplers.SamplerResult(gp, samples, diagnostics=None)[source]#

Bases: object

Posterior samples and component predictions from any sampler.

Prediction methods propagate hyperparameter uncertainty by drawing a new cube at each posterior sample. For multi-epoch results, epoch may be 'combine', 'all', or an integer index.

get_parameter_names()[source]#

Names of the free parameters, e.g. 'fg_int.variance'.

get_n_params()[source]#

Number of free parameters.

get_parameter_samples(param_name)[source]#

All samples of one parameter, in sampling space.

plot_samples()[source]#

Plot parameter traces for convergence and burn-in inspection.

plot_samples_likelihood(p_true=None)[source]#

Plot log posterior against each parameter.

plot_corner(fig=None, plot_prior=True, **kargs_corner)[source]#

Plot the posterior, optionally shading prior quantile ranges.

select_random_sample(samples=None, rng=None)[source]#

Set the kernels to one random posterior sample.

generate_data_cubes(n_pick, kern_name='eor', fill_gaps=False, epoch='combine')[source]#

Return component cubes drawn at n_pick posterior samples.

kern_name accepts component-label patterns such as 'eor*'. For a shared-fraction time kernel, append ':coherent' or ':independent' to select one latent process.

Repeated calls intentionally produce different posterior realizations. Seed NumPy and Torch before calling for reproducible draws.

get_interpolated_i_cube(epoch='combine')[source]#

The data with flagged channels filled in, at one posterior sample.

get_ps_stack(ps_gen, kbins, n_pick=100, kern_name='eor', subtract_from=None, fill_gaps=False, epoch='combine')[source]#

Return component power spectra over posterior realizations.

If subtract_from is provided, spectra of subtract_from - component are accumulated instead. Repeated calls intentionally use new posterior realizations; seed NumPy and Torch before calling for reproducible results.

class ps_eor.ml_gpr.samplers.AbstractSampler(gp)[source]#

Bases: object

Base class for inference methods operating on one regressor.

get_parameter_names()[source]#

Return free parameter names in sampler-vector order.

get_result()[source]#

SamplerResult for the run so far. Subclasses implement this; run() calls it and returns the result.

log_marginal_likelihood(p)[source]#

Evaluate the likelihood at sampling-space vector p.

prior_transform(uu)[source]#

Transform a unit-cube vector into sampling space.

class ps_eor.ml_gpr.samplers.MAPOptimizer(gp, n_restarts=4, n_laplace_samples=2000, optimizer_cls=None, debug=False, validate_feasible=False)[source]#

Bases: AbstractSampler

Find the MAP and approximate local uncertainty with Laplace draws.

This is fast, but its uncertainty assumes a locally Gaussian posterior. Check result.diagnostics['laplace_valid'] before using the error bars.

Parameters:
  • n_restarts – independent optimizations from different starting points; the best is kept. Guards against local optima.

  • n_laplace_samples – draws from the Gaussian around the MAP, which become the “samples” downstream code uses for uncertainty.

  • optimizer_cls – torch optimizer, LBFGS by default.

  • validate_feasible – Check that every Laplace draw produces a valid covariance. This is slower and normally unnecessary.

run(n_steps, lr=1.0, verbose=False)[source]#

Optimize to the MAP and return a SamplerResult.

Parameters:
  • n_steps – optimizer steps per restart.

  • lr – learning rate.

  • verbose – report the loss of each restart.

Leaves the kernels at the best-fit hyperparameters.

get_result()[source]#

SamplerResult holding the MAP point plus its Laplace approximation.

Computes the Hessian and draws within the priors’ hard bounds.

class ps_eor.ml_gpr.samplers.MCMCSampler(gp, n_walkers, emcee_moves='stretch', debug=False)[source]#

Bases: AbstractSampler

Ensemble MCMC via emcee – the dependable default.

Gradient-free and robust. Walkers start from prior draws, so n_walkers should comfortably exceed the number of free parameters. run(n_steps) discards a burn-in before returning; check SamplerResult.plot_samples() to confirm the chains have converged before trusting the result.

run(n_steps, verbose=False, live_update=False, n_burn=50, clip_nsigma=6, discard_walkers_nsigma=10)[source]#

Run n_steps of ensemble MCMC and return the result.

Walkers start from prior draws. n_steps counts steps per walker, so the total number of likelihood evaluations is n_steps * n_walkers. n_burn and the clipping controls determine which chain samples are retained in the returned result. live_update displays traces in a notebook.

get_result(n_burn=50, clip_nsigma=6, discard_walkers_nsigma=10)[source]#

SamplerResult for the chains sampled so far.

Parameters:
  • n_burn – initial steps to discard. Set it from the trace plot rather than trusting the default.

  • clip_nsigma – drop samples this far from the median of a parameter.

  • discard_walkers_nsigma – drop whole walkers stuck at a much worse likelihood than the rest, i.e. never converged.

class ps_eor.ml_gpr.samplers.NestedSampler(gp, nlive=500, bound='multi', sample='auto', **kargs_dynesty)[source]#

Bases: AbstractSampler

Nested sampling via dynesty.

Handles multimodal posteriors and provides Bayesian evidence for model comparison.

run(live_update=False, **kargs_dynesty)[source]#

Run to convergence and return a SamplerResult.

Extra keyword arguments go to dynesty’s own run_nested, e.g. dlogz. Interrupting the run keeps whatever has been sampled.

get_result()[source]#

SamplerResult for the run so far. The underlying samples also carry the Bayesian evidence, for model comparison.

class ps_eor.ml_gpr.samplers.UltraNestNestedSampler(gp, nlive=500, bound='multi', **kargs_ultranest)[source]#

Bases: AbstractSampler

Nested sampling through the optional UltraNest dependency.

run(live_update=False, **kargs_ultranest)[source]#

Run to convergence and return a SamplerResult.

Extra keyword arguments go to ultranest’s own run. Interrupting the run keeps whatever has been sampled.

get_result()[source]#

SamplerResult for the run so far.

class ps_eor.ml_gpr.samplers.NUTSSampler(gp, warmup_steps=500, num_chains=1, max_tree_depth=8, target_accept_prob=0.8, full_mass=False, warm_start_map=False, debug=False)[source]#

Bases: AbstractSampler

No-U-Turn sampling through Pyro.

NUTS can sample strongly correlated posteriors more efficiently than gradient-free MCMC. Always inspect divergences, effective sample sizes, and r_hat before using the result.

Parameters:
  • warmup_steps – Adaptation steps; several hundred are usually needed.

  • max_tree_depth – Maximum trajectory depth and primary runtime control.

  • target_accept_prob – Increase to reduce step size when chains diverge.

  • full_mass – Adapt a dense mass matrix for correlated parameters.

  • warm_start_map – Initialize at the MAP instead of a prior draw.

run(n_steps, verbose=False, seed=None)[source]#

Run NUTS and return samples with convergence diagnostics.

n_steps is the number of retained posterior draws per chain; warmup_steps additional adaptation steps are discarded. Multiple chains run sequentially because the stateless likelihood is not process-pickleable. The result records divergences, effective sample sizes, and split r_hat. Use at least four chains for a robust convergence assessment.

summary()[source]#

Print per-parameter between-chain ESS and r_hat from the last run.