Note
Go to the end to download the full example code.
Cross point elasticities¶
We use a previously estimated nested logit model and calculate disaggregate and aggregate cross point elasticities.
Details about this example are available in Section 3 of Bierlaire (2018) Calculating indicators with PandasBiogeme
Michel Bierlaire, EPFL Sat Jun 28 2025, 20:58:34
import sys
from IPython.core.display_functions import display
from biogeme.biogeme import BIOGEME
from biogeme.data.optima import normalized_weight, read_data
from biogeme.expressions import Derive
from biogeme.models import nested
from biogeme.results_processing import EstimationResults
from scenarios import CostCarCHF, MarginalCostPT, TimeCar, TimePT, scenario
Obtain the specification for the default scenario The definition of the scenarios is available in Specification of a nested logit model.
v, nests, _, _ = scenario()
Obtain the expression for the choice probability of each alternative.
prob_pt = nested(v, None, nests, 0)
prob_car = nested(v, None, nests, 1)
prob_sm = nested(v, None, nests, 2)
Calculation of the cross elasticities. We use the ‘Derive’ operator to calculate the derivatives.
cross_elas_pt_time = Derive(prob_pt, 'TimeCar') * TimeCar / prob_pt
cross_elas_pt_cost = Derive(prob_pt, 'CostCarCHF') * CostCarCHF / prob_pt
cross_elas_car_time = Derive(prob_car, 'TimePT') * TimePT / prob_car
cross_elas_car_cost = Derive(prob_car, 'MarginalCostPT') * MarginalCostPT / prob_car
Formulas to simulate.
simulate = {
'weight': normalized_weight,
'Prob. car': prob_car,
'Prob. public transportation': prob_pt,
'Prob. slow modes': prob_sm,
'cross_elas_pt_time': cross_elas_pt_time,
'cross_elas_pt_cost': cross_elas_pt_cost,
'cross_elas_car_time': cross_elas_car_time,
'cross_elas_car_cost': cross_elas_car_cost,
}
Read the data
database = read_data()
Create the Biogeme object.
the_biogeme = BIOGEME(database, simulate)
Read the estimation results from the file
try:
results = EstimationResults.from_yaml_file(
filename='saved_results/b02estimation.yaml'
)
except FileNotFoundError:
sys.exit(
'Run first the script b02estimation.py in order to generate '
'the file b02estimation.yaml.'
)
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. car ... cross_elas_car_time cross_elas_car_cost
0 0.893779 0.519165 ... 0.112659 0.000000
1 0.868674 0.560868 ... 0.054643 0.051997
2 0.868674 0.875040 ... 0.035465 0.206901
3 0.965766 0.813507 ... 0.077714 0.039783
4 0.868674 0.729616 ... 0.083253 0.179205
... ... ... ... ... ...
1894 2.053830 0.711097 ... 0.118187 0.216012
1895 0.868674 0.849018 ... 0.166123 0.154992
1896 0.868674 0.688197 ... 0.116736 0.088844
1897 0.965766 0.742202 ... 0.072428 0.181998
1898 0.965766 0.763156 ... 0.081890 0.191696
[1899 rows x 8 columns]
We calculate the aggregate elasticities.
First, the weighted probabilities.
simulated_values['Weighted prob. car'] = (
simulated_values['weight'] * simulated_values['Prob. car']
)
simulated_values['Weighted prob. PT'] = (
simulated_values['weight'] * simulated_values['Prob. public transportation']
)
Then the denominators of the aggregate elasticity expressions.
denominator_car = simulated_values['Weighted prob. car'].sum()
denominator_pt = simulated_values['Weighted prob. PT'].sum()
And finally the aggregate elasticities themselves.
Elasticity of car with respect to public transportation travel time.
cross_elas_term_car_time = (
simulated_values['Weighted prob. car']
* simulated_values['cross_elas_car_time']
/ denominator_car
).sum()
print(
f'Aggregate cross elasticity of car wrt PT time: ' f'{cross_elas_term_car_time:.3g}'
)
Aggregate cross elasticity of car wrt PT time: 0.105
Elasticity of car with respect to public transportation travel cost.
cross_elas_term_car_cost = (
simulated_values['Weighted prob. car']
* simulated_values['cross_elas_car_cost']
/ denominator_car
).sum()
print(
f'Aggregate cross elasticity of car wrt PT cost: ' f'{cross_elas_term_car_cost:.3g}'
)
Aggregate cross elasticity of car wrt PT cost: 0.125
Elasticity of public transportatiom with respect to car travel time.
cross_elas_term_pt_time = (
simulated_values['Weighted prob. PT']
* simulated_values['cross_elas_pt_time']
/ denominator_pt
).sum()
print(
f'Aggregate cross elasticity of PT wrt car time: ' f'{cross_elas_term_pt_time:.3g}'
)
Aggregate cross elasticity of PT wrt car time: 0.0941
Elasticity of public transportatiom with respect to car travel cost.
cross_elas_term_pt_cost = (
simulated_values['Weighted prob. PT']
* simulated_values['cross_elas_pt_cost']
/ denominator_pt
).sum()
print(
f'Aggregate cross direct elasticity of PT wrt car cost: '
f'{cross_elas_term_pt_cost:.3g}'
)
Aggregate cross direct elasticity of PT wrt car cost: 0.201
Total running time of the script: (0 minutes 3.507 seconds)