.. 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 features of Biogeme ================================================== Same model as b01logit, using LinearUtility, segmentations Michel Bierlaire, EPFL Wed Jun 18 2025, 10:57:53 .. GENERATED FROM PYTHON SOURCE LINES 12-30 .. code-block:: Python import os from IPython.core.display_functions import display 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 .. GENERATED FROM PYTHON SOURCE LINES 31-32 See the data processing script: :ref:`swissmetro_data`. .. GENERATED FROM PYTHON SOURCE LINES 32-51 .. 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, ) 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 52-53 Parameters to be estimated. .. GENERATED FROM PYTHON SOURCE LINES 53-56 .. 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 57-59 Starting value. We use starting values estimated from a previous run .. GENERATED FROM PYTHON SOURCE LINES 59-62 .. 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 63-64 Define segmentations. .. GENERATED FROM PYTHON SOURCE LINES 64-77 .. 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 78-79 Segmentation of the constants. .. GENERATED FROM PYTHON SOURCE LINES 79-84 .. 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() .. GENERATED FROM PYTHON SOURCE LINES 85-88 Definition of the utility functions.A `LinearTermTuple` combines a coefficient (`beta`) and a variable (`x`). The linear utility function is the sum over those tuples of the product of each variable by its respective coefficient. .. GENERATED FROM PYTHON SOURCE LINES 88-106 .. code-block:: Python 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 107-108 Associate utility functions with the numbering of alternatives. .. GENERATED FROM PYTHON SOURCE LINES 108-110 .. code-block:: Python v = {1: v_train, 2: v_swissmetro, 3: v_car} .. GENERATED FROM PYTHON SOURCE LINES 111-112 Associate the availability conditions with the alternatives. .. GENERATED FROM PYTHON SOURCE LINES 112-114 .. code-block:: Python av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} .. GENERATED FROM PYTHON SOURCE LINES 115-119 Definition of the model. This is the contribution of each observation to the log likelihood function. .. GENERATED FROM PYTHON SOURCE LINES 119-121 .. code-block:: Python logprob = loglogit(v, av, CHOICE) .. GENERATED FROM PYTHON SOURCE LINES 122-125 User notes. These notes will be included as such in the report file. .. GENERATED FROM PYTHON SOURCE LINES 125-133 .. 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 134-138 Create the Biogeme object. We include users notes, and we ask not to calculate the second derivatives. The parameter 'calculating_second_derivatives' is a general instruction for Biogeme, In this case, the second derivatives will not even be calculated after the algorithm has converged. It means that the statistics will have to rely on bootstrap or BHHH. .. GENERATED FROM PYTHON SOURCE LINES 138-147 .. 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 148-152 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 152-155 .. code-block:: Python the_biogeme.calculate_null_loglikelihood(av) the_biogeme.model_name = 'b01b_logit' .. GENERATED FROM PYTHON SOURCE LINES 156-157 Estimate the parameters. .. GENERATED FROM PYTHON SOURCE LINES 157-164 .. 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 165-167 Get the results in a pandas table. .. GENERATED FROM PYTHON SOURCE LINES 167-172 .. 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 ---------- Name Value ... Bootstrap t-stat. Bootstrap p-value 0 asc_train_ref -0.534241 ... -5.408762 6.346178e-08 1 asc_train_diff_male -1.103475 ... -12.735402 0.000000e+00 2 asc_train_diff_with_ga 1.889291 ... 19.546871 0.000000e+00 3 b_time -1.172988 ... -10.952513 0.000000e+00 4 b_cost -1.089775 ... -15.198306 0.000000e+00 5 asc_car_ref -0.612850 ... -6.590000 4.398260e-11 6 asc_car_diff_male 0.408056 ... 4.311043 1.624860e-05 7 asc_car_diff_with_ga -0.414881 ... -1.979356 4.777590e-02 [8 rows x 5 columns] .. GENERATED FROM PYTHON SOURCE LINES 173-175 Get general statistics. .. GENERATED FROM PYTHON SOURCE LINES 175-181 .. 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.7451E-02 Bootstrapping time: 0:00:35.138482 .. GENERATED FROM PYTHON SOURCE LINES 182-184 Messages from the optimization algorithm. .. GENERATED FROM PYTHON SOURCE LINES 184-189 .. 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.265091 Proportion of Hessian calculation: 0/35 = 0.0% Relative gradient: 3.827951698290516e-06 .. GENERATED FROM PYTHON SOURCE LINES 190-192 Try to generate the html output with the robust variance-covariance matrix. It does not work as the second derivatives matrix is not calculated. .. GENERATED FROM PYTHON SOURCE LINES 192-208 .. 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 209-210 Generate the html output with the BHHH variance-covariance matrix .. GENERATED FROM PYTHON SOURCE LINES 210-221 .. 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 222-224 Generate the file in Alogit format. .. GENERATED FROM PYTHON SOURCE LINES 224-227 .. 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 228-230 Generate LaTeX code with the results. .. GENERATED FROM PYTHON SOURCE LINES 230-232 .. 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.065 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 `_