core.result.Result

core.result.Result(file_name=None, dictionary=None)

A dataset class to hold a collection of samples, implementing I/O, importance sampling, and unconditional flow training.

Attributes: samples : pd.Dataframe Contains parameter samples, as well as (possibly) log_prob, log_likelihood, weights, log_prior, delta_log_prob_target. domain : Domain Should be implemented in a subclass. prior : PriorDict Should be implemented in a subclass. likelihood : Likelihood Should be implemented in a subclass. context : dict Context data from which the samples were produced (e.g., strain data, ASDs). metadata : dict event_metadata : dict log_evidence : float log_evidence_std : float (property) effective_sample_size, n_eff : float (property) sample_efficiency : float (property)

Attributes

Name Description
base_metadata
constraint_parameter_keys
context
dataset_type
effective_sample_size
event_metadata
fixed_parameter_keys
importance_sampling_metadata
injection_parameters
log_bayes_factor
log_evidence_std
log_noise_evidence
metadata
n_eff
num_samples
sample_efficiency
samples
search_parameter_keys

Methods

Name Description
get_all_injection_credible_levels Get credible levels for all parameters.
get_injection_credible_level Get the credible level of the injected parameter.
importance_sample Calculate importance weights for samples.
merge Merge several Result instances into one. Check that they are compatible,
parameter_subset Return a new object of the same type, with only a subset of parameters. Drops
plot_corner Generate a corner plot of the samples.
plot_log_probs Make a scatter plot of the target versus proposal log probabilities. For the
plot_weights Make a scatter plot of samples weights vs log proposal.
print_summary Display the number of samples, and (if importance sampling is complete) the log
rejection_sample Generate unweighted posterior samples from weighted ones via rejection sampling.
reset_event Set the Result context and event_metadata based on an EventDataset.
sampling_importance_resampling Generate unweighted posterior samples from weighted ones. New
split Split the Result into a set of smaller results. The samples are evenly divided
train_unconditional_flow Train an unconditional flow to represent the distribution of self.samples.

get_all_injection_credible_levels

core.result.Result.get_all_injection_credible_levels(keys=None, weighted=False)

Get credible levels for all parameters.

Adapted from Bilby.

Parameters

keys: list, optional A list of keys for which return the credible levels, if None, defaults to search_parameter_keys weighted: bool, optional Whether to use sample weights in calculating credible level.

Returns

credible_levels: dict The credible levels at which the injected parameters are found.

get_injection_credible_level

core.result.Result.get_injection_credible_level(parameter, weighted=False)

Get the credible level of the injected parameter.

Calculated as CDF(injection value).

Adapted from Bilby.

Parameters

parameter: str Parameter to get credible level for weighted: bool, optional Whether to use sample weights in calculating credible level.

Returns

float: credible level

importance_sample

core.result.Result.importance_sample(num_processes=1, **likelihood_kwargs)

Calculate importance weights for samples.

Importance sampling starts with samples have been generated from a proposal distribution q(theta), in this case a neural network model. Certain networks (i.e., non-GNPE) also provide the log probability of each sample, which is required for importance sampling.

Given the proposal, we re-weight samples according to the (un-normalized) target distribution, which we take to be the likelihood L(theta) times the prior pi(theta). This gives sample weights

w(theta) ~ pi(theta) L(theta) / q(theta),

where the overall normalization does not matter (and we take to have mean 1). Since q(theta) enters this expression, importance sampling is only possible when we know the log probability of each sample.

As byproducts, this method also estimates the evidence and effective sample size of the importance sampled points.

This method modifies the samples pd.DataFrame in-place, adding new columns for log_likelihood, log_prior, and weights. It also stores the log_evidence as an attribute.

Parameters

Name Type Description Default
num_processes int Number of parallel processes to use when calculating likelihoods. (This is the most expensive task.) 1
likelihood_kwargs dict kwargs that are forwarded to the likelihood constructor. E.g., options for marginalization. {}

merge

core.result.Result.merge(parts)

Merge several Result instances into one. Check that they are compatible, in the sense of having the same metadata. Finally, calculate a new log evidence for the combined result.

This is useful when recombining separate importance sampling jobs.

Parameters

Name Type Description Default
parts list[Result] List of sub-Results to be combined. required

Returns

Name Type Description
Combined Result.

parameter_subset

core.result.Result.parameter_subset(parameters)

Return a new object of the same type, with only a subset of parameters. Drops all other columns in samples DataFrame as well (e.g., log_prob, weights).

Parameters

Name Type Description Default
parameters list List of parameters to keep. required

Returns

Name Type Description
Result

plot_corner

core.result.Result.plot_corner(parameters=None, filename='corner.pdf', **kwargs)

Generate a corner plot of the samples.

Parameters

Name Type Description Default
parameters list[str] List of parameters to include. If None, include all parameters. (Default: None) None
filename str Where to save samples. 'corner.pdf'

Other Parameters

Name Type Description Default
legend_font_size Font size of the legend. required

plot_log_probs

core.result.Result.plot_log_probs(filename='log_probs.png')

Make a scatter plot of the target versus proposal log probabilities. For the target, subtract off the log evidence.

plot_weights

core.result.Result.plot_weights(filename='weights.png')

Make a scatter plot of samples weights vs log proposal.

print_summary

core.result.Result.print_summary()

Display the number of samples, and (if importance sampling is complete) the log evidence and number of effective samples.

rejection_sample

core.result.Result.rejection_sample(
    max_samples_per_draw=1,
    clip_weights=False,
    random_state=None,
)

Generate unweighted posterior samples from weighted ones via rejection sampling.

Each original sample contributes at most max_samples_per_draw copies to the output, so the result avoids the excessive duplication that :meth:sampling_importance_resampling can produce for high-weight samples.

Algorithm (unbiased, maximum efficiency)

The weights are first scaled so that the largest weight equals max_samples_per_draw. Each sample i then contributes

  • floor(w_scaled[i]) copies deterministically (integer part), and
  • one additional copy with probability w_scaled[i] - floor(w_scaled[i]) (fractional part, a single Bernoulli draw).

The expected number of copies of sample i is therefore exactly w_scaled[i] ∝ w[i], which guarantees an unbiased representation of the posterior. Using the integer part deterministically (rather than rounding stochastically) maximises the expected total number of output samples for a given max_samples_per_draw.

Optional weight clipping

When clip_weights=True, the ceil(sqrt(N)) largest weights are replaced by their mean and the weights are re-normalized to mean 1 before rejection sampling. This number of clips is the theoretically optimal choice that yields asymptotically unbiased results [1]_. Using the mean (rather than the minimum) of the clipped group preserves their total weight, which minimises the bias introduced by clipping. The net effect is reduced weight variance and a larger expected number of output samples.

If the samples DataFrame has no weights column the samples are already unweighted and are returned unchanged.

Parameters

Name Type Description Default
max_samples_per_draw int Maximum number of copies any single input sample may contribute to the output. Default is 1 (standard rejection sampling, no duplicates). 1
clip_weights bool Whether to clip the ceil(sqrt(N)) largest weights to their mean before rejection sampling. Default is False. False
random_state int or None Seed for the random number generator, for reproducibility. None

Returns

Name Type Description
pd.DataFrame Unweighted samples (the weights column is dropped).

References

.. [1] Elvira et al., “A Comparison Of Clipping Strategies For Importance Sampling” https://ieeexplore.ieee.org/document/8450722

reset_event

core.result.Result.reset_event(event_dataset)

Set the Result context and event_metadata based on an EventDataset.

If these attributes already exist, perform a comparison to check for changes. Update relevant objects appropriately. Note that setting context and event_metadata attributes directly would not perform these additional checks and updates.

Parameters

Name Type Description Default
event_dataset New event to be used for importance sampling. required

sampling_importance_resampling

core.result.Result.sampling_importance_resampling(
    num_samples=None,
    random_state=None,
)

Generate unweighted posterior samples from weighted ones. New samples are sampled with probability proportional to the sample weight. Resampling is done with replacement, until the desired number of unweighted samples is obtained.

Parameters

Name Type Description Default
num_samples int Number of samples to resample. None
random_state int or None Sampling seed. None

Returns

Name Type Description
pd.Dataframe Unweighted samples

split

core.result.Result.split(num_parts)

Split the Result into a set of smaller results. The samples are evenly divided among the sub-results. Additional information (metadata, context, etc.) are copied into each.

This is useful for splitting expensive tasks such as importance sampling across multiple jobs.

Parameters

Name Type Description Default
num_parts int The number of parts to split the Result across. required

Returns

Name Type Description
list of sub-Results.

train_unconditional_flow

core.result.Result.train_unconditional_flow(
    parameters,
    nde_settings,
    train_dir=None,
    threshold_std=np.inf,
)

Train an unconditional flow to represent the distribution of self.samples.

Parameters

Name Type Description Default
parameters list List of parameters over which to train the flow. Can be a subset of the existing parameters. required
nde_settings dict Configuration settings for the neural density estimator. required
train_dir Optional[str] Where to save the output of network training, e.g., logs, checkpoints. If not provide, a temporary directory is used. None
threshold_std Optional[float] Drop samples more than threshold_std standard deviations away from the mean (in any parameter) before training the flow. This is meant to remove outlier samples. np.inf

Returns

Name Type Description
PosteriorModel