Note
Go to the end to download the full example code.
Baseline mode choice model: maximum likelihood estimationΒΆ
This example estimates a multinomial logit model for transportation mode choice using maximum likelihood and Biogeme.
It is the baseline specification of the hybrid-choice tutorial. The model contains only observed choice variables and standard utility functions: there are no latent variables, structural equations, or measurement equations. The results therefore provide a reference against which the hybrid-choice specifications introduced later can be compared.
The script performs the following steps:
load the Optima mode-choice data,
build the utility functions from the common tutorial specification,
construct the logit log-likelihood,
estimate the model, or reload previously saved estimation results,
display the estimated parameters as pandas and LaTeX tables.
Michel Bierlaire Sat Jun 06 2026, 15:23:41
from choice_latent_variables import generate_utility_functions
from optima import (
Choice,
read_data,
)
import biogeme.biogeme_logging as blog
from biogeme.biogeme import BIOGEME
from biogeme.models import loglogit
from biogeme.results_processing import (
get_latex_estimated_parameters,
get_latex_general_statistics,
get_pandas_estimated_parameters,
)
logger = blog.get_screen_logger(level=blog.INFO)
/Users/bierlair/MyFiles/github/biogeme/docs/source/examples/hybrid_choice_models/choice_latent_variables.py:83: SyntaxWarning: "\m" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\m"? A raw string is also an option.
V_{\mathrm{PT}}
Load the Optima mode-choice data.
database = read_data()
# Build the utility functions for the transportation alternatives.
utilities = generate_utility_functions()
# Construct the log-likelihood of the multinomial logit model.
log_likelihood = loglogit(utilities, None, Choice)
# Create the Biogeme object used for estimation.
biogeme = BIOGEME(
database,
log_likelihood,
)
biogeme.model_name = 'plot_h01_mode_logit'
# Estimate the model, or reload the saved results if they are already available.
yaml_file_name = f'saved_results/{biogeme.model_name}.yaml'
results = biogeme.estimate_or_load(yaml_file_name=yaml_file_name)
# Display a compact summary and the estimated parameters.
print(results.short_summary())
print(get_pandas_estimated_parameters(estimation_results=results))
general_statistics = get_latex_general_statistics(estimation_results=results)
print(general_statistics)
estimated_parameters = get_latex_estimated_parameters(estimation_results=results)
print(estimated_parameters[''])
Default values of the Biogeme parameters are used.
File biogeme.toml has been created
Estimation results are read from saved_results/plot_h01_mode_logit.yaml. No estimation is performed.
Results for model plot_h01_mode_logit
Nbr of parameters: 7
Sample size: 889
Excluded data: 0
Final log likelihood: -508.6166
Akaike Information Criterion: 1031.233
Bayesian Information Criterion: 1064.764
{'Estimated parameters': Name Value ... Robust t-stat. Robust p-value
0 choice_scale_parameter 0.078161 ... 4.176004 0.000030
1 choice_asc_pt -8.705850 ... -1.475779 0.140003
2 choice_beta_time_pt -12.182632 ... -2.859609 0.004242
3 choice_asc_car -3.065828 ... -0.609093 0.542463
4 choice_beta_time_car -25.982708 ... -2.940295 0.003279
5 choice_beta_dist_work -2.612986 ... -3.112401 0.001856
6 choice_beta_dist_other_purposes -4.124008 ... -3.377163 0.000732
[7 rows x 5 columns]}
%% General statistics
\section{General statistics}
\begin{tabular}{ll}
Number of estimated parameters & 7 \\
Sample size & 889 \\
Excluded observations & 0 \\
Init log likelihood & -5937.274 \\
Final log likelihood & -508.6166 \\
Likelihood ratio test for the init. model & 10857.31 \\
Rho-square for the init. model & 0.914 \\
Rho-square-bar for the init. model & 0.913 \\
Akaike Information Criterion & 1031.233 \\
Bayesian Information Criterion & 1064.764 \\
Final gradient norm & 2.8171E-05 \\
Bootstrapping time & None \\
Algorithm & \verb$Newton with trust region for simple bound constraints$ \\
Cause of termination & \verb$Relative gradient = 7.8e-08 <= 6.1e-06$ \\
Number of function evaluations & \verb$45$ \\
Number of gradient evaluations & \verb$27$ \\
Number of hessian evaluations & \verb$13$ \\
Number of iterations & \verb$18$ \\
Optimization time & \verb$0:00:01.428014$ \\
Proportion of Hessian calculation & \verb$13/13 = 100.0%$ \\
Relative gradient & \verb$7.786e-08$ \\
\end{tabular}
\begin{tabular}{rlr@{.}lr@{.}lr@{.}lr@{.}l}
& & \multicolumn{2}{l}{} & \multicolumn{2}{l}{Robust} & \multicolumn{4}{l}{} \\
Parameter & & \multicolumn{2}{l}{Coeff.} & \multicolumn{2}{l}{Asympt.} & \multicolumn{4}{l}{} \\
number & Description & \multicolumn{2}{l}{estimate} & \multicolumn{2}{l}{std. error} & \multicolumn{2}{l}{$t$-stat} & \multicolumn{2}{l}{$p$-value} \\
\hline
0 & choice\_scale\_parameter & 0&0782 & 0&0187 & 4&18 & 2&97e-05 \\
1 & choice\_asc\_pt & -8&71 & 5&90 & -1&48 & 0&140 \\
2 & choice\_beta\_time\_pt & -12&2 & 4&26 & -2&86 & 0&00424 \\
3 & choice\_asc\_car & -3&07 & 5&03 & -0&609 & 0&542 \\
4 & choice\_beta\_time\_car & -26&0 & 8&84 & -2&94 & 0&00328 \\
5 & choice\_beta\_dist\_work & -2&61 & 0&840 & -3&11 & 0&00186 \\
6 & choice\_beta\_dist\_other\_purposes & -4&12 & 1&22 & -3&38 & 0&000732 \\
\end{tabular}
Total running time of the script: (0 minutes 1.082 seconds)