.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/bayesian_swissmetro/plot_b09_nested.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_bayesian_swissmetro_plot_b09_nested.py: 9. Nested logit model ===================== Bayesian estimation of a nested logit model. Michel Bierlaire, EPFL Mon Nov 03 2025, 20:02:56 .. GENERATED FROM PYTHON SOURCE LINES 11-16 .. code-block:: Python from pathlib import Path from IPython.core.display_functions import display .. GENERATED FROM PYTHON SOURCE LINES 17-18 See the data processing script: :ref:`swissmetro_data`. .. GENERATED FROM PYTHON SOURCE LINES 18-46 .. code-block:: Python from swissmetro_data import ( CAR_AV_SP, CAR_CO_SCALED, CAR_TT_SCALED, CHOICE, SM_AV, SM_COST_SCALED, SM_TT_SCALED, TRAIN_AV_SP, TRAIN_COST_SCALED, TRAIN_TT_SCALED, database, ) from biogeme import biogeme_logging as blog from biogeme.bayesian_estimation import ( BayesianResults, BayesianResultsSummary, get_pandas_estimated_parameters, ) from biogeme.biogeme import BIOGEME from biogeme.expressions import Beta from biogeme.models import lognested from biogeme.nests import NestsForNestedLogit, OneNestForNestedLogit logger = blog.get_screen_logger(level=blog.INFO) logger.info('Example b09_nested') .. rst-class:: sphx-glr-script-out .. code-block:: none Example b09_nested .. GENERATED FROM PYTHON SOURCE LINES 47-48 Parameters to be estimated. .. GENERATED FROM PYTHON SOURCE LINES 48-55 .. code-block:: Python asc_car = Beta('asc_car', 0, None, None, 0) asc_train = Beta('asc_train', 0, None, None, 0) asc_sm = Beta('asc_sm', 0, None, None, 1) b_time = Beta('b_time', 0, None, 0, 0) b_cost = Beta('b_cost', 0, None, 0, 0) nest_parameter = Beta('nest_parameter', 1, 1, 3, 0) .. GENERATED FROM PYTHON SOURCE LINES 56-57 Definition of the utility functions. .. GENERATED FROM PYTHON SOURCE LINES 57-61 .. code-block:: Python v_train = asc_train + b_time * TRAIN_TT_SCALED + b_cost * TRAIN_COST_SCALED v_swissmetro = asc_sm + b_time * SM_TT_SCALED + b_cost * SM_COST_SCALED v_car = asc_car + b_time * CAR_TT_SCALED + b_cost * CAR_CO_SCALED .. GENERATED FROM PYTHON SOURCE LINES 62-63 Associate utility functions with the numbering of alternatives. .. GENERATED FROM PYTHON SOURCE LINES 63-65 .. code-block:: Python v = {1: v_train, 2: v_swissmetro, 3: v_car} .. GENERATED FROM PYTHON SOURCE LINES 66-67 Associate the availability conditions with the alternatives. .. GENERATED FROM PYTHON SOURCE LINES 67-69 .. code-block:: Python av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} .. GENERATED FROM PYTHON SOURCE LINES 70-74 Definition of nests. Only the non-trivial nests must be defined. A trivial nest is a nest containing exactly one alternative. In this example, we create a nest for the existing modes, that is train (1) and car (3). .. GENERATED FROM PYTHON SOURCE LINES 74-81 .. code-block:: Python existing = OneNestForNestedLogit( nest_param=nest_parameter, list_of_alternatives=[1, 3], name='existing' ) nests = NestsForNestedLogit(choice_set=list(v), tuple_of_nests=(existing,)) .. rst-class:: sphx-glr-script-out .. code-block:: none The following elements do not appear in any nest and are assumed each to be alone in a separate nest: {2}. If it is not the intention, check the assignment of alternatives to nests. .. GENERATED FROM PYTHON SOURCE LINES 82-85 Definition of the model. This is the contribution of each observation to the log likelihood function. The choice model is a nested logit, with availability conditions. .. GENERATED FROM PYTHON SOURCE LINES 85-87 .. code-block:: Python log_probability = lognested(v, av, nests, CHOICE) .. GENERATED FROM PYTHON SOURCE LINES 88-89 Create the Biogeme object. .. GENERATED FROM PYTHON SOURCE LINES 89-95 .. code-block:: Python the_biogeme = BIOGEME( database, log_probability, ) the_biogeme.model_name = 'b09_nested' .. rst-class:: sphx-glr-script-out .. code-block:: none Biogeme parameters read from biogeme.toml. .. GENERATED FROM PYTHON SOURCE LINES 96-98 Estimate the posterior distribution of the parameters, or read the results if already available. .. GENERATED FROM PYTHON SOURCE LINES 98-105 .. code-block:: Python yaml_file = Path('saved_results') / f'{the_biogeme.model_name}.yaml' try: summary_results = BayesianResultsSummary.from_yaml_file(filename=yaml_file) except FileNotFoundError: results: BayesianResults = the_biogeme.bayesian_estimation() summary_results = results.to_summary() .. GENERATED FROM PYTHON SOURCE LINES 106-108 .. code-block:: Python print(summary_results.short_summary()) .. rst-class:: sphx-glr-script-out .. code-block:: none Sample size 6768 Sampler NUTS Number of chains 4 Number of draws per chain 2000 Total number of draws 8000 Acceptance rate target 0.9 Run time 0:01:13.630640 Posterior predictive log-likelihood (sum of log mean p) -5234.16 Expected log-likelihood E[log L(Y|θ)] -5239.40 Best-draw log-likelihood (posterior upper bound) -5236.95 LOO (Leave-One-Out Cross-Validation) -5244.78 LOO Standard Error 62.43 Effective number of parameters (p_LOO) 10.61 .. GENERATED FROM PYTHON SOURCE LINES 109-110 Present the parameter estimates in a pandas table. .. GENERATED FROM PYTHON SOURCE LINES 110-115 .. code-block:: Python pandas_results = get_pandas_estimated_parameters( estimation_results=summary_results, ) display(pandas_results) .. rst-class:: sphx-glr-script-out .. code-block:: none Name Value (mean) ... ESS (bulk) ESS (tail) 0 asc_train -0.512258 ... 3780.857775 4376.578915 1 asc_car -0.166730 ... 3544.475464 4047.261422 2 b_time -0.899860 ... 3278.500453 4214.372089 3 b_cost -0.857638 ... 4584.850376 4675.997401 4 nest_parameter 2.055084 ... 4336.560782 4617.790002 [5 rows x 12 columns] .. GENERATED FROM PYTHON SOURCE LINES 116-117 Report the variables stored in the Bayesian estimation results. .. GENERATED FROM PYTHON SOURCE LINES 117-119 .. code-block:: Python display(summary_results.report_stored_variables()) .. rst-class:: sphx-glr-script-out .. code-block:: none group variable dims shape 0 constant_data CAR_AV_SP [obs] [6768] 1 constant_data CAR_CO_SCALED [obs] [6768] 2 constant_data CAR_TT_SCALED [obs] [6768] 3 constant_data CHOICE [obs] [6768] 4 constant_data SM_AV [obs] [6768] 5 constant_data SM_COST_SCALED [obs] [6768] 6 constant_data SM_TT_SCALED [obs] [6768] 7 constant_data TRAIN_AV_SP [obs] [6768] 8 constant_data TRAIN_COST_SCALED [obs] [6768] 9 constant_data TRAIN_TT_SCALED [obs] [6768] 10 log_likelihood _choice [chain, draw, obs] [4, 2000, 6768] 11 posterior asc_car [chain, draw] [4, 2000] 12 posterior asc_train [chain, draw] [4, 2000] 13 posterior b_cost [chain, draw] [4, 2000] 14 posterior b_time [chain, draw] [4, 2000] 15 posterior log_like [chain, draw, obs] [4, 2000, 6768] 16 posterior nest_parameter [chain, draw] [4, 2000] 17 prior asc_car [chain, draw] [1, 2000] 18 prior asc_train [chain, draw] [1, 2000] 19 prior b_cost [chain, draw] [1, 2000] 20 prior b_time [chain, draw] [1, 2000] 21 prior log_like [chain, draw, obs] [1, 2000, 6768] 22 prior nest_parameter [chain, draw] [1, 2000] 23 sample_stats acceptance_rate [chain, draw] [4, 2000] 24 sample_stats diverging [chain, draw] [4, 2000] 25 sample_stats energy [chain, draw] [4, 2000] 26 sample_stats lp [chain, draw] [4, 2000] 27 sample_stats n_steps [chain, draw] [4, 2000] 28 sample_stats step_size [chain, draw] [4, 2000] 29 sample_stats tree_depth [chain, draw] [4, 2000] .. GENERATED FROM PYTHON SOURCE LINES 120-122 We calculate the correlation between the error terms of the alternatives. .. GENERATED FROM PYTHON SOURCE LINES 122-127 .. code-block:: Python corr = nests.correlation( parameters=summary_results.get_beta_values(), alternatives_names={1: 'Train', 2: 'Swissmetro', 3: 'Car'}, ) print(corr) .. rst-class:: sphx-glr-script-out .. code-block:: none Train Swissmetro Car Train 1.000000 0.0 0.763222 Swissmetro 0.000000 1.0 0.000000 Car 0.763222 0.0 1.000000 .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.034 seconds) .. _sphx_glr_download_auto_examples_bayesian_swissmetro_plot_b09_nested.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_b09_nested.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_b09_nested.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_b09_nested.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_