Note
Go to the end to download the full example code.
Estimation of the hybrid choice modelΒΆ
Full information estimation of the model combining observed choice and Likert scale psychometric indicators.
Michel Bierlaire, EPFL Wed Sept 03 2025, 08:19:40
from choice_model import v
from IPython.core.display_functions import display
from measurement_equations_likert import generate_likert_measurement_equations
from optima import (
Choice,
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.expressions import Expression, MonteCarlo, log
from biogeme.models import logit
from biogeme.results_processing import (
EstimationResults,
get_pandas_estimated_parameters,
)
NUMBER_OF_DRAWS = 10_000
logger = blog.get_screen_logger(level=blog.INFO)
database = read_data()
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 for the indicators
measurement_equations: Expression = generate_likert_measurement_equations(
car_centric_attitude, urban_preference_attitude
)
Conditional likelihood for the choice model
choice_likelihood = logit(v, None, Choice)
conditional_likelihood = choice_likelihood * measurement_equations
Log likelihood
log_likelihood = log(MonteCarlo(conditional_likelihood))
Create the Biogeme object
print('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 = 'b03_hybrid'
Create the biogeme object
Biogeme parameters read from biogeme.toml.
If estimation results are saved on file, we read them to speed up the process. If not, we estimate the parameters.
results: EstimationResults = read_or_estimate(
the_biogeme=the_biogeme, directory='saved_results'
)
Results are read from the file saved_results/b03_hybrid.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: 84
final log likelihood: -17367.158
Output file: None
pandas_results = get_pandas_estimated_parameters(estimation_results=results)
display(pandas_results)
Name ... BHHH p-value
0 log_scale_choice_model_short_dist ... 0.000000e+00
1 log_scale_choice_model_long_dist ... 0.000000e+00
2 choice_asc_pt_short_dist ... 5.652436e-04
3 choice_asc_pt_long_dist ... 2.272115e-01
4 choice_beta_time_pt_short_dist ... 1.588512e-04
.. ... ... ...
79 meas_car_centric_attitude_coeff_Mobil08 ... 9.490186e-13
80 meas_scale_Mobil08 ... 0.000000e+00
81 meas_intercept_Mobil07 ... 0.000000e+00
82 meas_car_centric_attitude_coeff_Mobil07 ... 5.021534e-06
83 meas_scale_Mobil07 ... 0.000000e+00
[84 rows x 5 columns]
Total running time of the script: (0 minutes 4.300 seconds)