Beispiel #1
0
def get_model(n_obs=50, true_params=None, seed_obs=None):
    """Return a complete Gaussian noise model.

    Parameters
    ----------
    n_obs : int, optional
        the number of observations
    true_params : list, optional
        true_params[0] corresponds to the mean,
        true_params[1] corresponds to the standard deviation
    seed_obs : int, optional
        seed for the observed data generation

    Returns
    -------
    m : elfi.ElfiModel

    """
    if true_params is None:
        true_params = [10, 2]

    y_obs = Gauss(*true_params,
                  n_obs=n_obs,
                  random_state=np.random.RandomState(seed_obs))
    sim_fn = partial(Gauss, n_obs=n_obs)

    m = elfi.ElfiModel()
    elfi.Prior('uniform', -10, 50, model=m, name='mu')
    elfi.Prior('truncnorm', 0.01, 5, model=m, name='sigma')
    elfi.Simulator(sim_fn, m['mu'], m['sigma'], observed=y_obs, name='Gauss')
    elfi.Summary(ss_mean, m['Gauss'], name='S1')
    elfi.Summary(ss_var, m['Gauss'], name='S2')
    elfi.Distance('euclidean', m['S1'], m['S2'], name='d')

    return m
Beispiel #2
0
    def get_model(self, n_obs=100, true_params=None, seed_obs=None):
        """Return a complete MA2 model in inference task.

        Parameters
        ----------
        n_obs : int, optional
            observation length of the MA2 process
        true_params : list, optional
            parameters with which the observed data is generated
        seed_obs : int, optional
            seed for the observed data generation

        Returns
        -------
        m : elfi.ElfiModel

        """
        if true_params is None:
            true_params = [60]

        y_obs = self.func(*true_params,
                          random_state=np.random.RandomState(seed_obs))
        m = elfi.ElfiModel()
        elfi.Prior(ss.uniform, 0, 100, model=m, name='t1')
        elfi.Simulator(self.func, m['t1'], observed=y_obs, name='sim')
        elfi.Distance('euclidean', m['sim'], name='dist')
        return m
Beispiel #3
0
def get_model(n_obs=100, true_params=None, seed_obs=None):
    """Returns a complete MA2 model in inference task

    Parameters
    ----------
    n_obs : int
        observation length of the MA2 process
    true_params : list
        parameters with which the observed data is generated
    seed_obs : None, int
        seed for the observed data generation

    Returns
    -------
    m : elfi.ElfiModel
    """
    if true_params is None:
        true_params = [.6, .2]

    y = MA2(*true_params,
            n_obs=n_obs,
            random_state=np.random.RandomState(seed_obs))
    sim_fn = partial(MA2, n_obs=n_obs)

    m = elfi.ElfiModel(set_current=False)
    elfi.Prior(CustomPrior1, 2, model=m, name='t1')
    elfi.Prior(CustomPrior2, m['t1'], 1, name='t2')
    elfi.Simulator(sim_fn, m['t1'], m['t2'], observed=y, name='MA2')
    elfi.Summary(autocov, m['MA2'], name='S1')
    elfi.Summary(autocov, m['MA2'], 2, name='S2')
    elfi.Distance('euclidean', m['S1'], m['S2'], name='d')
    return m
Beispiel #4
0
    def get_model(self, n_obs=100, true_params=None, seed_obs=None):
        """Return a complete model in inference task.

        Parameters
        ----------
        n_obs : int, optional
            observation length of the MA2 process
        true_params : list, optional
            parameters with which the observed data is generated
        seed_obs : int, optional
            seed for the observed data generation

        Returns
        -------
        m : elfi.ElfiModel

        """

        m = elfi.ElfiModel()
        if true_params is None:
            elfi.Prior('uniform', -20.0, 20.0, model=m, name='white')
            elfi.Prior('uniform', -20.0, 20.0, model=m, name='yellow')
            elfi.Prior('uniform', -20.0, 20.0, model=m, name='red')
            elfi.Prior('uniform', -20.0, 20.0, model=m, name='green')
            elfi.Prior('uniform', -20.0, 20.0, model=m, name='purple')
            params = [
                m['white'], m['yellow'], m['red'], m['green'], m['purple']
            ]

        y_obs = self.get_observed_data()
        elfi.Simulator(self.func, *params, observed=y_obs, name='sim')
        elfi.Distance('euclidean', m['sim'], name='dist')
        # elfi.Distance(self.discrepancyII, m['DGP'], name='d')
        return m
Beispiel #5
0
def test_list_output():
    vsim = elfi.tools.vectorize(lsimulator)
    vsum = elfi.tools.vectorize(lsummary)

    v = vsim(np.array([[.2, .8], [.3, .7]]))
    assert is_array(v)
    assert not isinstance(v[0], list)

    vsim = elfi.tools.vectorize(lsimulator, dtype=False)

    v = vsim(np.array([[.2, .8], [.3, .7]]))
    assert is_array(v)
    assert isinstance(v[0], list)

    obs = lsimulator([.2, .8])

    elfi.new_model()
    p = elfi.Prior('dirichlet', [2, 2])
    sim = elfi.Simulator(vsim, p, observed=obs)
    S = elfi.Summary(vsum, sim)
    d = elfi.Distance('euclidean', S)

    pool = elfi.OutputPool(['sim'])
    rej = elfi.Rejection(d, batch_size=100, pool=pool, output_names=['sim'])
    sample = rej.sample(100, n_sim=1000)
    mean = np.mean(sample.samples['p'], axis=0)

    # Crude test
    assert mean[1] > mean[0]
def test_single_parameter_linear_adjustment():
    """A regression test against values obtained in the notebook."""
    seed = 20170616
    n_obs = 50
    batch_size = 100
    mu, sigma = (5, 1)

    # Hyperparameters
    mu0, sigma0 = (10, 100)

    y_obs = gauss.Gauss(
        mu, sigma, n_obs=n_obs, batch_size=1, random_state=np.random.RandomState(seed))
    sim_fn = partial(gauss.Gauss, sigma=sigma, n_obs=n_obs)

    # Posterior
    n = y_obs.shape[1]
    mu1 = (mu0 / sigma0**2 + y_obs.sum() / sigma**2) / (1 / sigma0**2 + n / sigma**2)
    sigma1 = (1 / sigma0**2 + n / sigma**2)**(-0.5)

    # Model
    m = elfi.ElfiModel()
    elfi.Prior('norm', mu0, sigma0, model=m, name='mu')
    elfi.Simulator(sim_fn, m['mu'], observed=y_obs, name='Gauss')
    elfi.Summary(lambda x: x.mean(axis=1), m['Gauss'], name='S1')
    elfi.Distance('euclidean', m['S1'], name='d')

    res = elfi.Rejection(m['d'], output_names=['S1'], seed=seed).sample(1000, threshold=1)
    adj = elfi.adjust_posterior(model=m, sample=res, parameter_names=['mu'], summary_names=['S1'])

    assert np.allclose(_statistics(adj.outputs['mu']), (4.9772879640569778, 0.02058680115402544))
Beispiel #7
0
def get_model(n_obs=100, true_params=None, seed_obs=None, n_lags=5):
    """Return a complete ARCH(1) model.

    Parameters
    ----------
    n_obs: int
        Observation length of the ARCH(1) process.
    true_params: list, optinal
        Parameters with which the observed data are generated.
    seed_obs: int, optional
        Seed for the observed data generation.
    n_lags: int, optional
        Number of lags in summary statistics.

    Returns
    -------
    elfi.ElfiModel

    """
    if true_params is None:
        true_params = [0.3, 0.7]
        logger.info(
            f'true_params were not given. Now using [t1, t2] = {true_params}.')

    # elfi model
    m = elfi.ElfiModel()

    # priors
    t1 = elfi.Prior('uniform', -1, 2, model=m)
    t2 = elfi.Prior('uniform', 0, 1, model=m)
    priors = [t1, t2]

    # observations
    y_obs = arch(*true_params,
                 n_obs=n_obs,
                 random_state=np.random.RandomState(seed_obs))

    # simulator
    Y = elfi.Simulator(arch, *priors, observed=y_obs)

    # summary statistics
    ss = []
    ss.append(elfi.Summary(sample_mean, Y, name='MU', model=m))
    ss.append(elfi.Summary(sample_variance, Y, name='VAR', model=m))
    for i in range(1, n_lags + 1):
        ss.append(elfi.Summary(autocorr, Y, i, name=f'AC_{i}', model=m))
    for i, j in combinations(range(1, n_lags + 1), 2):
        ss.append(
            elfi.Summary(pairwise_autocorr,
                         Y,
                         i,
                         j,
                         name=f'PW_{i}_{j}',
                         model=m))

    # distance
    elfi.Distance('euclidean', *ss, name='d', model=m)

    return m
Beispiel #8
0
def get_model(alpha=0.2, delta=0, tau=0.198, N=20, seed_obs=None):
    """Returns the example model used in Lintusaari et al. 2016.

    Here we infer alpha using the summary statistic T1. We expect the executable `bdm` be
    available in the working directory.

    Parameters
    ----------

    alpha : float
        birth rate
    delta : float
        death rate
    tau : float
        mutation rate
    N : int
        size of the population
    seed_obs : None, int
        Seed for the observed data generation. None gives the same data as in
        Lintusaari et al. 2016

    Returns
    -------
    m : elfi.ElfiModel
    """

    if seed_obs is None and N == 20:
        y = np.zeros(N, dtype='int16')
        data = np.array([6, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1], dtype='int16')
        y[0:len(data)] = data

    else:
        y = BDM(alpha,
                delta,
                tau,
                N,
                random_state=np.random.RandomState(seed_obs))

    m = elfi.ElfiModel(name='bdm')
    elfi.Prior('uniform', .005, 2, model=m, name='alpha')
    elfi.Simulator(BDM, m['alpha'], delta, tau, N, observed=y, name='BDM')
    elfi.Summary(T1, m['BDM'], name='T1')
    elfi.Distance('minkowski', m['T1'], p=1, name='d')

    m['BDM'].uses_meta = True

    # Warn the user if the executable is not present
    if not os.path.isfile('bdm') and not os.path.isfile('bdm.exe'):
        cpp_path = get_sources_path()
        warnings.warn(
            "This model uses an external simulator `bdm` implemented in C++ "
            "that needs to be compiled and copied to your working directory. "
            "We could not find it from your current working directory. Please"
            "copy the folder `{}` to your working directory "
            "and compile the source.".format(cpp_path), RuntimeWarning)

    return m
Beispiel #9
0
def get_model(n_obs=50, true_params=None, seed_obs=None, stochastic=True):
    """Returns a complete Ricker model in inference task.
    
    This is a simplified example that achieves reasonable predictions. For more extensive treatment
    and description using 13 summary statistics, see:
    
    Wood, S. N. (2010) Statistical inference for noisy nonlinear ecological dynamic systems, 
    Nature 466, 1102–1107.

    Parameters
    ----------
    n_obs : int, optional
        Number of observations.
    true_params : list, optional
        Parameters with which the observed data is generated.
    seed_obs : None, int, optional
        Seed for the observed data generation.
    stochastic : bool, optional
        Whether to use the stochastic or deterministic Ricker model.

    Returns
    -------
    m : elfi.ElfiModel
    """

    if stochastic:
        simulator = partial(stochastic_ricker, n_obs=n_obs)
        if true_params is None:
            true_params = [3.8, 0.3, 10.]

    else:
        simulator = partial(ricker, n_obs=n_obs)
        if true_params is None:
            true_params = [3.8]

    m = elfi.ElfiModel()
    y_obs = simulator(*true_params, n_obs=n_obs, random_state=np.random.RandomState(seed_obs))
    sim_fn = partial(simulator, n_obs=n_obs)
    sumstats = []

    if stochastic:
        elfi.Prior(ss.expon, np.e, 2, model=m, name='t1')
        elfi.Prior(ss.truncnorm, 0, 5, model=m, name='t2')
        elfi.Prior(ss.uniform, 0, 100, model=m, name='t3')
        elfi.Simulator(sim_fn, m['t1'], m['t2'], m['t3'], observed=y_obs, name='Ricker')
        sumstats.append(elfi.Summary(partial(np.mean, axis=1), m['Ricker'], name='Mean'))
        sumstats.append(elfi.Summary(partial(np.var, axis=1), m['Ricker'], name='Var'))
        sumstats.append(elfi.Summary(num_zeros, m['Ricker'], name='#0'))
        elfi.Discrepancy(chi_squared, *sumstats, name='d')

    else:  # very simple deterministic case
        elfi.Prior(ss.expon, np.e, model=m, name='t1')
        elfi.Simulator(sim_fn, m['t1'], observed=y_obs, name='Ricker')
        sumstats.append(elfi.Summary(partial(np.mean, axis=1), m['Ricker'], name='Mean'))
        elfi.Distance('euclidean', *sumstats, name='d')

    return m
    def build(self,
              model,
              pattern,
              prior_pos,
              prior_cov=64,
              r_bound=47.9,
              pmt_mask=np.ones(127)):
        ### Build Priors
        px = elfi.Prior(BoundedNormal_x, r_bound, prior_pos, prior_cov)
        py = elfi.Prior(BoundedNormal_y, px, r_bound, prior_pos, prior_cov)

        ### Build Model
        model = elfi.tools.vectorize(model)
        Y = elfi.Simulator(model, px, py, observed=np.array([pattern]))

        # TODO implement PMT mask here
        #def summarize(data, key):
        #    # Select either energy or time for model output.
        #    return np.array([v[key] for v in data])
        def summarize(data):
            return np.array(
                [list(v['energy']) + list(v['time']) for v in data])

        # Build summary stat for energy and time
        #S1 = elfi.Summary(summarize, Y, 'energy')
        #S2 = elfi.Summary(summarize, Y, 'time')
        S1 = elfi.Summary(summarize, Y)

        d = elfi.Distance('braycurtis', S1)
        log_d = elfi.Operation(np.log, d)

        # set the ELFI model so we can remove it later
        self.model = px.model

        ### Setup BOLFI
        bounds = {'px': (-r_bound, r_bound), 'py': (-r_bound, r_bound)}

        target_model = GPyRegression(log_d.model.parameter_names,
                                     bounds=bounds)

        acquisition_method = ConstraintLCBSC(target_model,
                                             prior=ModelPrior(log_d.model),
                                             noise_var=[1, 1],
                                             exploration_rate=10)

        bolfi = elfi.BOLFI(
            log_d,
            batch_size=1,
            initial_evidence=50,
            update_interval=1,
            # bounds=bounds,  # Not used when using target_model
            target_model=target_model,
            # acq_noise_var=[0.1, 0.1],  # Not used when using acq method
            acquisition_method=acquisition_method,
        )
        return bolfi
Beispiel #11
0
def multivariate_model(request):
    ndim = request.param
    m = elfi.ElfiModel()
    elfi.Prior(ss.multivariate_normal, [0] * ndim, model=m, name='t1')
    elfi.Simulator(rowsummer,
                   m['t1'],
                   observed=np.array([[0]]),
                   model=m,
                   name='sim')
    elfi.Distance('euclidean', m['sim'], model=m, name='d')
    return m
Beispiel #12
0
def new_sample(MA2, t_prior, t_prior_name, N=500, y_obs=y_obs):
    # ELFI also supports giving the scipy.stats distributions as strings
    Y = elfi.Simulator(MA2, t_prior, observed=y_obs)
    S1 = elfi.Summary(autocov, Y)
    S2 = elfi.Summary(autocov, Y,
                      2)  # the optional keyword lag is given the value 2
    d = elfi.Distance('euclidean', S1, S2)
    rej = elfi.Rejection(d, batch_size=5000, seed=np.random.randint(10**5))

    result = rej.sample(N, quantile=0.01)
    return result.samples[t_prior_name].mean(axis=0)
Beispiel #13
0
def multivariate_model(request):
    ndim = request.param

    def fun(x, batch_size, random_state):
        return np.sum(x, keepdims=True, axis=1)

    m = elfi.ElfiModel()
    elfi.Prior(ss.multivariate_normal, [0] * ndim, model=m, name='t1')
    elfi.Simulator(fun, m['t1'], observed=np.array([[0]]), model=m, name='sim')
    elfi.Distance('euclidean', m['sim'], model=m, name='d')
    return m
Beispiel #14
0
def sleep_model(request):
    """The true param will be half of the given sleep time."""
    ub_sec = request.param or .5
    m = elfi.ElfiModel()
    elfi.Constant(ub_sec, model=m, name='ub')
    elfi.Prior('uniform', 0, m['ub'], model=m, name='sec')
    elfi.Simulator(sleeper, m['sec'], model=m, name='slept')
    elfi.Summary(no_op, m['slept'], model=m, name='summary')
    elfi.Distance('euclidean', m['summary'], model=m, name='d')

    m.observed['slept'] = ub_sec / 2
    return m
 def predict(self, data_test):
     elfi.new_model("SMC")
     prior = elfi.Prior(MVUniform, self.p_lower, self.p_upper)
     sim = elfi.Simulator(self.simulator,
                          prior,
                          observed=data_test,
                          name='sim')
     SS = elfi.Summary(self.identity, sim, name='identity')
     d = elfi.Distance('euclidean', SS, name='d')
     smc = elfi.SMC(d, batch_size=1, seed=42)
     samples = smc.sample(self.n_particles, [self.threshold])
     return samples.samples_array
Beispiel #16
0
def get_model(n_obs=50, true_params=None, seed_obs=None, **kwargs):
    """Return a complete Lotka-Volterra model in inference task.

    Parameters
    ----------
    n_obs : int, optional
        Number of observations.
    true_params : list, optional
        Parameters with which the observed data is generated.
    seed_obs : int, optional
        Seed for the observed data generation.

    Returns
    -------
    m : elfi.ElfiModel

    """
    logger = logging.getLogger()
    if true_params is None:
        true_params = [1.0, 0.005, 0.6, 50, 100, 10.]

    kwargs['n_obs'] = n_obs
    y_obs = lotka_volterra(*true_params,
                           random_state=np.random.RandomState(seed_obs),
                           **kwargs)

    m = elfi.ElfiModel()
    sim_fn = partial(lotka_volterra, **kwargs)
    priors = []
    sumstats = []

    priors.append(elfi.Prior(ExpUniform, -6., 2., model=m, name='r1'))
    priors.append(elfi.Prior(ExpUniform, -6., 2., model=m,
                             name='r2'))  # easily kills populations
    priors.append(elfi.Prior(ExpUniform, -6., 2., model=m, name='r3'))
    priors.append(elfi.Prior('poisson', 50, model=m, name='prey0'))
    priors.append(elfi.Prior('poisson', 100, model=m, name='predator0'))
    priors.append(
        elfi.Prior(ExpUniform, np.log(0.5), np.log(50), model=m, name='sigma'))

    elfi.Simulator(sim_fn, *priors, observed=y_obs, name='LV')
    sumstats.append(
        elfi.Summary(partial(pick_stock, species=0), m['LV'], name='prey'))
    sumstats.append(
        elfi.Summary(partial(pick_stock, species=1), m['LV'], name='predator'))
    elfi.Distance('sqeuclidean', *sumstats, name='d')

    logger.info(
        "Generated %i observations with true parameters r1: %.1f, r2: %.3f, r3: %.1f, "
        "prey0: %i, predator0: %i, sigma: %.1f.", n_obs, *true_params)

    return m
Beispiel #17
0
    def get_model(self, n_obs=100, true_params=None, seed_obs=None):
        """Return a complete model in inference task.

        Parameters
        ----------
        n_obs : int, optional
            observation length of the MA2 process
        true_params : list, optional
            parameters with which the observed data is generated
        seed_obs : int, optional
            seed for the observed data generation

        Returns
        -------
        m : elfi.ElfiModel

        """

        m = elfi.ElfiModel()
        if true_params is None and self.env_name == "CartPole-v0":
            # gravity, masscart, masspole, length, force_mag
            true_params = [[9.8], [1.0], [0.1], [0.5], [10.0]]
            elfi.Prior('uniform', 5.0, 10.0, model=m, name='gravity')
            elfi.Prior('uniform', 0.1, 5, model=m, name='masscart')
            elfi.Prior('uniform', 0.1, 5, model=m, name='masspole')
            elfi.Prior('uniform', 0.1, 5, model=m, name='length')
            elfi.Prior('uniform', 5.0, 10.0, model=m, name='force_mag')
            params = [
                m['gravity'], m['masscart'], m['masspole'], m['length'],
                m['force_mag']
            ]

        elif true_params is None and self.env_name == "MountainCar-v0":
            # goal_position, goal_velocity, force, gravity
            true_params = [0.5, 0, 0.001, 0.0025]
            elfi.Prior('uniform', -1.2, 0.6, model=m, name='goal_position')
            elfi.Prior('uniform', 0, 5.0, model=m, name='goal_velocity')
            elfi.Prior('uniform', 0.0001, 0.01, model=m, name='force')
            elfi.Prior('uniform', 0.0001, 0.01, model=m, name='gravity')
            params = [
                m['goal_position'], m['goal_velocity'], m['force'],
                m['gravity']
            ]

        y_obs = self.func(*true_params,
                          random_state=np.random.RandomState(seed_obs))
        elfi.Simulator(self.func, *params, observed=y_obs, name='DGP')
        elfi.Distance('euclidean', m['DGP'], name='d')
        return m
Beispiel #18
0
    def get_model(self, n_obs=100, true_params=None, seed_obs=None):
        m = elfi.new_model()

        elfi.Prior('uniform', -2, 4, name='x')
        elfi.Prior('uniform', -2, 4, name='y')
        params = [m['x'], m['y']]

        if true_params is None:
            true_params = [[1.5, 1]]
        y_obs = self.func(*true_params, random_state=np.random.RandomState(seed_obs))
        y_obs = [np.mean(y_obs), np.std(y_obs)]

        elfi.Simulator(self.func, *params, observed=y_obs, name='sim')
        # elfi.Summary(partial(np.mean, axis=1), m['sim'], name='Mean')
        # elfi.Summary(partial(np.std, axis=1), m['sim'], name='Std')
        elfi.Distance('euclidean', m['sim'], name='dist')

        return m
Beispiel #19
0
    def build(self,
              model,
              pattern,
              prior_pos,
              prior_cov=25,
              r_bound=47.9,
              pmt_mask=np.ones(127)):
        ### Build Priors
        px = elfi.Prior(BoundedNormal_x, r_bound, prior_pos, prior_cov)
        py = elfi.Prior(BoundedNormal_y, px, r_bound, prior_pos, prior_cov)

        ### Build Model
        model = elfi.tools.vectorize(model)
        Y = elfi.Simulator(model, px, py, observed=np.array([pattern]))

        # TODO implement PMT mask here
        d = elfi.Distance('braycurtis', Y)
        log_d = elfi.Operation(np.log, d)

        # set the ELFI model so we can remove it later
        self.model = px.model

        ### Setup BOLFI
        bounds = {'px': (-r_bound, r_bound), 'py': (-r_bound, r_bound)}

        target_model = GPyRegression(log_d.model.parameter_names,
                                     bounds=bounds)

        acquisition_method = ConstraintLCBSC(target_model,
                                             prior=ModelPrior(log_d.model),
                                             noise_var=[5, 5],
                                             exploration_rate=10)

        bolfi = elfi.BOLFI(
            log_d,
            batch_size=1,
            initial_evidence=50,
            update_interval=1,
            # bounds=bounds,  # Not used when using target_model
            target_model=target_model,
            # acq_noise_var=[0.1, 0.1],  # Not used when using acq method
            acquisition_method=acquisition_method,
        )
        return bolfi
Beispiel #20
0
    def _obtain_accepted_thetas(self, set_ss, n_sim, n_acc, batch_size):
        """Perform the ABC-rejection sampling and identify `closest' parameters.

        The sampling is performed using the initialised simulator.

        Parameters
        ----------
        set_ss : List
            Summary-statistics combination to be used in the rejection sampling.
        n_sim : int
            Number of the iterations of the rejection sampling.
        n_acc : int
            Number of the accepted parameters.
        batch_size : int
            Number of samples per batch.

        Returns
        -------
        array_like
            Accepted parameters.

        """
        # Initialise the distance function.
        m = self.simulator.model.copy()
        list_ss = []
        for ss in set_ss:
            list_ss.append(elfi.Summary(ss, m[self.simulator.name], model=m))
        if isinstance(self.fn_distance, str):
            d = elfi.Distance(self.fn_distance, *list_ss, model=m)
        else:
            d = elfi.Discrepancy(self.fn_distance, *list_ss, model=m)

        # Run the simulations.
        # TODO: include different distance functions in the summary-statistics combinations.
        sampler_rejection = elfi.Rejection(d,
                                           batch_size=batch_size,
                                           seed=self.seed,
                                           pool=self.pool)
        result = sampler_rejection.sample(n_acc, n_sim=n_sim)

        # Extract the accepted parameters.
        thetas_acc = result.samples_array
        return thetas_acc
Beispiel #21
0
def test_dict_output():
    vsim = elfi.tools.vectorize(simulator)
    vsum = elfi.tools.vectorize(summary)

    obs = simulator([.2, .8])

    elfi.new_model()
    p = elfi.Prior('dirichlet', [2, 2])
    sim = elfi.Simulator(vsim, p, observed=obs)
    S = elfi.Summary(vsum, sim)
    d = elfi.Distance('euclidean', S)

    pool = elfi.OutputPool(['sim'])
    rej = elfi.Rejection(d, batch_size=100, pool=pool, output_names=['sim'])
    sample = rej.sample(100, n_sim=1000)
    mean = np.mean(sample.samples['p'], axis=0)

    # Crude test
    assert mean[1] > mean[0]
    def get_model(self, n_obs=10, true_params=None, seed_obs=None):
        m = elfi.new_model()

        # Parameters: ns, kc, alpha, r_star, As
        # priors from Sinha and Souradeep 2006.
        elfi.Prior('uniform', 0.5, 1.0, name='ns')
        elfi.Prior('uniform', 1e-7, 1e-3, name='kc')
        elfi.Prior('uniform', 0., 10., name='alpha')
        elfi.Prior('uniform', 0., 1., name='r_star')
        elfi.Prior('uniform', 2.7, 1.3, name='As')
        params = [m['ns'], m['kc'], m['alpha'], m['r_star'], m['As']]

        if true_params is None:
            true_params = [[0.96, 0.0003, 0.58, 0.75, 3.35]]
        y_obs = self.func(*true_params,
                          random_state=np.random.RandomState(seed_obs))

        elfi.Simulator(self.func, *params, observed=y_obs, name='sim')
        elfi.Distance('euclidean', m['sim'], name='dist')
        return m
 def predict(self, data_test):
     elfi.new_model("BOLFI")
     prior = elfi.Prior(MVUniform, self.p_lower, self.p_upper)
     sim = elfi.Simulator(self.simulator,
                          prior,
                          observed=data_test,
                          name='sim')
     SS = elfi.Summary(self.identity, sim, name='identity')
     d = elfi.Distance('euclidean', SS, name='d')
     log_d = elfi.Operation(np.log, d)
     bolfi = elfi.BOLFI(log_d,
                        batch_size=1,
                        initial_evidence=20,
                        update_interval=10,
                        acq_noise_var=self.p_lower.size * [0.1],
                        bounds=None,
                        seed=42)
     bolfi.fit(n_evidence=self.n_particles)
     post = bolfi.extract_posterior(-1.)
     samples = post.model.X
     return samples
Beispiel #24
0
def main():
    global eng
    datadir = Path('/home/ben/phd/stfp/abc_results/gradientNet')

    eng = matlab.engine.start_matlab()

    eng.addpath(eng.genpath('~/phd/stfp/abc_code'))
    eng.addpath(eng.genpath('~/phd/easySim'))

    maxConnProbOB2E_prior = elfi.Prior('uniform', 0, 1)
    maxConnProbOB2I_prior = elfi.Prior('uniform', 0, 1)
    maxConnProbGC2E_prior = elfi.Prior('uniform', 0, 1)
    maxConnProbGC2I_prior = elfi.Prior('uniform', 0, 1)
    sigmaOB2PC_prior = elfi.Prior('uniform', 1e-6, 1000e-6)
    sigmaGC2PC_prior = elfi.Prior('uniform', 1e-6, 1000e-6)

    sim = elfi.Simulator(simulator,
                         maxConnProbOB2E_prior,
                         maxConnProbOB2I_prior,
                         maxConnProbGC2E_prior,
                         maxConnProbGC2I_prior,
                         sigmaOB2PC_prior,
                         sigmaGC2PC_prior,
                         observed=0)

    S = elfi.Summary(score_network, sim)

    d = elfi.Distance('euclidean', S)

    #log_d = elfi.Operation(np.log, d)

    pool = elfi.OutputPool([
        'connProbOB2E_prior', 'connProbOB2I_prior', 'connProbGC2E_prior',
        'connProbGC2I_prior', 'sigmaOB2PC_prior', 'sigmaGC2PC_prior', 'S', 'd'
    ])

    ie_maxConnProbOB2E, ie_maxConnProbOB2I, ie_maxConnProbGC2E, ie_maxConnProbGC2I, ie_sigmaOB2PC, ie_sigmaGC2PC, ie_scores = eng.load_initial_evidence_gradientNet(
        '/home/ben/phd/stfp/abc_results/gradientNet', nargout=7)

    ie_maxConnProbOB2E = np.asarray(ie_maxConnProbOB2E)
    ie_maxConnProbOB2I = np.asarray(ie_maxConnProbOB2I)
    ie_maxConnProbGC2E = np.asarray(ie_maxConnProbGC2E)
    ie_maxConnProbGC2I = np.asarray(ie_maxConnProbGC2I)
    ie_sigmaOB2PC = np.asarray(ie_sigmaOB2PC)
    ie_sigmaGC2PC = np.asarray(ie_sigmaGC2PC)
    ie_scores = np.asarray(ie_scores)

    #ie_log_scores = np.log(ie_scores)

    if not ie_maxConnProbOB2E.any():
        ie = 10
        print('0 prior runs detected')
    else:
        ie = {
            'maxConnProbOB2E_prior': ie_maxConnProbOB2E,
            'maxConnProbOB2I_prior': ie_maxConnProbOB2I,
            'maxConnProbGC2E_prior': ie_maxConnProbGC2E,
            'maxConnProbGC2I_prior': ie_maxConnProbGC2I,
            'sigmaOB2PC_prior': ie_sigmaOB2PC,
            'sigmaGC2PC_prior': ie_sigmaGC2PC,
            'd': ie_scores
        }
        print(
            str(ie_maxConnProbOB2E.size) +
            ' prior runs detected... using as initial evidence')

    bolfi = elfi.BOLFI(d,
                       batch_size=1,
                       initial_evidence=ie,
                       update_interval=1,
                       bounds={
                           'maxConnProbOB2E_prior': (0, 1),
                           'maxConnProbOB2I_prior': (0, 1),
                           'maxConnProbGC2E_prior': (0, 1),
                           'maxConnProbGC2I_prior': (0, 1),
                           'sigmaOB2PC_prior': (1e-6, 1000e-6),
                           'sigmaGC2PC_prior': (1e-6, 1000e-6)
                       },
                       acq_noise_var=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       pool=pool)

    posterior = bolfi.fit(n_evidence=500)

    with open(datadir / 'bolfi_result.pkl', 'wb') as fname:
        pickle.dump(bolfi, fname)

    #bolfi.plot_state()
    bolfi.plot_discrepancy()
    plt.show(block=True)
Beispiel #25
0
# Set the generating parameters that we will try to infer
mean0 = 1
std0 = 3
alpha0 = 3.5

# Generate some data (using a fixed seed here)
np.random.seed(20170525)
y0 = simulator(mean0, std0, alpha0)
print(y0)

# Add the simulator node and observed data to the model
sim = elfi.Simulator(simulator, mu, sigma, alpha, observed=y0)

# Add summary statistics to the model
S1 = elfi.Summary(mean, sim)
S2 = elfi.Summary(var, sim)

# Specify distance as euclidean between summary vectors (S1, S2) from simulated and
# observed data
d = elfi.Distance('euclidean', S1, S2)

#### Plot the complete model (requires graphviz)
# elfi.draw(d)

rej = elfi.Rejection(d, batch_size=10000, seed=30052017)
res = rej.sample(10000, threshold=.5)
print(res)

import matplotlib.pyplot as plt
res.plot_marginals()
plt.show()
Beispiel #26
0
def get_model(true_params=None,
              seed_obs=None,
              initial_state=None,
              n_obs=40,
              f=10.,
              phi=0.984,
              total_duration=4):
    """Return a complete Lorenz model in inference task.

    This is a simplified example that achieves reasonable predictions.

    Hakkarainen, J., Ilin, A., Solonen, A., Laine, M., Haario, H., Tamminen,
    J., Oja, E., and Järvinen, H. (2012). On closure parameter estimation in
    chaotic systems. Nonlinear Processes in Geophysics, 19(1), 127–143.

    Parameters
    ----------
    true_params : list, optional
        Parameters with which the observed data is generated.
    seed_obs : int, optional
        Seed for the observed data generation.
    initial_state : ndarray
        Initial state value of the time-series.
    n_obs : int, optional
        Number of observed variables
    f : float, optional
        Force term
    phi : float, optional
        This value is used to express stochastic forcing term. It should be configured according
        to force term and eventually impacts to the result of eta.
        More details in Wilks (2005) et al.
    total_duration : float, optional

    Returns
    -------
    m : elfi.ElfiModel

    """
    simulator = partial(forecast_lorenz,
                        initial_state=initial_state,
                        f=f,
                        n_obs=n_obs,
                        phi=phi,
                        total_duration=total_duration)

    if not true_params:
        true_params = [2.0, 0.1]

    m = elfi.ElfiModel()

    y_obs = simulator(*true_params,
                      random_state=np.random.RandomState(seed_obs))
    sumstats = []

    elfi.Prior('uniform', 0.5, 3., model=m, name='theta1')
    elfi.Prior('uniform', 0, 0.3, model=m, name='theta2')
    elfi.Simulator(simulator,
                   m['theta1'],
                   m['theta2'],
                   observed=y_obs,
                   name='Lorenz')

    sumstats.append(elfi.Summary(mean, m['Lorenz'], name='Mean'))

    sumstats.append(elfi.Summary(var, m['Lorenz'], name='Var'))

    sumstats.append(elfi.Summary(autocov, m['Lorenz'], name='Autocov'))

    sumstats.append(elfi.Summary(cov, m['Lorenz'], name='Cov'))

    sumstats.append(elfi.Summary(xcov, m['Lorenz'], True, name='CrosscovPrev'))

    sumstats.append(elfi.Summary(xcov, m['Lorenz'], False,
                                 name='CrosscovNext'))

    elfi.Distance('euclidean', *sumstats, name='d')

    return m
############# DEFINE ELFI MODEL ##################
def simulator(theta, dim, batch_size=10000, random_state=None):
    likelihood = Likelihood()
    theta = np.repeat(theta, dim, -1)
    return likelihood.rvs(theta, seed=random_state)


elfi.new_model("1D_example")
elfi_prior = elfi.Prior(Prior(), name="theta")
elfi_simulator = elfi.Simulator(simulator,
                                elfi_prior,
                                dim,
                                observed=np.expand_dims(data, 0),
                                name="simulator")
dist = elfi.Distance('euclidean', elfi_simulator, name="dist")

bounds = [(-2.5, 2.5)]
dim = data.shape[-1]

# Defines the ROMC inference method
romc = elfi.ROMC(dist, bounds)
romc1 = elfi.ROMC(dist, bounds)
romc2 = elfi.ROMC(dist, bounds)
romc3 = elfi.ROMC(dist, bounds)

############# Gradients ###################
seed = 21
eps = 1
n1 = np.linspace(1, 101, 10)
solve_grad = []
Beispiel #28
0
prior_args = [m[name] for name in m.parameter_names]

elfi.Simulator(elfi_sim,
               *prior_args,
               m["length"],
               m["recombination_rate"],
               m["mutation_rate"],
               priors,
               name="sim",
               model=m)

elfi.Summary(elfi_sum, m["sim"], name="sum", model=m)
elfi.Summary(elfi_sum_scaler, m["sum"], None,
             name="sum_scaler")  # Placeholder (no scaling yet)
elfi.Distance('euclidean', m["sum_scaler"], name='d', model=m)

# Rejection to "train" sum stat scaler
start_time = time.time()
pool = elfi.OutputPool(['sum'])
rej = elfi.Rejection(m['d'], batch_size=1, seed=1, pool=pool)
rej.sample(train_scaler_n_sim, quantile=1, bar=False)  # Accept all
sum_stats = pool.get_store('sum')
sum_stats = np.array(list(sum_stats.values()))
sum_stats = sum_stats.reshape(-1, sum_stats.shape[2])  # Drop batches axis
scaler = StandardScaler()
scaler.fit(sum_stats)
elapsed_time = time.time() - start_time
logging.info(
    f"{train_scaler_n_sim} simulations to train standard scaler completed in {elapsed_time/60:.2f} minutes"
)
Beispiel #29
0
                                   X,
                                   N,
                                   K,
                                   r,
                                   alphaprior1,
                                   alphaprior2,
                                   alphaprior3,
                                   alphaprior4,
                                   alphaprior5,
                                   alphaprior6,
                                   tau,
                                   measurement_idx,
                                   observed=observeddata)

summary = elfi.Summary(logdestack, simulator_results)
d = elfi.Distance('euclidean', summary)
#log_d = elfi.Operation(np.log, d)

bolfi = elfi.BOLFI(d,
                   batch_size=1,
                   initial_evidence=100,
                   update_interval=10,
                   bounds={
                       'alphaprior1': (0, 5),
                       'alphaprior2': (0, 5),
                       'alphaprior3': (0, 5),
                       'alphaprior4': (0, 5),
                       'alphaprior5': (0, 5),
                       'alphaprior6': (0, 5)
                   },
                   acq_noise_var=[0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
Beispiel #30
0
def main(base, output, number_processes):
    # generate null (should only execute once)
    use = 'BOLFI'
    #use = 'SINGLE'
    if use != 'SINGLE':
        click.secho('Generating null dataset', fg='yellow')
        subprocess.check_call(
            ["snakemake", "null", "--profile", "elfi_profile"])
        click.secho('Creating environments', fg='yellow')
        subprocess.check_call(
            ["snakemake", "--profile", "elfi_profile", "--create-envs-only"])
        click.secho('Starting BOLFI', fg='yellow')
    if base:
        global base_output
        base_output = base
    if output:
        global summary_output
        summary_output = output
    # setup priors
    elfi.set_client(multiprocessing.Client(num_processes=number_processes))
    model = elfi.ElfiModel(name='msprime')
    elfi.Prior('uniform', 0, 0.5, model=model, name='n1')
    elfi.Prior('uniform', 0, 0.5, model=model, name='n2')
    elfi.Prior('uniform', 0, 1, model=model, name='split_prop')
    elfi.Prior('uniform', 1, 1861, model=model, name='split_size')
    snake_sim = elfi.tools.external_operation(command,
                                              prepare_inputs=prepare_inputs,
                                              process_result=process_result,
                                              stdout=False)
    vec_snake = elfi.tools.vectorize(snake_sim)
    empirical = np.array([
        0,  # desert MSE
        0.291761,
        0.328705,
        0.335145,  # pi
        0.12985,
        0.156539,
        0.0921547,  # fst
        0.023,
        0.019
    ])  # admix
    snake_node = elfi.Simulator(vec_snake,
                                model['n1'],
                                model['n2'],
                                model['split_prop'],
                                model['split_size'],
                                observed=empirical,
                                name='snake_sim')
    snake_node.uses_meta = True
    distance = elfi.Distance('euclidean', snake_node, name='dist')
    if use == 'SINGLE':
        print(
            snake_sim(0.1,
                      0.1,
                      0.1,
                      100,
                      seed=2,
                      meta={
                          'model_name': 'test',
                          'batch_index': 1,
                          'submission_index': 2
                      }))
        return

    elif use == 'BOLFI':
        pool = elfi.ArrayPool(
            ['n1', 'n2', 'split_prop', 'split_size', 'snake_sim'],
            name='bolfi_pool')

        bolfi = elfi.BOLFI(distance,
                           batch_size=1,
                           initial_evidence=20,
                           update_interval=3,
                           bounds={
                               'n1': (0, 0.5),
                               'n2': (0, 0.5),
                               'split_prop': (0, 1),
                               'split_size': (1, 1861)
                           },
                           pool=pool)
        post = bolfi.fit(n_evidence=10, bar=False)
        click.secho('Saving results', fg='yellow')
        pool.save()
        post.save()
        click.secho('Done', fg='green')

        return