Direct point elasticities

We use a previously estimated nested logit model and calculate

disaggregate and aggregate direct point 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:01:41 2023

import sys
import biogeme.biogeme as bio
from biogeme import models
import biogeme.results as res
import biogeme.exceptions as excep
from biogeme.expressions import Derive
from optima_data import database, normalized_weight

from scenarios import (
    scenario,
    TimePT,
    TimeCar,
    MarginalCostPT,
    CostCarCHF,
    distance_km,
)

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 = models.nested(V, None, nests, 0)
prob_CAR = models.nested(V, None, nests, 1)
prob_SM = models.nested(V, None, nests, 2)

Calculation of the direct elasticities. We use the ‘Derive’ operator to calculate the derivatives.

direct_elas_pt_time = Derive(prob_PT, 'TimePT') * TimePT / prob_PT

direct_elas_pt_cost = Derive(prob_PT, 'MarginalCostPT') * MarginalCostPT / prob_PT

direct_elas_car_time = Derive(prob_CAR, 'TimeCar') * TimeCar / prob_CAR

direct_elas_car_cost = Derive(prob_CAR, 'CostCarCHF') * CostCarCHF / prob_CAR

direct_elas_sm_dist = Derive(prob_SM, 'distance_km') * distance_km / prob_SM

Formulas to simulate.

simulate = {
    'weight': normalized_weight,
    'Prob. car': prob_CAR,
    'Prob. public transportation': prob_PT,
    'Prob. slow modes': prob_SM,
    'direct_elas_pt_time': direct_elas_pt_time,
    'direct_elas_pt_cost': direct_elas_pt_cost,
    'direct_elas_car_time': direct_elas_car_time,
    'direct_elas_car_cost': direct_elas_car_cost,
    'direct_elas_sm_dist': direct_elas_sm_dist,
}

Create the Biogeme object.

the_biogeme = bio.BIOGEME(database, simulate)

Read the estimation results from the file

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

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

simulated_values = the_biogeme.simulate(results.getBetaValues())
simulated_values
weight Prob. car Prob. public transportation Prob. slow modes direct_elas_pt_time direct_elas_pt_cost direct_elas_car_time direct_elas_car_cost direct_elas_sm_dist
0 0.886023 0.521791 0.476807 0.001402 -0.128761 0.000000 -0.044176 -0.155490 -6.282280
2 0.861136 0.563268 0.238681 0.198051 -0.236955 -0.215072 -0.007565 -0.020018 -0.690123
3 0.861136 0.875824 0.119136 0.005040 -0.278714 -1.550950 -0.008245 -0.030060 -6.242559
4 0.957386 0.814110 0.051136 0.134754 -2.020961 -1.030288 -0.020782 -0.022100 -1.734068
5 0.861136 0.732059 0.257192 0.010749 -0.255844 -0.525291 -0.015470 -0.052004 -4.727090
... ... ... ... ... ... ... ... ... ...
2259 2.036009 0.714085 0.285872 0.000043 -0.305144 -0.531971 -0.033015 -0.115081 -10.671587
2261 0.861136 0.849040 0.149688 0.001272 -0.948767 -0.881532 -0.051836 -0.049301 -8.100940
2262 0.861136 0.689083 0.205901 0.105016 -0.551441 -0.417948 -0.029794 -0.030061 -1.862736
2263 0.957386 0.744274 0.219850 0.035876 -0.291011 -0.697499 -0.017718 -0.046520 -3.407459
2264 0.957386 0.765468 0.209149 0.025383 -0.342744 -0.765284 -0.018957 -0.053750 -3.969568

1906 rows × 9 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']
)
simulated_values['Weighted prob. SM'] = (
    simulated_values['weight'] * simulated_values['Prob. slow modes']
)

Then the denominators of the aggregate elasticity expressions.

denominator_car = simulated_values['Weighted prob. car'].sum()
denominator_pt = simulated_values['Weighted prob. PT'].sum()
denominator_sm = simulated_values['Weighted prob. SM'].sum()

And finally the aggregate elasticities themselves.

Elasticity of car with respect to time.

direct_elas_term_car_time = (
    simulated_values['Weighted prob. car']
    * simulated_values['direct_elas_car_time']
    / denominator_car
).sum()

print(
    f'Aggregate direct point elasticity of car wrt time: '
    f'{direct_elas_term_car_time:.3g}'
)
Aggregate direct point elasticity of car wrt time: -0.0441

Elasticity of car with respect to cost.

direct_elas_term_car_cost = (
    simulated_values['Weighted prob. car']
    * simulated_values['direct_elas_car_cost']
    / denominator_car
).sum()
print(
    f'Aggregate direct point elasticity of car wrt cost: '
    f'{direct_elas_term_car_cost:.3g}'
)
Aggregate direct point elasticity of car wrt cost: -0.0906

Elasticity of public transportation with respect to time.

direct_elas_term_pt_time = (
    simulated_values['Weighted prob. PT']
    * simulated_values['direct_elas_pt_time']
    / denominator_pt
).sum()
print(
    f'Aggregate direct point elasticity of PT wrt time: '
    f'{direct_elas_term_pt_time:.3g}'
)
Aggregate direct point elasticity of PT wrt time: -0.274

Elasticity of public transportation with respect to cost.

direct_elas_term_pt_cost = (
    simulated_values['Weighted prob. PT']
    * simulated_values['direct_elas_pt_cost']
    / denominator_pt
).sum()
print(
    f'Aggregate direct point elasticity of PT wrt cost: '
    f'{direct_elas_term_pt_cost:.3g}'
)
Aggregate direct point elasticity of PT wrt cost: -0.32

Elasticity of slow modes with respect to distance.

direct_elas_term_sm_dist = (
    simulated_values['Weighted prob. SM']
    * simulated_values['direct_elas_sm_dist']
    / denominator_sm
).sum()
print(
    f'Aggregate direct point elasticity of SM wrt distance: '
    f'{direct_elas_term_sm_dist:.3g}'
)
Aggregate direct point elasticity of SM wrt distance: -1.09

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

Gallery generated by Sphinx-Gallery