Arc elasticities

We use a previously estimated nested logit model and calculate arc elasticities.

Details about this example are available in Section 3 of Bierlaire (2018) Calculating indicators with PandasBiogeme

author:

Michel Bierlaire, EPFL

date:

Wed Apr 12 21:00:10 2023

import sys

from IPython.core.display_functions import display

import biogeme.biogeme as bio
from biogeme.exceptions import BiogemeError
from biogeme import models
import biogeme.results as res
from biogeme.data.optima import read_data, normalized_weight
from scenarios import scenario

Obtain the specification for the default scenario The definition of the scenarios is available in Specification of a nested logit model.

V, nests, _, MarginalCostPT = scenario()

Obtain the expression for the choice probability of the public transportation.

prob_PT = models.nested(V, None, nests, 0)

We investigate a scenario where the price for public transportation increases by 20%. We extract the corresponding scenario.

V_after, _, _, MarginalCostPT_after = scenario(factor=1.2)
prob_PT_after = models.nested(V_after, None, nests, 0)

Disaggregate elasticities

direct_elas_pt = (
    (prob_PT_after - prob_PT)
    * MarginalCostPT
    / (prob_PT * (MarginalCostPT_after - MarginalCostPT))
)

Formulas to simulate.

simulate = {
    'weight': normalized_weight,
    'Prob. PT': prob_PT,
    'direct_elas_pt': direct_elas_pt,
}

Read the data

database = read_data()

Create the Biogeme object.

the_biogeme = bio.BIOGEME(database, simulate)

Read the estimation results from the file

try:
    results = res.bioResults(pickle_file='saved_results/b02estimation.pickle')
except BiogemeError:
    sys.exit(
        'Run first the script b02estimation.py in order to generate '
        'the file b02estimation.pickle.'
    )

simulated_values is a Panda dataframe with the same number of rows as the database, and as many columns as formulas to simulate.

simulated_values = the_biogeme.simulate(results.get_beta_values())
display(simulated_values)
        weight  Prob. PT  direct_elas_pt
0     0.886023  0.490700        0.000000
2     0.861136  0.228886       -0.276116
3     0.861136  0.102446       -1.618974
4     0.957386  0.039047       -1.261659
5     0.861136  0.252618       -0.588057
...        ...       ...             ...
2259  2.036009  0.289274       -0.571994
2261  0.861136  0.148251       -0.920795
2262  0.861136  0.187894       -0.536265
2263  0.957386  0.205622       -0.830743
2264  0.957386  0.198499       -0.888497

[1906 rows x 3 columns]

We calculate the aggregate elasticities.

First, the weighted probabilities.

simulated_values['Weighted prob. PT'] = (
    simulated_values['weight'] * simulated_values['Prob. PT']
)

Then the denominator of the aggregate elasticity expression.

denominator_pt = simulated_values['Weighted prob. PT'].sum()

And finally the aggregate elasticities themselves.

direct_elas_pt = (
    simulated_values['Weighted prob. PT']
    * simulated_values['direct_elas_pt']
    / denominator_pt
).sum()

print(
    f'Aggregate direct arc elasticity of public transportation wrt cost: '
    f'{direct_elas_pt:.3g}'
)
Aggregate direct arc elasticity of public transportation wrt cost: -0.34

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

Gallery generated by Sphinx-Gallery