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_availability, 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:84: 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()

# Availability
availability = generate_availability()

# Construct the log-likelihood of the multinomial logit model.
log_likelihood = loglogit(utilities, availability, 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:           -486.6121
Akaike Information Criterion:   987.2241
Bayesian Information Criterion: 1020.755

{'Estimated parameters':                               Name      Value  ...  Robust t-stat.  Robust p-value
0           choice_scale_parameter   0.070267  ...        3.872426        0.000108
1                    choice_asc_pt  -9.400998  ...       -1.381116        0.167243
2              choice_beta_time_pt -14.974005  ...       -2.901699        0.003711
3                   choice_asc_car  -2.669523  ...       -0.467447        0.640180
4             choice_beta_time_car -30.947933  ...       -2.909002        0.003626
5            choice_beta_dist_work  -2.932912  ...       -2.974942        0.002930
6  choice_beta_dist_other_purposes  -4.692437  ...       -3.198592        0.001381

[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 & -5936.166 \\
Final log likelihood & -486.6121 \\
Likelihood ratio test for the init. model & 10899.11 \\
Rho-square for the init. model & 0.918 \\
Rho-square-bar for the init. model & 0.917 \\
Akaike Information Criterion & 987.2241 \\
Bayesian Information Criterion & 1020.755 \\
Final gradient norm & 5.4654E-04 \\
Bootstrapping time & None \\
Algorithm & \verb$Newton with trust region for simple bound constraints$ \\
Cause of termination & \verb$Relative gradient = 1.3e-07 <= 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.064024$ \\
Proportion of Hessian calculation & \verb$13/13 = 100.0%$ \\
Relative gradient & \verb$1.331e-07$ \\
\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&0703 & 0&0181 & 3&87 & 0&000108 \\
1 & choice\_asc\_pt & -9&40 & 6&81 & -1&38 & 0&167 \\
2 & choice\_beta\_time\_pt & -15&0 & 5&16 & -2&90 & 0&00371 \\
3 & choice\_asc\_car & -2&67 & 5&71 & -0&467 & 0&640 \\
4 & choice\_beta\_time\_car & -30&9 & 10&6 & -2&91 & 0&00363 \\
5 & choice\_beta\_dist\_work & -2&93 & 0&986 & -2&97 & 0&00293 \\
6 & choice\_beta\_dist\_other\_purposes & -4&69 & 1&47 & -3&20 & 0&00138 \\

\end{tabular}

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

Gallery generated by Sphinx-Gallery