Skip to content

example_choosiow module

example using the Choo and Siow homoskedastic model

create_choosiow_population(X, Y, K, std_betas)

we simulate a Choo and Siow population with equal numbers of men and women of each type and random bases functions and coefficients

1
2
3
4
5
6
7
8
9
Args:
 X: number of types of men
 Y: number of types of women
 K: random basis functions
 std_betas: the coefficients are drawn from a centered normal
             with this standard deviation

Returns:
    a `ChooSiowPrimitives` instance, the basis functions, and the coefficients
Source code in cupid_matching/example_choo_siow.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
def create_choosiow_population(
    X: int, Y: int, K: int, std_betas: float
) -> tuple[ChooSiowPrimitives, np.ndarray, np.ndarray]:
    """
    we simulate a Choo and Siow population
    with equal numbers of men and women of each type
    and random bases functions and coefficients

        Args:
         X: number of types of men
         Y: number of types of women
         K: random basis functions
         std_betas: the coefficients are drawn from a centered normal
                     with this standard deviation

        Returns:
            a `ChooSiowPrimitives` instance, the basis functions, and the coefficients
    """
    betas_true = std_betas * np.random.randn(K)
    phi_bases = np.random.randn(X, Y, K)
    n = np.ones(X)
    m = np.ones(Y)
    Phi = phi_bases @ betas_true
    choo_siow_instance = ChooSiowPrimitives(Phi, n, m)
    return choo_siow_instance, phi_bases, betas_true

demo_choo_siow(n_households, X, Y, K, std_betas=1.0)

run four MDE estimators and the Poisson estimator on randomly generated data

Parameters:

Name Type Description Default
n_households int

number of households

required
X int

number of types of men

required
Y int

number of types of women

required
K int

number of basis functions

required
std_betas float

the standard errors of their coefficients

1.0

Returns:

Type Description
tuple[float, float, float, float, float]

the discrepancies of the five estimators

Source code in cupid_matching/example_choo_siow.py
 81
 82
 83
 84
 85
 86
 87
 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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
def demo_choo_siow(
    n_households: int, X: int, Y: int, K: int, std_betas: float = 1.0
) -> tuple[float, float, float, float, float]:
    """run four MDE estimators and the Poisson estimator
    on randomly generated data

    Args:
        n_households: number of households
        X: number of types of men
        Y: number of types of women
        K: number of basis functions
        std_betas: the standard errors of their coefficients

    Returns:
        the discrepancies of the five estimators
    """
    choo_siow_instance, phi_bases, betas_true = create_choosiow_population(
        X, Y, K, std_betas
    )
    mus_sim = choo_siow_instance.simulate(n_households)

    # we estimate using four variants of the minimum distance estimator
    mde_discrepancy = mde_estimate(
        mus_sim,
        phi_bases,
        betas_true,
        entropy_choo_siow,
        title="RESULTS FOR MDE WITH ANALYTICAL GRADIENT",
    )
    mde_discrepancy_numeric = mde_estimate(
        mus_sim,
        phi_bases,
        betas_true,
        entropy_choo_siow_numeric,
        title="RESULTS FOR MDE WITH NUMERICAL GRADIENT",
    )
    mde_discrepancy_corrected = mde_estimate(
        mus_sim,
        phi_bases,
        betas_true,
        entropy_choo_siow_corrected,
        title="RESULTS FOR THE CORRECTED MDE WITH ANALYTICAL GRADIENT",
    )
    mde_discrepancy_corrected_numeric = mde_estimate(
        mus_sim,
        phi_bases,
        betas_true,
        entropy_choo_siow_corrected_numeric,
        title="RESULTS FOR THE CORRECTED MDE WITH NUMERICAL GRADIENT",
    )

    # we also estimate using Poisson GLM
    print_stars("    RESULTS FOR POISSON   ")
    poisson_results = choo_siow_poisson_glm(mus_sim, phi_bases)
    _, mux0_sim, mu0y_sim, n_sim, m_sim = mus_sim.unpack()
    poisson_discrepancy = poisson_results.print_results(
        betas_true,
        u_true=-np.log(mux0_sim / n_sim),
        v_true=-np.log(mu0y_sim / m_sim),
    )
    return (
        mde_discrepancy,
        mde_discrepancy_numeric,
        mde_discrepancy_corrected,
        mde_discrepancy_corrected_numeric,
        cast(float, poisson_discrepancy),
    )

mde_estimate(mus_sim, phi_bases, betas_true, entropy, no_singles=False, title=None, verbose=False)

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
betas_true np.ndarray

their true coefficients

required
entropy EntropyFunctions

the entropy functions we use

required
no_singles bool

if True, we use the no-singles version of the model

False
title str | None

the name of the estimator

None

Returns:

Type Description
float

the largest absolute difference between the true and estimated coefficients

Source code in cupid_matching/example_choo_siow.py
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
def mde_estimate(
    mus_sim: Matching,
    phi_bases: np.ndarray,
    betas_true: np.ndarray,
    entropy: EntropyFunctions,
    no_singles: bool = False,
    title: str | None = None,
    verbose: bool = False,
) -> float:
    """we estimate the parameters using the minimum distance estimator

    Args:
        mus_sim: a Choo and Siow Matching
        phi_bases: the basis functions
        betas_true: their true coefficients
        entropy: the entropy functions we use
        no_singles: if `True`, we use the no-singles version of the model
        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,
        no_singles=no_singles,
        verbose=verbose,
    )
    mde_discrepancy = mde_results.print_results(true_coeffs=betas_true)
    return cast(float, mde_discrepancy)