Esempio n. 1
0
def test_simple_inference_can_be_run():
    n_samples = 4
    true_params = [0.5, 0.5]  # t1, t2
    for sampling_type in ["grid", "uniform", "BO"]:
        params = BolfiParams(bounds=((0, 1), (0, 1)),
                             n_samples=n_samples,
                             n_initial_evidence=2,
                             sampling_type=sampling_type,
                             grid_tics=[[0.25, 0.75], [0.33, 0.66]],
                             seed=1,
                             simulator_node_name="MA2",
                             discrepancy_node_name="d")
        model = get_model(n_obs=1000, true_params=true_params, seed_obs=1)
        results = list()
        bf = BolfiFactory(model, params)
        exp = bf.get()
        exp.do_sampling()
        exp.compute_samples_and_ML()
        assert len(exp.samples) == n_samples
        assert exp.ML_val is not None
        exp.compute_posterior()
        assert exp.post is not None
        exp.compute_MAP()
        assert exp.MAP_val is not None
        ML_sim = exp.simulate_data(exp.ML)
        MAP_sim = exp.simulate_data(exp.MAP)
        ML_disc = exp.compute_discrepancy_with_data(exp.ML, ML_sim)
        MAP_disc = exp.compute_discrepancy_with_data(exp.MAP, MAP_sim)
Esempio n. 2
0
def test_multi_parameter_linear_adjustment():
    """A regression test against values obtained in the notebook."""
    seed = 20170511
    threshold = 0.2
    batch_size = 1000
    n_samples = 500
    m = ma2.get_model(true_params=[0.6, 0.2], seed_obs=seed)

    summary_names = ['S1', 'S2']
    parameter_names = ['t1', 't2']
    linear_adjustment = LinearAdjustment()

    res = elfi.Rejection(
        m['d'],
        batch_size=batch_size,
        output_names=['S1', 'S2'],
        # output_names=summary_names, # fails ?!?!?
        seed=seed).sample(
            n_samples, threshold=threshold)
    adjusted = adjust_posterior(
        model=m,
        sample=res,
        parameter_names=parameter_names,
        summary_names=summary_names,
        adjustment=linear_adjustment)
    t1 = adjusted.outputs['t1']
    t2 = adjusted.outputs['t2']

    t1_mean, t1_var = (0.51606048286584782, 0.017253007645871756)
    t2_mean, t2_var = (0.15805189695581101, 0.028004406914362647)
    assert np.allclose(_statistics(t1), (t1_mean, t1_var))
    assert np.allclose(_statistics(t2), (t2_mean, t2_var))
Esempio n. 3
0
def setup_ma2_with_informative_data():
    true_params = OrderedDict([('t1', .6), ('t2', .2)])
    n_obs = 100

    # In our implementation, seed 4 gives informative (enough) synthetic observed
    # data of length 100 for quite accurate inference of the true parameters using
    # posterior mean as the point estimate
    m = ma2.get_model(n_obs=n_obs, true_params=true_params.values(), seed_obs=4)
    return m, true_params
Esempio n. 4
0
def test_observed():
    true_params = [.6, .2]
    m = ema2.get_model(100, true_params=true_params)
    y = m.observed['MA2']
    S1 = m.get_reference('S1')
    S2 = m.get_reference('S2')

    S1_observed = ema2.autocov(y)
    S2_observed = ema2.autocov(y, 2)

    assert np.array_equal(S1.observed, S1_observed)
    assert np.array_equal(S2.observed, S2_observed)
Esempio n. 5
0
def test_sample_object_to_dict():
    data_rej = OrderedDict()
    data_smc = OrderedDict()
    m = get_model(n_obs=100, true_params=[.6, .2])
    batch_size, n = 1, 2
    schedule = [0.7, 0.2, 0.05]
    rej = elfi.Rejection(m['d'], batch_size=batch_size)
    res_rej = rej.sample(n, threshold=0.1)
    smc = elfi.SMC(m['d'], batch_size=batch_size)
    res_smc = smc.sample(n, schedule)
    sample_object_to_dict(data_rej, res_rej)
    sample_object_to_dict(data_smc, res_smc, skip='populations')
    assert any(x not in data_rej for x in ['meta', 'output']) is True
    assert any(x not in data_smc for x in ['meta', 'output', 'populations']) is True
Esempio n. 6
0
def test_pickle_ma2():
    m = ma2.get_model()
    d = m.get_reference('d')

    np.random.seed(0)
    res1 = d.generate(10)

    serialized = pickle.dumps(m)
    m = pickle.loads(serialized)
    d = m.get_reference('d')

    np.random.seed(0)
    res2 = d.generate(10)

    assert np.array_equal(res1, res2)
Esempio n. 7
0
def test_simple_inference_experiment_can_be_run():
    n_samples = 4
    true_params = [0.5, 0.5]  # t1, t2
    params = BolfiParams(bounds=((0, 1), (0, 1)),
                         n_samples=n_samples,
                         n_initial_evidence=2,
                         sampling_type="uniform",
                         seed=1,
                         simulator_node_name="MA2",
                         discrepancy_node_name="d")
    model = get_model(n_obs=1000, true_params=true_params, seed_obs=1)
    bf = BolfiFactory(model, params)
    test_data = model.generate(1)["MA2"][0]
    ground_truth = {"t1": 0.5, "t2": 0.5}
    inference_experiment(bf, ground_truth=ground_truth, test_data=test_data)
Esempio n. 8
0
def test_simple_inference_can_be_run_consistently():
    for sampling_type in ["grid", "uniform", "BO"]:
        params = BolfiParams(bounds=((0, 1), (0, 1)),
                             n_samples=4,
                             n_initial_evidence=2,
                             sampling_type=sampling_type,
                             grid_tics=[[0.25, 0.75], [0.33, 0.66]],
                             seed=1,
                             discrepancy_node_name="d")
        model = get_model()
        results = list()
        bf = BolfiFactory(model, params)
        for i in range(2):
            post = bf.get().run()
            results.append(post.ML[0])
        np.testing.assert_array_almost_equal(results[0], results[1])
Esempio n. 9
0
def test_romc3():
    """Test that ROMC provides sensible samples at the MA2 example."""
    # load built-in model
    seed = 1
    np.random.seed(seed)
    model = ma2.get_model(seed_obs=seed)

    # define romc inference method
    bounds = [(-2, 2), (-2, 2)]
    romc = elfi.ROMC(model, bounds=bounds, discrepancy_name="d")

    # solve problems
    n1 = 100
    seed = 21
    romc.solve_problems(n1=n1, seed=seed)

    # estimate regions
    eps_filter = .02
    romc.estimate_regions(eps_filter=eps_filter,
                          fit_models=True,
                          eps_cutoff=0.1)

    # sample from posterior
    n2 = 50
    romc.sample(n2=n2)

    romc_mean = romc.result.sample_means_array
    romc_cov = romc.result.samples_cov()

    # Inference with Rejection
    N = 10000
    rej = elfi.Rejection(model,
                         discrepancy_name="d",
                         batch_size=10000,
                         seed=seed)
    result = rej.sample(N, threshold=.1)

    rejection_mean = result.sample_means_array
    rejection_cov = np.cov(result.samples_array.T)

    # assert summary statistics of samples match the ground truth
    assert np.allclose(romc_mean, rejection_mean, atol=.1)
    assert np.allclose(romc_cov, rejection_cov, atol=.1)
Esempio n. 10
0
import elfi
from elfi.examples import ma2


# load the model from elfi.examples
model = ma2.get_model()

# setup and run rejection sampling
rej = elfi.Rejection(model['d'], batch_size=10000)
result = rej.sample(1000, quantile=0.01)

# show summary of results on stdout
result.summary()

Esempio n. 11
0
def test_implementing_new_algorithm():
    import numpy as np

    from elfi.methods.parameter_inference import ParameterInference
    from elfi.methods.results import Sample

    import elfi.examples.ma2 as ma2

    class CustomMethod(ParameterInference):
        def __init__(self, model, discrepancy_name, threshold, **kwargs):
            # Create a name list of nodes whose outputs we wish to receive
            output_names = [discrepancy_name] + model.parameter_names
            super(CustomMethod, self).__init__(model, output_names, **kwargs)

            self.threshold = threshold
            self.discrepancy_name = discrepancy_name

            # Prepare lists to push the filtered outputs into
            self.state['filtered_outputs'] = {
                name: []
                for name in output_names
            }

        def set_objective(self, n_sim):
            self.objective['n_sim'] = n_sim

        def update(self, batch, batch_index):
            super(CustomMethod, self).update(batch, batch_index)

            # Make a filter mask (logical numpy array) from the distance array
            filter_mask = batch[self.discrepancy_name] <= self.threshold

            # Append the filtered parameters to their lists
            for name in self.output_names:
                values = batch[name]
                self.state['filtered_outputs'][name].append(
                    values[filter_mask])

        def extract_result(self):
            filtered_outputs = self.state['filtered_outputs']
            outputs = {
                name: np.concatenate(filtered_outputs[name])
                for name in self.output_names
            }

            return Sample(method_name='CustomMethod',
                          outputs=outputs,
                          parameter_names=self.parameter_names,
                          discrepancy_name=self.discrepancy_name,
                          n_sim=self.state['n_sim'],
                          threshold=self.threshold)

    # Below is from the part where we demonstrate iterative advancing

    # Run it
    m = ma2.get_model()
    custom_method = CustomMethod(m, 'd', threshold=.1, batch_size=1000)

    # Continue inference from the previous state (with n_sim=2000)
    custom_method.infer(n_sim=4000)

    # Or use it iteratively
    custom_method.set_objective(n_sim=6000)

    custom_method.iterate()
    assert custom_method.finished == False

    # Investigate the current state
    custom_method.extract_result()

    custom_method.iterate()
    assert custom_method.finished
    custom_method.extract_result()
Esempio n. 12
0
                (mean + std - range[0]) / (range[1] - range[0]),
                color="k",
                linestyle="--",
                label=r"$\sigma = %.3f$" % (std))
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.ylim(ylim)
    plt.legend()
    plt.savefig(savepath, bbox_inches='tight')
    plt.show(block=False)


# Set seed for reproducibility
seed = 1
np.random.seed(seed)
model = ma2.get_model(seed_obs=seed)

# plot prior samples

x = model.generate(1000)
plt.figure()
plt.title("Samples from the prior")
plt.xlabel(r"$\theta_1$")
plt.ylabel(r"$\theta_2$")
plt.plot(x["t1"], x["t2"], "bo")
plt.savefig(os.path.join(prepath, "mae2_prior_samples.png"),
            bbox_inches="tight")
plt.show(block=False)

####### ROMC with gradients ################
n1 = 1000