.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/bayesian_swissmetro/plot_b10_nested_bottom.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_b10_nested_bottom.py: 10. Nested logit model normalized from bottom ============================================= Bayesian estimation of a nested logit model where the normalization is done at the bottom level. Michel Bierlaire, EPFL Mon Nov 03 2025, 20:07:02 .. GENERATED FROM PYTHON SOURCE LINES 12-17 .. code-block:: Python from pathlib import Path from IPython.core.display_functions import display .. GENERATED FROM PYTHON SOURCE LINES 18-19 See the data processing script: :ref:`swissmetro_data`. .. GENERATED FROM PYTHON SOURCE LINES 19-47 .. 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, ) import biogeme.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_mev_mu from biogeme.nests import NestsForNestedLogit, OneNestForNestedLogit logger = blog.get_screen_logger(level=blog.INFO) logger.info('Example b10nested_bottom.py') .. rst-class:: sphx-glr-script-out .. code-block:: none Example b10nested_bottom.py .. GENERATED FROM PYTHON SOURCE LINES 48-49 The scale parameters must stay away from zero. We define a small but positive lower bound .. GENERATED FROM PYTHON SOURCE LINES 49-51 .. code-block:: Python POSITIVE_LOWER_BOUND = 1.0e-5 .. GENERATED FROM PYTHON SOURCE LINES 52-53 Parameters to be estimated. .. GENERATED FROM PYTHON SOURCE LINES 53-59 .. 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) .. GENERATED FROM PYTHON SOURCE LINES 60-63 This is the scale parameter of the choice model. It is usually normalized to one. In this example, we normalize the nest parameter instead, and estimate the scale parameter for the model. .. GENERATED FROM PYTHON SOURCE LINES 63-65 .. code-block:: Python scale_parameter = Beta('scale_parameter', 0.5, POSITIVE_LOWER_BOUND, 1.0, 0) .. GENERATED FROM PYTHON SOURCE LINES 66-67 Definition of the utility functions .. GENERATED FROM PYTHON SOURCE LINES 67-71 .. 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 72-73 Associate utility functions with the numbering of alternatives. .. GENERATED FROM PYTHON SOURCE LINES 73-75 .. code-block:: Python v = {1: v_train, 2: v_swissmetro, 3: v_car} .. GENERATED FROM PYTHON SOURCE LINES 76-77 Associate the availability conditions with the alternatives. .. GENERATED FROM PYTHON SOURCE LINES 77-79 .. code-block:: Python av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} .. GENERATED FROM PYTHON SOURCE LINES 80-82 Definition of nests. Only the non trivial nests must be defined. A trivial nest is a nest containing exactly one alternative. The nest parameter is normalized to 1. .. GENERATED FROM PYTHON SOURCE LINES 82-89 .. code-block:: Python nest_parameter = 1.0 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 90-94 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, where the scale parameter mu is explicitly involved. .. GENERATED FROM PYTHON SOURCE LINES 94-96 .. code-block:: Python log_probability = lognested_mev_mu(v, av, nests, CHOICE, scale_parameter) .. GENERATED FROM PYTHON SOURCE LINES 97-98 Create the Biogeme object. .. GENERATED FROM PYTHON SOURCE LINES 98-101 .. code-block:: Python the_biogeme = BIOGEME(database, log_probability) the_biogeme.model_name = 'b10_nested_bottom' .. rst-class:: sphx-glr-script-out .. code-block:: none Biogeme parameters read from biogeme.toml. .. GENERATED FROM PYTHON SOURCE LINES 102-104 Estimate the posterior distribution of the parameters, or read the results if already available. .. GENERATED FROM PYTHON SOURCE LINES 104-111 .. 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 112-114 .. 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:15.092001 Posterior predictive log-likelihood (sum of log mean p) -5234.09 Expected log-likelihood E[log L(Y|θ)] -5239.41 Best-draw log-likelihood (posterior upper bound) -5236.96 LOO (Leave-One-Out Cross-Validation) -5244.87 LOO Standard Error 62.51 Effective number of parameters (p_LOO) 10.78 .. GENERATED FROM PYTHON SOURCE LINES 115-116 Present the parameter estimates in a pandas table. .. GENERATED FROM PYTHON SOURCE LINES 116-121 .. 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 -1.058813 ... 2800.385207 3178.820712 1 asc_car -0.349121 ... 2945.109954 3498.749239 2 b_time -1.850985 ... 3673.382521 4257.132277 3 b_cost -1.767942 ... 3736.113021 4408.544295 4 scale_parameter 0.484612 ... 3332.040480 4400.007045 [5 rows x 12 columns] .. GENERATED FROM PYTHON SOURCE LINES 122-123 Report the variables stored in the Bayesian estimation results. .. GENERATED FROM PYTHON SOURCE LINES 123-124 .. 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 scale_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 scale_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] .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.032 seconds) .. _sphx_glr_download_auto_examples_bayesian_swissmetro_plot_b10_nested_bottom.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_b10_nested_bottom.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_b10_nested_bottom.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_b10_nested_bottom.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_