MIMIC (Multiple Indicators Multiple Causes) model

THe MIMIC model involves two latent_old variables: “car centric” attitude, and “urban preference” attitude. We consider the indicators as continuous Michel Bierlaire, EPFL Fri May 16 2025, 10:32:30

from IPython.core.display_functions import display
from measurement_equations_likert import generate_likert_measurement_equations
from optima import read_data
from read_or_estimate import read_or_estimate
from structural_equations import (
    LatentVariable,
    build_car_centric_attitude,
    build_urban_preference_attitude,
)

import biogeme.biogeme_logging as blog
from biogeme.biogeme import BIOGEME
from biogeme.database import Database
from biogeme.expressions import Expression, MonteCarlo, log
from biogeme.results_processing import (
    get_pandas_estimated_parameters,
)

logger = blog.get_screen_logger(level=blog.INFO)

NUMBER_OF_DRAWS = 10

Structural equation: car centric attitude

car_centric_attitude: LatentVariable = build_car_centric_attitude()

Structural equation: urban preference

urban_preference_attitude: LatentVariable = build_urban_preference_attitude()

Generate the measurement equations

measurement_equations: Expression = generate_likert_measurement_equations(
    car_centric_attitude, urban_preference_attitude
)

Generate the loglikelihood function

log_likelihood = log(MonteCarlo(measurement_equations))

Read the data

database: Database = read_data()

Create the Biogeme object.

the_biogeme = BIOGEME(
    database,
    log_likelihood,
    number_of_draws=NUMBER_OF_DRAWS,
    calculating_second_derivatives='never',
    numerically_safe=True,
    max_iterations=5000,
)
the_biogeme.model_name = 'b01_mimic_discrete'
Biogeme parameters read from biogeme.toml.
The number of draws (10) is low. The results may not be meaningful.

If estimation results are saved on file, we read them to speed up the process. If not, we estimate the parameters.

results = read_or_estimate(the_biogeme=the_biogeme, directory='saved_results')
Results are read from the file saved_results/b01_mimic_discrete.yaml.
print(f'Estimated betas: {results.number_of_parameters}')
print(f'final log likelihood: {results.final_log_likelihood:.3f}')
print(f'Output file: {the_biogeme.html_filename}')
Estimated betas: 72
final log likelihood: -17191.128
Output file: None
pandas_results = get_pandas_estimated_parameters(estimation_results=results)
display(pandas_results)
                                              Name  ...  BHHH p-value
0                          meas_intercept_LifSty07  ...  0.000000e+00
1         meas_car_centric_attitude_coeff_LifSty07  ...  3.703281e-07
2                         struct_car_highEducation  ...  1.072475e-13
3                           struct_car_top_manager  ...  1.431735e-01
4                             struct_car_employees  ...  3.965799e-01
..                                             ...  ...           ...
67  meas_urban_preference_attitude_coeff_ResidCh02  ...  8.939391e-07
68                            meas_scale_ResidCh02  ...  0.000000e+00
69                          meas_intercept_Mobil05  ...  1.386431e-01
70         meas_car_centric_attitude_coeff_Mobil05  ...  7.771561e-15
71                              meas_scale_Mobil05  ...  0.000000e+00

[72 rows x 5 columns]

Total running time of the script: (0 minutes 1.936 seconds)

Gallery generated by Sphinx-Gallery