Exemplo n.º 1
0
def test_child_indices():
    """Testing existence of properties for calculation of child indices!"""
    point_constr = {"n_periods": 2, "n_lagged_choices": 1}

    params, options = generate_random_model(point_constr=point_constr)

    # Add some inadmissible states
    optim_paras, options = process_params_and_options(params, options)

    state_space = create_state_space_class(optim_paras, options)

    # Create all relevant columns
    core_columns = ["period"] + create_core_state_space_columns(optim_paras)

    # compose child indices of first choice
    initial_state = state_space.core.iloc[0][core_columns].to_numpy()

    # Get all the future states
    states = []
    for i in range(len(optim_paras["choices"])):
        child = initial_state.copy()
        child[0] += 1
        child[i + 1] += 1
        child[-1] = i
        ix = state_space.indexer[tuple(child)]
        states.append(np.array(ix).reshape(1, 2))

    manual = np.concatenate(states, axis=0)
    np.testing.assert_array_equal(state_space.child_indices[0][0], manual)
Exemplo n.º 2
0
def test_wage_nonpecs():
    """Replace constants in reward functions with constants due to observables."""
    point_constr = {"n_periods": 3, "n_lagged_choices": 1, "observables": [2]}
    params, options = generate_random_model(point_constr=point_constr)

    solve = get_solve_func(params, options)
    state_space = solve(params)

    # Replace constants in choices with constant utility by observables.
    optim_paras, _ = process_params_and_options(params, options)

    wage_choice = ("wage", np.random.choice(optim_paras["choices_w_wage"]))
    nonpec_choice = ("nonpec", np.random.choice(list(optim_paras["choices"])))

    # Change specs accordingly
    for reward in [wage_choice, nonpec_choice]:
        constant = params.loc[(f"{reward[0]}_{reward[1]}", "constant"),
                              "value"]
        params = params.drop(index=[(f"{reward[0]}_{reward[1]}", "constant")])

        for obs in range(2):
            params.loc[(f"{reward[0]}_{reward[1]}", f"observable_0_{obs}"),
                       "value"] += constant

    solve = get_solve_func(params, options)
    state_space_ = solve(params)

    for attribute in ["wages", "nonpecs"]:
        apply_to_attributes_of_two_state_spaces(
            getattr(state_space, attribute),
            getattr(state_space_, attribute),
            np.testing.assert_array_almost_equal,
        )
Exemplo n.º 3
0
def test_distribution_of_observables(seed):
    """Test that the distribution of observables matches the simulated distribution."""
    np.random.seed(seed)

    # Now specify a set of observables
    point_constr = {
        "observables": [np.random.randint(2, 6)],
        "simulation_agents": 1000,
        "n_periods": 1,
    }

    params, options = generate_random_model(point_constr=point_constr)

    simulate = rp.get_simulate_func(params, options)
    df = simulate(params)

    # Check observable probabilities
    probs = df["Observable_0"].value_counts(normalize=True, sort=False)

    # Check proportions
    np.testing.assert_almost_equal(
        probs.to_numpy(),
        params.loc[params.index.get_level_values(0).str.
                   contains("observable_observable_0"), "value", ].to_numpy(),
        decimal=1,
    )
Exemplo n.º 4
0
def test_equality_for_myopic_agents_and_tiny_delta():
    """Test equality of simulated data and likelihood with myopia and tiny delta."""
    # Get simulated data and likelihood for myopic model.
    params, options = generate_random_model(myopic=True)

    simulate = rp.get_simulate_func(params, options)
    df = simulate(params)

    log_like = get_log_like_func(params, options, df)
    likelihood = log_like(params)

    # Get simulated data and likelihood for model with tiny delta.
    params.loc["delta", "value"] = 1e-12

    df_ = simulate(params)

    log_like = rp.get_log_like_func(params, options, df_)
    likelihood_ = log_like(params)

    # The continuation values are different because for delta = 0 the backward induction
    # is completely skipped and all continuation values are set to zero whereas for a
    # tiny delta, the delta ensures that continuation have no impact.
    columns = df.filter(like="Continu").columns.tolist()
    pd.testing.assert_frame_equal(df.drop(columns=columns),
                                  df_.drop(columns=columns))

    np.testing.assert_almost_equal(likelihood, likelihood_, decimal=12)
Exemplo n.º 5
0
def test_raise_exception_for_missing_meas_error():
    params, options = generate_random_model()

    params = params.drop(index=("meas_error", "sd_b"))

    with pytest.raises(KeyError):
        _parse_measurement_errors(params, options)
Exemplo n.º 6
0
def test_raise_exception_for_missing_shock_matrix():
    params, _ = generate_random_model()

    params = params.drop(index="shocks_sdcorr", level="category")

    with pytest.raises(KeyError):
        _parse_shocks({}, params)
Exemplo n.º 7
0
def test_invariance_of_wage_calc():
    """The model reproduces invariant properties of wage outcomes."""
    point_constr = {"n_periods": 2, "observables": [3]}

    params, options = generate_random_model(point_constr=point_constr)

    # Add some inadmissible states
    optim_paras, _ = process_params_and_options(params, options)

    # Solve first model
    solve = get_solve_func(params, options)
    state_space = solve(params)

    pos = np.random.choice(range(len(state_space.dense)))
    dense_combination = list(state_space.dense.keys())[pos]
    dense_index = state_space.dense_covariates_to_dense_index[
        dense_combination]
    idx = state_space.core_key_and_dense_index_to_dense_key[(1, dense_index)]

    # Solve relevant wages
    wages_b = state_space.wages[idx][:, 1]

    # Impose some restriction
    options["negative_choice_set"] = {"a": ["period == 1"]}

    solve = get_solve_func(params, options)
    state_space = solve(params)

    wages_b_alt = state_space.wages[idx][:, 0]

    np.testing.assert_array_equal(wages_b, wages_b_alt)
Exemplo n.º 8
0
def test_distribution_of_observables():
    """Test that the distribution of observables matches the simulated distribution."""
    # Now specify a set of observables
    point_constr = {
        "observables": [np.random.randint(2, 6)],
        "simulation_agents": 1000
    }

    params, options = generate_random_model(point_constr=point_constr)

    simulate = rp.get_simulate_func(params, options)
    df = simulate(params)

    # Check observable probabilities
    probs = df["Observable_0"].value_counts(normalize=True, sort=False)

    # Check proportions
    n_levels = point_constr["observables"][0]
    for level in range(n_levels):
        # Some observables might be missing in the simulated data because of small
        # probabilities. Test for zero probability in this case.
        probability = probs.loc[level] if level in probs.index else 0

        params_probability = params.loc[(f"observable_observable_0_{level}",
                                         "probability"), "value"]

        np.testing.assert_allclose(probability, params_probability, atol=0.05)
Exemplo n.º 9
0
def test_run_through_of_solve_with_interpolation():
    params, options = generate_random_model(point_constr={
        "n_periods": 5,
        "interpolation_points": 10
    })

    solve = get_solve_func(params, options)
    solve(params)
Exemplo n.º 10
0
def test_raise_exception_for_observable_with_one_value(observables):
    point_constr = {"observables": observables}
    params, _ = generate_random_model(point_constr=point_constr)

    params = params.drop(index="observable_observable_0_0", level="category")["value"]

    with pytest.raises(ValueError, match=r"Observables and exogenous processes"):
        _parse_observables({}, params)
Exemplo n.º 11
0
def test_generate_random_model():
    """Test if random model specifications can be simulated and processed."""
    params, options = generate_random_model()

    df = simulate_truncated_data(params, options)

    log_like = get_log_like_func(params, options, df)

    crit_val = log_like(params)

    assert isinstance(crit_val, float)
Exemplo n.º 12
0
def process_model_or_seed(model_or_seed, **kwargs):
    if isinstance(model_or_seed, str):
        params, options = rp.get_example_model(model_or_seed, with_data=False)
    else:
        np.random.seed(model_or_seed)
        params, options = generate_random_model(**kwargs)

    if "kw_97" in str(model_or_seed):
        options["n_periods"] = 10

    return params, options
Exemplo n.º 13
0
def _create_single(idx):
    """Create a single test."""
    np.random.seed(idx)

    params, options = generate_random_model()

    crit_val = compute_log_likelihood(params, options)

    if not isinstance(crit_val, float):
        raise AssertionError(" ... value of criterion function too large.")

    return params, options, crit_val
Exemplo n.º 14
0
def test_simulation_and_estimation_with_different_models():
    """Test the evaluation of the criterion function not at the true parameters."""
    # Simulate a dataset
    params, options = generate_random_model()
    df = simulate_truncated_data(params, options)

    # Evaluate at different points, ensuring that the simulated dataset still fits.
    crit_func = get_crit_func(params, options, df)
    params_ = add_noise_to_params(params, options)

    params.equals(params_)

    crit_func(params)
Exemplo n.º 15
0
def test_invariant_results_for_two_estimations():
    params, options = generate_random_model()
    df = simulate_truncated_data(params, options)

    crit_func = get_crit_func(params, options, df)

    # First estimation.
    crit_val = crit_func(params)

    # Second estimation.
    crit_val_ = crit_func(params)

    assert crit_val == crit_val_
Exemplo n.º 16
0
def test_simulation_and_estimation_with_different_models():
    """Test the evaluation of the criterion function not at the true parameters."""
    # Set constraints.
    num_agents = np.random.randint(5, 100)
    constr = {
        "simulation_agents": num_agents,
        "n_periods": np.random.randint(1, 4),
        "edu_max": 15,
        "edu_start": [7],
        "edu_share": [1],
        "n_lagged_choices": np.random.choice(2),
    }

    # Simulate a dataset
    params, options = generate_random_model(point_constr=constr)
    df = simulate_truncated_data(params, options)

    # Evaluate at different points, ensuring that the simulated dataset still fits.
    params, options = generate_random_model(point_constr=constr)
    crit_func = get_crit_func(params, options, df)

    crit_func(params)
Exemplo n.º 17
0
def test_generate_random_model(seed):
    """Test if random model specifications can be simulated and processed."""
    np.random.seed(seed)

    params, options = generate_random_model()

    df = simulate_truncated_data(params, options)

    crit_func = get_crit_func(params, options, df)

    crit_val = crit_func(params)

    assert isinstance(crit_val, float)
Exemplo n.º 18
0
def test_equality_of_models_with_and_without_observables(seed):
    """Test equality of models with and without observables.

    First, generate a model where the parameter values of observables is set to zero.
    The second model is obtained by assigning all observable indicators the value of the
    constant in the reward functions and set the constants to zero. The two models
    should be equivalent.

    """
    np.random.seed(seed)

    # Now specify a set of observables
    observables = [np.random.randint(2, 6)]
    point_constr = {"observables": observables}

    # Get simulated data and likelihood for myopic model.
    params, options = generate_random_model(myopic=True,
                                            point_constr=point_constr)

    # Get all reward values
    index_reward = [
        x for x in set(params.index.get_level_values(0))
        if "nonpec" in x or "wage" in x
    ]

    # Get all indices that have
    obs_labels = generate_obs_labels(observables, index_reward)

    # Set these values to zero
    params.loc[obs_labels, "value"] = 0

    # Simulate the base model
    simulate = rp.get_simulate_func(params, options)
    df = simulate(params)

    # Put two new values into the eq
    for x in obs_labels:
        params.loc[x, "value"] = params.loc[(x[0], "constant"), "value"]

    for x in index_reward:
        params.loc[(x, "constant"), "value"] = 0

    # Simulate the new model
    df_ = simulate(params)

    # test for equality
    pd.testing.assert_frame_equal(df_, df)
Exemplo n.º 19
0
def process_model_or_seed(model_or_seed=None, **kwargs):
    if isinstance(model_or_seed, str):
        params, options = rp.get_example_model(model_or_seed, with_data=False)
    elif isinstance(model_or_seed, int):
        np.random.seed(model_or_seed)
        params, options = generate_random_model(**kwargs)
    else:
        raise ValueError

    if "kw_94" in str(model_or_seed):
        options["n_periods"] = 10
    if "kw_97" in str(model_or_seed):
        options["n_periods"] = 5
    elif "kw_2000" in str(model_or_seed):
        options["n_periods"] = 3

    return params, options
Exemplo n.º 20
0
def test_invariant_results_for_two_estimations():
    num_agents = np.random.randint(5, 100)
    constr = {
        "simulation_agents": num_agents,
        "n_periods": np.random.randint(1, 4),
        "n_lagged_choices": np.random.choice(2),
    }

    # Simulate a dataset.
    params, options = generate_random_model(point_constr=constr)
    df = simulate_truncated_data(params, options)

    crit_func = get_crit_func(params, options, df)

    # First estimation.
    crit_val = crit_func(params)

    # Second estimation.
    crit_val_ = crit_func(params)

    assert crit_val == crit_val_
Exemplo n.º 21
0
def process_model_or_seed(model_or_seed=None, **kwargs):
    if isinstance(model_or_seed, str):
        params, options = rp.get_example_model(model_or_seed, with_data=False)
    elif isinstance(model_or_seed, int):
        np.random.seed(model_or_seed)
        params, options = generate_random_model(**kwargs)
    else:
        raise ValueError

    if "kw_94" in str(model_or_seed):
        options["n_periods"] = 10
    elif "kw_97" in str(model_or_seed):
        options["n_periods"] = 5
    elif "kw_2000" in str(model_or_seed):
        options["n_periods"] = 3
    elif "robinson_crusoe_extended" in str(model_or_seed):
        options["n_periods"] = 5
    elif "robinson_crusoe_with_observed_characteristics" in str(model_or_seed):
        options["n_periods"] = 5

    return params, options
Exemplo n.º 22
0
def test_normalize_probabilities():
    constraints = {"observables": [3]}
    params, options = generate_random_model(point_constr=constraints)
    optim_paras_1, _ = process_params_and_options(params, options)

    for group in ["initial_exp_edu", "observable_"]:
        mask = params.index.get_level_values(0).str.contains(group)
        params.loc[mask, "value"] = params.loc[mask, "value"].to_numpy() / 2

    with pytest.warns(UserWarning, match=r"The probabilities for parameter group"):
        optim_paras_2, _ = process_params_and_options(params, options)

    for key in optim_paras_1["choices"]["edu"]["start"]:
        np.testing.assert_array_almost_equal(
            optim_paras_1["choices"]["edu"]["start"][key],
            optim_paras_2["choices"]["edu"]["start"][key],
        )
    for level in optim_paras_1["observables"]["observable_0"]:
        np.testing.assert_array_almost_equal(
            optim_paras_1["observables"]["observable_0"][level],
            optim_paras_2["observables"]["observable_0"][level],
        )
Exemplo n.º 23
0
def test_equality_for_myopic_agents_and_tiny_delta(seed):
    """Test equality of simulated data and likelihood with myopia and tiny delta."""
    np.random.seed(seed)

    # Get simulated data and likelihood for myopic model.
    params, options = generate_random_model(myopic=True)

    simulate = rp.get_simulate_func(params, options)
    df = simulate(params)

    crit_func = get_crit_func(params, options, df)
    likelihood = crit_func(params)

    # Get simulated data and likelihood for model with tiny delta.
    params.loc["delta", "value"] = 1e-12

    df_ = simulate(params)

    crit_func_ = rp.get_crit_func(params, options, df_)
    likelihood_ = crit_func_(params)

    pd.testing.assert_frame_equal(df, df_)
    np.testing.assert_almost_equal(likelihood, likelihood_, decimal=12)
Exemplo n.º 24
0
def test_dense_choice_cores():
    """
    Check whether continuation values are equal for paths where the restrictions do not
    make any difference. We check continuation values at states where one choice leads
    to a remaining decision tree that is equivalent to the unrestricted problem and one
    where this is not the case!

    """
    if CHAOSPY_INSTALLED:
        point_constr = {
            "n_periods": 6,
            "observables": [3],
            "n_lagged_choices": 1
        }

        params, options = generate_random_model(point_constr=point_constr)
        options["monte_carlo_sequence"] = "sobol"

        # Add some inadmissible states
        optim_paras, _ = process_params_and_options(params, options)

        # Solve the base model
        solve = get_solve_func(params, options)
        state_space = solve(params)

        # Retrieve index
        edu_start = np.random.choice(
            list(optim_paras["choices"]["edu"]["start"].keys()))
        state = (3, 0, 3, edu_start, 1)
        core_ix = state_space.indexer[state]

        # Choose dense covar
        pos = np.random.choice(range(len(state_space.dense)))

        # Get indices
        dense_combination = list(state_space.dense.keys())[pos]
        dense_index = state_space.dense_covariates_to_dense_index[
            dense_combination]
        ix = (
            state_space.core_key_and_dense_index_to_dense_key[core_ix[0],
                                                              dense_index],
            core_ix[1],
        )

        unrestricted_cont = state_space.get_continuation_values(3)[ix[0]][
            ix[1]]

        # Impose some restriction
        options["negative_choice_set"] = {"a": ["period == 4 & exp_b ==4"]}

        # Solve the restricted model
        solve = get_solve_func(params, options)
        state_space = solve(params)
        core_ix = state_space.indexer[state]

        # Get indices
        dense_combination = list(state_space.dense.keys())[pos]
        dense_index = state_space.dense_covariates_to_dense_index[
            dense_combination]
        ix = (
            state_space.core_key_and_dense_index_to_dense_key[core_ix[0],
                                                              dense_index],
            core_ix[1],
        )

        # Check some features of the state_space
        restricted_cont = state_space.get_continuation_values(3)[ix[0]][ix[1]]

        for i in [0, 2, 3]:
            assert restricted_cont[i] == unrestricted_cont[i]
        assert restricted_cont[1] != unrestricted_cont[1]