예제 #1
0
def test_FFBSStep():

    np.random.seed(2032)

    poiszero_sim, _ = simulate_poiszero_hmm(30, 150)
    y_test = poiszero_sim["Y_t"]

    with pm.Model() as test_model:
        p_0_rv = pm.Dirichlet("p_0", np.r_[1, 1])
        p_1_rv = pm.Dirichlet("p_1", np.r_[1, 1])

        P_tt = tt.stack([p_0_rv, p_1_rv])
        P_rv = pm.Deterministic("P_tt", tt.shape_padleft(P_tt))

        pi_0_tt = compute_steady_state(P_rv)

        S_rv = HMMStateSeq("S_t", P_rv, pi_0_tt, shape=y_test.shape[0])

        Y_rv = PoissonZeroProcess("Y_t", 9.0, S_rv, observed=y_test)

    with test_model:
        ffbs = FFBSStep([S_rv])

    test_point = test_model.test_point.copy()
    test_point["p_0_stickbreaking__"] = poiszero_sim["p_0_stickbreaking__"]
    test_point["p_1_stickbreaking__"] = poiszero_sim["p_1_stickbreaking__"]

    res = ffbs.step(test_point)

    assert np.array_equal(res["S_t"], poiszero_sim["S_t"])
예제 #2
0
def test_FFBSStep_extreme():
    """Test a long series with extremely large mixture separation (and, thus, very small likelihoods)."""  # noqa: E501

    np.random.seed(2032)

    mu_true = 5000
    poiszero_sim, _ = simulate_poiszero_hmm(9000, mu_true)
    y_test = poiszero_sim["Y_t"]

    with pm.Model() as test_model:
        p_0_rv = poiszero_sim["p_0"]
        p_1_rv = poiszero_sim["p_1"]

        P_tt = at.stack([p_0_rv, p_1_rv])
        P_rv = pm.Deterministic("P_tt", at.shape_padleft(P_tt))

        pi_0_tt = poiszero_sim["pi_0"]

        S_rv = DiscreteMarkovChain("S_t", P_rv, pi_0_tt, shape=y_test.shape[0])
        S_rv.tag.test_value = (y_test > 0).astype(int)

        # This prior is very far from the true value...
        E_mu, Var_mu = 100.0, 10000.0
        mu_rv = pm.Gamma("mu", E_mu**2 / Var_mu, E_mu / Var_mu)

        PoissonZeroProcess("Y_t", mu_rv, S_rv, observed=y_test)

    with test_model:
        ffbs = FFBSStep([S_rv])

    test_point = test_model.test_point.copy()
    test_point["p_0_stickbreaking__"] = poiszero_sim["p_0_stickbreaking__"]
    test_point["p_1_stickbreaking__"] = poiszero_sim["p_1_stickbreaking__"]

    with np.errstate(over="ignore", under="ignore"):
        res = ffbs.step(test_point)

    assert np.array_equal(res["S_t"], poiszero_sim["S_t"])

    with test_model, np.errstate(over="ignore",
                                 under="ignore"), warnings.catch_warnings():
        warnings.filterwarnings("ignore", category=UserWarning)
        warnings.filterwarnings("ignore", category=DeprecationWarning)
        warnings.filterwarnings("ignore", category=FutureWarning)
        mu_step = pm.NUTS([mu_rv])
        ffbs = FFBSStep([S_rv])
        steps = [ffbs, mu_step]
        trace = pm.sample(
            20,
            step=steps,
            cores=1,
            chains=1,
            tune=100,
            n_init=100,
            progressbar=False,
        )

        assert not trace.get_sampler_stats("diverging").all()
        assert trace["mu"].mean() > 1000.0
예제 #3
0
def test_FFBSStep():

    with pm.Model(), pytest.raises(ValueError):
        P_rv = np.eye(2)[None, ...]
        S_rv = DiscreteMarkovChain("S_t", P_rv, np.r_[1.0, 0.0], shape=10)
        S_2_rv = DiscreteMarkovChain("S_2_t", P_rv, np.r_[0.0, 1.0], shape=10)
        PoissonZeroProcess("Y_t",
                           9.0,
                           S_rv + S_2_rv,
                           observed=np.random.poisson(9.0, size=10))
        # Only one variable can be sampled by this step method
        ffbs = FFBSStep([S_rv, S_2_rv])

    with pm.Model(), pytest.raises(TypeError):
        S_rv = pm.Categorical("S_t", np.r_[1.0, 0.0], shape=10)
        PoissonZeroProcess("Y_t",
                           9.0,
                           S_rv,
                           observed=np.random.poisson(9.0, size=10))
        # Only `DiscreteMarkovChains` can be sampled with this step method
        ffbs = FFBSStep([S_rv])

    with pm.Model(), pytest.raises(TypeError):
        P_rv = np.eye(2)[None, ...]
        S_rv = DiscreteMarkovChain("S_t", P_rv, np.r_[1.0, 0.0], shape=10)
        pm.Poisson("Y_t", S_rv, observed=np.random.poisson(9.0, size=10))
        # Only `SwitchingProcess`es can used as dependent variables
        ffbs = FFBSStep([S_rv])

    np.random.seed(2032)

    poiszero_sim, _ = simulate_poiszero_hmm(30, 150)
    y_test = poiszero_sim["Y_t"]

    with pm.Model() as test_model:
        p_0_rv = pm.Dirichlet("p_0", np.r_[1, 1], shape=2)
        p_1_rv = pm.Dirichlet("p_1", np.r_[1, 1], shape=2)

        P_tt = at.stack([p_0_rv, p_1_rv])
        P_rv = pm.Deterministic("P_tt", at.shape_padleft(P_tt))

        pi_0_tt = compute_steady_state(P_rv)

        S_rv = DiscreteMarkovChain("S_t", P_rv, pi_0_tt, shape=y_test.shape[0])

        PoissonZeroProcess("Y_t", 9.0, S_rv, observed=y_test)

    with test_model:
        ffbs = FFBSStep([S_rv])

    test_point = test_model.test_point.copy()
    test_point["p_0_stickbreaking__"] = poiszero_sim["p_0_stickbreaking__"]
    test_point["p_1_stickbreaking__"] = poiszero_sim["p_1_stickbreaking__"]

    res = ffbs.step(test_point)

    assert np.array_equal(res["S_t"], poiszero_sim["S_t"])
예제 #4
0
def test_only_positive_state():
    number_of_draws = 50
    S = 2
    mu = 10
    y_t = np.repeat(0, 100)

    with pm.Model():
        p_0_rv = pm.Dirichlet("p_0", np.r_[1, 1], shape=2)
        p_1_rv = pm.Dirichlet("p_1", np.r_[1, 1], shape=2)

        P_tt = at.stack([p_0_rv, p_1_rv])
        Gammas_tt = pm.Deterministic("P_tt", at.shape_padleft(P_tt))

        gamma_0_rv = pm.Dirichlet("gamma_0", np.ones((S, )), shape=S)

        V_rv = DiscreteMarkovChain("V_t",
                                   Gammas_tt,
                                   gamma_0_rv,
                                   shape=y_t.shape[0])
        V_rv.tag.test_value = (y_t > 0) * 1

        _ = SwitchingProcess(
            "Y_t",
            [Constant.dist(np.array(0, dtype=np.int64)),
             Constant.dist(mu)],
            V_rv,
            observed=y_t,
        )

        posterior_trace = pm.sample(
            chains=1,
            draws=number_of_draws,
            return_inferencedata=True,
            step=FFBSStep([V_rv]),
        )

        posterior_pred_trace = pm.sample_posterior_predictive(
            posterior_trace.posterior, var_names=["Y_t"])
        assert np.all(posterior_pred_trace["Y_t"] == 0)
예제 #5
0
def test_time_varying_model():

    np.random.seed(1039)

    data = gen_toy_data()

    formula_str = "1 + C(weekday)"
    X_df = patsy.dmatrix(formula_str, data, return_type="dataframe")
    X_np = X_df.values

    xi_shape = X_np.shape[1]

    xi_0_true = np.array([2.0, -2.0, 2.0, -2.0, 2.0, -2.0,
                          2.0]).reshape(xi_shape, 1)
    xi_1_true = np.array([2.0, -2.0, 2.0, -2.0, 2.0, -2.0,
                          2.0]).reshape(xi_shape, 1)

    xis_rv_true = np.stack([xi_0_true, xi_1_true], axis=1)

    with pm.Model(**TV_CONFIG) as sim_model:
        _ = create_dirac_zero_hmm(X_np,
                                  mu=1000,
                                  xis=xis_rv_true,
                                  observed=np.zeros(X_np.shape[0]))

    sim_point = pm.sample_prior_predictive(samples=1, model=sim_model)

    y_t = sim_point["Y_t"].squeeze().astype(int)

    split = int(len(y_t) * 0.7)

    train_y, test_V = y_t[:split], sim_point["V_t"].squeeze()[split:]
    train_X, test_X = X_np[:split, :], X_np[split:, :]

    X = shared(train_X, name="X", borrow=True)
    Y = shared(train_y, name="y_t", borrow=True)

    with pm.Model() as model:
        xis_rv = pm.Normal("xis", 0, 10, shape=xis_rv_true.shape)
        _ = create_dirac_zero_hmm(X, 1000, xis_rv, Y)

    number_of_draws = 500

    with model:
        steps = [
            FFBSStep([model.V_t]),
            pm.NUTS(
                vars=[
                    model.gamma_0,
                    model.Gamma,
                ],
                target_accept=0.90,
            ),
        ]

    with model:
        posterior_trace = pm.sample(
            draws=number_of_draws,
            step=steps,
            random_seed=100,
            return_inferencedata=True,
            chains=1,
            cores=1,
            progressbar=True,
            idata_kwargs={"dims": {
                "Y_t": ["date"],
                "V_t": ["date"]
            }},
        )

    # Update the shared variable values
    Y.set_value(np.ones(test_X.shape[0], dtype=Y.dtype))
    X.set_value(test_X)

    model.V_t.distribution.shape = (test_X.shape[0], )

    hdi_data = az.hdi(posterior_trace, hdi_prob=0.95,
                      var_names=["xis"]).to_dataframe()
    hdi_data = hdi_data.unstack(level="hdi")

    xis_true_flat = xis_rv_true.squeeze().flatten()
    check_idx = ~np.in1d(np.arange(len(xis_true_flat)),
                         np.arange(3, len(xis_true_flat), step=4))
    assert np.all(
        xis_true_flat[check_idx] <= hdi_data["xis",
                                             "higher"].values[check_idx])
    assert np.all(
        xis_true_flat[check_idx] >= hdi_data["xis", "lower"].values[check_idx])

    trace = posterior_trace.posterior.drop_vars(["Gamma", "V_t"])

    with aesara.config.change_flags(compute_test_value="off"):
        adds_pois_ppc = pm.sample_posterior_predictive(
            trace, var_names=["V_t", "Y_t", "Gamma"], model=model)

    assert (np.abs(adds_pois_ppc["V_t"] - test_V) /
            test_V.shape[0]).mean() < 1e-2