.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/swissmetro/plot_b01b_logit.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_swissmetro_plot_b01b_logit.py: 1b. Illustration of additional Biogeme features =============================================== This example estimates the same logit model as in Example 1a, but illustrates several additional features available in Biogeme. In particular, it demonstrates: - the use of `LinearUtility` to define utility functions, - automatic parameter segmentation, - the generation of alternative variance-covariance matrices, - the production of several output formats. The model considers three transportation alternatives: - Train, - Swissmetro, - Car. The utility functions include alternative-specific constants and generic coefficients associated with travel time and travel cost. The Swissmetro alternative is used as the reference alternative. The `# %%` markers are used to separate the script into notebook cells when the example gallery is converted into Jupyter notebooks. Tested with Biogeme 3.3.3. Michel Bierlaire, EPFL Tue Jun 09 2026, 14:40:00 .. GENERATED FROM PYTHON SOURCE LINES 35-40 .. code-block:: Python import os from IPython.core.display_functions import display .. GENERATED FROM PYTHON SOURCE LINES 41-42 Import the variables and the database prepared in the Swissmetro data-processing example. .. GENERATED FROM PYTHON SOURCE LINES 42-74 .. code-block:: Python from swissmetro_data import ( CAR_AV_SP, CAR_CO_SCALED, CAR_TT_SCALED, CHOICE, GA, MALE, 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.biogeme import BIOGEME from biogeme.exceptions import BiogemeError from biogeme.expressions import Beta, LinearTermTuple, LinearUtility from biogeme.models import loglogit from biogeme.results_processing import ( EstimateVarianceCovariance, EstimationResults, generate_html_file, get_pandas_estimated_parameters, ) from biogeme.segmentation import Segmentation logger = blog.get_screen_logger(level=blog.INFO) logger.info('Example b01logit_bis.py') .. rst-class:: sphx-glr-script-out .. code-block:: none Example b01logit_bis.py .. GENERATED FROM PYTHON SOURCE LINES 75-76 Define the model parameters to be estimated. .. GENERATED FROM PYTHON SOURCE LINES 76-79 .. code-block:: Python asc_car = Beta('asc_car', 0, None, None, 0) asc_train = Beta('asc_train', 0, None, None, 0) .. GENERATED FROM PYTHON SOURCE LINES 80-81 Starting values obtained from a previous estimation run. .. GENERATED FROM PYTHON SOURCE LINES 81-84 .. code-block:: Python b_time = Beta('b_time', -1.28, None, None, 0) b_cost = Beta('b_cost', -1.08, None, None, 0) .. GENERATED FROM PYTHON SOURCE LINES 85-86 Define the segmentation schemes used for the alternative-specific constants. .. GENERATED FROM PYTHON SOURCE LINES 86-99 .. code-block:: Python gender_segmentation = database.generate_segmentation( variable=MALE, mapping={0: 'female', 1: 'male'} ) ga_segmentation = database.generate_segmentation( variable=GA, mapping={0: 'without_ga', 1: 'with_ga'} ) segmentations_for_asc = [ gender_segmentation, ga_segmentation, ] .. GENERATED FROM PYTHON SOURCE LINES 100-101 Apply the segmentations to the alternative-specific constants. .. GENERATED FROM PYTHON SOURCE LINES 101-128 .. code-block:: Python asc_train_segmentation = Segmentation(asc_train, segmentations_for_asc) segmented_asc_train = asc_train_segmentation.segmented_beta() asc_car_segmentation = Segmentation(asc_car, segmentations_for_asc) segmented_asc_car = asc_car_segmentation.segmented_beta() # # Define the utility functions. A `LinearTermTuple` combines a coefficient # and an explanatory variable. A `LinearUtility` is the sum of the # products of each coefficient by its associated variable. terms1 = [ LinearTermTuple(beta=b_time, x=TRAIN_TT_SCALED), LinearTermTuple(beta=b_cost, x=TRAIN_COST_SCALED), ] v_train = segmented_asc_train + LinearUtility(terms1) terms2 = [ LinearTermTuple(beta=b_time, x=SM_TT_SCALED), LinearTermTuple(beta=b_cost, x=SM_COST_SCALED), ] v_swissmetro = LinearUtility(terms2) terms3 = [ LinearTermTuple(beta=b_time, x=CAR_TT_SCALED), LinearTermTuple(beta=b_cost, x=CAR_CO_SCALED), ] v_car = segmented_asc_car + LinearUtility(terms3) .. GENERATED FROM PYTHON SOURCE LINES 129-130 Associate each utility function with the corresponding alternative identifier. .. GENERATED FROM PYTHON SOURCE LINES 130-132 .. code-block:: Python v = {1: v_train, 2: v_swissmetro, 3: v_car} .. GENERATED FROM PYTHON SOURCE LINES 133-134 Associate the availability conditions with each alternative. .. GENERATED FROM PYTHON SOURCE LINES 134-136 .. code-block:: Python av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} .. GENERATED FROM PYTHON SOURCE LINES 137-138 Define the log-likelihood contribution of each observation. .. GENERATED FROM PYTHON SOURCE LINES 138-140 .. code-block:: Python logprob = loglogit(v, av, CHOICE) .. GENERATED FROM PYTHON SOURCE LINES 141-142 User notes that will be included in the generated report. .. GENERATED FROM PYTHON SOURCE LINES 142-150 .. code-block:: Python USER_NOTES = ( 'Example of a logit model with three alternatives: Train, Car and' ' Swissmetro. Same as 01logit and ' 'introducing some options and features. In particular, LinearUtility,' ' and automatic segmentation of parameters.' ) .. GENERATED FROM PYTHON SOURCE LINES 151-154 Create the Biogeme object. Second derivatives are disabled. Therefore, statistics requiring the Hessian matrix will not be available and alternative procedures such as bootstrap or BHHH must be used. .. GENERATED FROM PYTHON SOURCE LINES 154-163 .. code-block:: Python the_biogeme = BIOGEME( database, logprob, user_notes=USER_NOTES, save_iterations=False, bootstrap_samples=100, calculating_second_derivatives='never', ) .. rst-class:: sphx-glr-script-out .. code-block:: none Biogeme parameters read from biogeme.toml. .. GENERATED FROM PYTHON SOURCE LINES 164-168 Calculate the null log likelihood for reporting. As we have used starting values different from 0, the initial model is not the equal probability model. .. GENERATED FROM PYTHON SOURCE LINES 168-171 .. code-block:: Python the_biogeme.calculate_null_loglikelihood(av) the_biogeme.model_name = 'b01b_logit' .. GENERATED FROM PYTHON SOURCE LINES 172-173 Estimate the parameters or retrieve previously saved results. .. GENERATED FROM PYTHON SOURCE LINES 173-180 .. code-block:: Python try: results = EstimationResults.from_yaml_file( filename=f'saved_results/{the_biogeme.model_name}.yaml' ) except FileNotFoundError: results = the_biogeme.estimate(run_bootstrap=True) .. GENERATED FROM PYTHON SOURCE LINES 181-182 Convert the estimated parameters into a pandas DataFrame. .. GENERATED FROM PYTHON SOURCE LINES 182-187 .. code-block:: Python print('Parameters') print('----------') pandas_results = get_pandas_estimated_parameters(estimation_results=results) display(pandas_results) .. rst-class:: sphx-glr-script-out .. code-block:: none Parameters ---------- {'Estimated parameters': Name Value ... Bootstrap t-stat. Bootstrap p-value 0 asc_train_ref -0.534241 ... -5.061991 4.149012e-07 1 asc_train_diff_male -1.103475 ... -11.847943 0.000000e+00 2 asc_train_diff_with_ga 1.889291 ... 19.572221 0.000000e+00 3 b_time -1.172988 ... -11.215484 0.000000e+00 4 b_cost -1.089775 ... -14.655465 0.000000e+00 5 asc_car_ref -0.612850 ... -6.872113 6.325829e-12 6 asc_car_diff_male 0.408056 ... 4.274671 1.914201e-05 7 asc_car_diff_with_ga -0.414883 ... -2.058358 3.955579e-02 [8 rows x 5 columns]} .. GENERATED FROM PYTHON SOURCE LINES 188-189 Display general estimation statistics. .. GENERATED FROM PYTHON SOURCE LINES 189-195 .. code-block:: Python print('General statistics') print('------------------') stats = results.get_general_statistics() for description, value in stats.items(): print(f'{description}: {value}') .. rst-class:: sphx-glr-script-out .. code-block:: none General statistics ------------------ Number of estimated parameters: 8 Sample size: 6768 Excluded observations: 3960 Null log likelihood: -6964.663 Init log likelihood: -5533.155 Final log likelihood: -4943.895 Likelihood ratio test for the null model: 4041.535 Rho-square for the null model: 0.29 Rho-square-bar for the null model: 0.289 Likelihood ratio test for the init. model: 1178.519 Rho-square for the init. model: 0.106 Rho-square-bar for the init. model: 0.105 Akaike Information Criterion: 9903.791 Bayesian Information Criterion: 9958.351 Final gradient norm: 3.7418E-02 Bootstrapping time: 0:00:47.395244 .. GENERATED FROM PYTHON SOURCE LINES 196-197 Display messages returned by the optimization algorithm. .. GENERATED FROM PYTHON SOURCE LINES 197-202 .. code-block:: Python print('Optimization algorithm') print('----------------------') for description, message in results.optimization_messages.items(): print(f'{description}:\t{message}') .. rst-class:: sphx-glr-script-out .. code-block:: none Optimization algorithm ---------------------- Algorithm: BFGS with trust region for simple bound constraints Cause of termination: Relative gradient = 3.8e-06 <= 6.1e-06 Number of function evaluations: 119 Number of gradient evaluations: 71 Number of hessian evaluations: 0 Number of iterations: 48 Optimization time: 0:00:00.492641 Proportion of Hessian calculation: 0/35 = 0.0% Relative gradient: 3.81749756689241e-06 .. GENERATED FROM PYTHON SOURCE LINES 203-206 Attempt to generate an HTML report based on the robust variance-covariance matrix. This fails because second derivatives have not been calculated. .. GENERATED FROM PYTHON SOURCE LINES 206-222 .. code-block:: Python try: robust_html_filename = f'{the_biogeme.model_name}_robust.html' # The following function assumes that the file does not exist. if os.path.exists(robust_html_filename): os.remove(robust_html_filename) generate_html_file( filename=robust_html_filename, estimation_results=results, variance_covariance_type=EstimateVarianceCovariance.ROBUST, ) print( f'Estimation results with robust statistics generated: {robust_html_filename}' ) except BiogemeError as e: print(f'BiogemeError: {e}') .. rst-class:: sphx-glr-script-out .. code-block:: none BiogemeError: Second derivatives matrix not available. .. GENERATED FROM PYTHON SOURCE LINES 223-224 Generate an HTML report using the BHHH variance-covariance matrix. .. GENERATED FROM PYTHON SOURCE LINES 224-235 .. code-block:: Python bhhh_html_filename = f'{the_biogeme.model_name}_bhhh.html' # The following function assumes that the file does not exist. Therefore, if it does exist, we erase it. if os.path.exists(bhhh_html_filename): os.remove(bhhh_html_filename) generate_html_file( filename=bhhh_html_filename, estimation_results=results, variance_covariance_type=EstimateVarianceCovariance.BHHH, ) print(f'Estimation results with BHHH statistics generated: {bhhh_html_filename}') .. rst-class:: sphx-glr-script-out .. code-block:: none File b01b_logit_bhhh.html has been generated. Estimation results with BHHH statistics generated: b01b_logit_bhhh.html .. GENERATED FROM PYTHON SOURCE LINES 236-237 Generate the results file in ALogit format. .. GENERATED FROM PYTHON SOURCE LINES 237-240 .. code-block:: Python f12_filename = results.write_f12() print(f'Estimation results in ALogit format generated: {f12_filename}') .. rst-class:: sphx-glr-script-out .. code-block:: none File b01b_logit.F12 has been generated. Estimation results in ALogit format generated: b01b_logit.F12 .. GENERATED FROM PYTHON SOURCE LINES 241-242 Generate LaTeX output containing the estimation results. .. GENERATED FROM PYTHON SOURCE LINES 242-244 .. code-block:: Python latex_filename = results.write_latex(include_begin_document=True) print(f'Estimation results in LaTeX format generated: {latex_filename}') .. rst-class:: sphx-glr-script-out .. code-block:: none File b01b_logit.tex has been generated. Estimation results in LaTeX format generated: b01b_logit.tex .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.084 seconds) .. _sphx_glr_download_auto_examples_swissmetro_plot_b01b_logit.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_b01b_logit.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_b01b_logit.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_b01b_logit.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_