Skip to content

example_nestedlogit module

example using a simple two-layer nested logit model One nest on each side must consist of the 0 option. The other nests are specified as nested lists. E.g. [[1, 3], [2,4]] describes two nests, one with types 1 and 3, and the other with types 2 and 4. On each side, the nests are the same for each type, with the same parameters.

create_nestedlogit_population(X, Y, K, std_alphas=0.5, std_betas=1.0)

we simulate a nested logit population with equal numbers of men and women of each type and random bases dunctions and coefficients

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Args:
 X: number of types of men
 Y: number of types of women
 K: random basis functions
 std_alphas: the nest parameters are drawn from a U[0, std_alphas] distribution
 std_betas: the coefficients of the bases are drawn from a centered normal
             with this standard deviation

Returns:
    a NestedLogitPrimitives instance, the basis functions, the true coefficients,
    and the entropy functions
Source code in cupid_matching/example_nested_logit.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
def create_nestedlogit_population(
    X: int,
    Y: int,
    K: int,
    std_alphas: float = 0.5,
    std_betas: float = 1.0,
) -> tuple[
    NestedLogitPrimitives,
    np.ndarray,
    np.ndarray,
    EntropyFunctions,
    EntropyFunctions,
]:
    """
    we simulate a nested logit population
    with equal numbers of men and women of each type
    and random bases dunctions and coefficients

        Args:
         X: number of types of men
         Y: number of types of women
         K: random basis functions
         std_alphas: the nest parameters are drawn from a U[0, std_alphas] distribution
         std_betas: the coefficients of the bases are drawn from a centered normal
                     with this standard deviation

        Returns:
            a NestedLogitPrimitives instance, the basis functions, the true coefficients,
            and the entropy functions
    """
    X, Y, K = 10, 12, 5
    nests_for_each_x = [
        list(range(1, Y // 2 + 1)),
        list(range(Y // 2 + 1, Y + 1)),
    ]
    nests_for_each_y = [
        list(range(1, X // 2 + 1)),
        list(range(X // 2 + 1, X + 1)),
    ]

    n = np.ones(X)
    m = np.ones(Y)
    phi_bases = np.random.randn(X, Y, K)

    (
        entropy_nested_logit,
        entropy_nested_logit_numeric,
    ) = setup_standard_nested_logit(nests_for_each_x, nests_for_each_y)
    n_rhos, n_deltas = len(nests_for_each_x), len(nests_for_each_y)
    n_alphas = n_rhos + n_deltas

    betas_true = std_betas * np.random.randn(K)
    alphas_true = std_alphas * np.random.uniform(size=n_alphas)

    Phi = phi_bases @ betas_true
    nested_logit_instance = NestedLogitPrimitives(
        Phi, n, m, nests_for_each_x, nests_for_each_y, alphas_true
    )
    true_coeffs = np.concatenate((alphas_true, betas_true))
    return (
        nested_logit_instance,
        phi_bases,
        true_coeffs,
        entropy_nested_logit,
        entropy_nested_logit_numeric,
    )

mde_estimate(mus_sim, phi_bases, true_coeffs, entropy, title)

we estimate the parameters using the minimum distance estimator

Parameters:

Name Type Description Default
mus_sim Matching

a Choo and Siow Matching

required
phi_bases np.ndarray

the basis functions

required
true_coeffs np.ndarray

their true coefficients and the nesting parameters

required
entropy EntropyFunctions

the entropy functions we use

required
title str

the name of the estimator

required

Returns:

Type Description
float

the largest absolute difference between the true and estimated coefficients

Source code in cupid_matching/example_nested_logit.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def mde_estimate(
    mus_sim: Matching,
    phi_bases: np.ndarray,
    true_coeffs: np.ndarray,
    entropy: EntropyFunctions,
    title: str,
) -> float:
    """we estimate the parameters using the minimum distance estimator

    Args:
        mus_sim: a Choo and Siow Matching
        phi_bases: the basis functions
        true_coeffs: their true coefficients and  the nesting parameters
        entropy: the entropy functions we use
        title: the name of the estimator

    Returns:
        the largest absolute difference between the true and estimated coefficients
    """
    print_stars(f"    {title}")
    mde_results = estimate_semilinear_mde(
        mus_sim,
        phi_bases,
        entropy,
        additional_parameters=entropy.additional_parameters,
    )
    mde_discrepancy = mde_results.print_results(true_coeffs=true_coeffs)
    return cast(float, mde_discrepancy)