Running calibration#

In the following we describe which demand model components can be calibrated and how to generate calibration targets from data. We also show how to run calibration and describe the corresponding parameters.

Individual model components#

The following demand model components can currently be calibrated with Polaris-Studio.

Activity generation rates#

This module updates the average daily frequency of activities by activity and person type.

Non-mandatory timing choice#

This module updates the time period specific constants for non-mandatory activities.

Destination choice#

Destination choice calibration works by adjusting a parameter that scales the effect of travel time on location choice. Reducing the parameter increases average trip distance for the activity by scaling down the disutility of travel time. Increasing the parameter increases travel time disutility which causes trips to be shorter. For work location choice, the module updates the parameter until the simulated straight-line distance to work matches the observed straight-line distance in the target file. For non-mandatory activities, the parameter is changed such that the simulated network trip distance matches the target network distance.

Mode choice#

Mode choice calibration consists of updating alternative-specific constants based on mode share by trip type (currently home-based work, home-based other, and non-home-based trips). For public transit mode choice, there is an optional step to adjust mode share by access mode based on boarding targets.

Calibration target generation from NHTS#

Polaris-Studio provides funtionality to generate calibration targets based on publicly available NHTS 2017 data. The basic steps are loading the data


import pandas as pd
from pathlib import Path

from polaris.runs.calibrate.target_generation import NHTS17Dataset, ActivityType

nhts = NHTS17Dataset.download() # or load from existing data with NHTS17Dataset.from_dir("my_nhts_path")

There are some differences in how POLARIS and NHTS 2017 define activity purposes, and NHTS2017 data does not contain activity generation rates for pre-school children. This makes it difficult to generate a complete set of targets using only NHTS 2017. However, one can use the following lines of code to generate a partial set of target values from the NHTS dataset.


NHTS17_ACT_MAPPING = {
    -7: ActivityType.IGNORE,           # I prefer not to answer
    -8: ActivityType.IGNORE,           # I don't know
    -9: ActivityType.IGNORE,           # Not ascertained
    1 : ActivityType.HOME,             # Regular home activities
    2 : ActivityType.WORK_AT_HOME,     # Work from home (paid)
    3 : ActivityType.WORK,             # Work
    4 : ActivityType.WORK,             # Work-related meeting / trip
    5 : ActivityType.WORK,             # Volunteer activities (not paid)
    6 : ActivityType.PICKUP_DROPOFF,   # Drop off /pick up someone
    7 : ActivityType.IGNORE,           # Change type of transportation
    8 : ActivityType.SCHOOL,           # Attend school as a student
    9 : ActivityType.SCHOOL,           # Attend child care
    10: ActivityType.SHOP_MAJOR,       # Attend adult care
    11: ActivityType.SHOP_MAJOR,       # Buy goods (groceries, clothes, appliances, gas)
    12: ActivityType.SHOP_MAJOR,       # Buy services (dry cleaners, banking, service a car, pet care)
    13: ActivityType.EAT_OUT,          # Buy meals (go out for a meal, snack, carry-out)
    14: ActivityType.SHOP_MAJOR,       # Other general errands (post office, library)
    15: ActivityType.LEISURE,          # Recreational activities (visit parks, movies, bars, museums)
    16: ActivityType.LEISURE,          # Exercise (go for a jog, walk, walk the dog, go to the gym)
    17: ActivityType.SOCIAL,           # Visit friends or relatives
    18: ActivityType.HEALTHCARE,       # Health care visit (medical, dental, therapy)
    19: ActivityType.RELIGIOUS_CIVIC,  # Religious or other community activities
    97: ActivityType.OTHER,            # Something else
}

actgen_df = nhts.generate_activity_generation_targets(NHTS17_ACT_MAPPING)
actgen_df.to_csv('activity_generation_targets.csv', index=False)

depart_df = nhts.generate_departure_time_targets(NHTS17_ACT_MAPPING)
depart_df.to_csv('timing_choice_targets.csv', index=False)

dest_df = nhts.generate_destination_choice_targets(NHTS17_ACT_MAPPING)
dest_df.to_csv('destination_choice_targets.csv', index=False)

mode_df = nhts.generate_mode_choice_targets()
mode_df.to_csv('mode_choice_targets.csv', index=False)

Missing or zero values in target files generated above will have to be filled with targets calculated from other data sources to generate a complete set of targets that can be used in POLARIS. A way of supplementing the target files is described in notebooks/create_targets_based_on_nhts2017.ipynb.

Running calibration#

Calibration in a model run is enabled by adding the following lines to convergence_control.yaml and running the model like in a convergence setting, see :ref:run.

calibration:
    enabled: true
    target_csv_dir: calibration_targets

The parameter configuration options are perhaps best explained with an example:

calibration:
    enabled: true
    target_csv_dir: calibration_targets
    num_planned_activity_iterations: 0
    calibration_schedule: 
        activity: 
            first_iteration: 1
            last_iteration: 120
            pattern: [0,0,0,0,0,0,1,0,0,0]
        destination: 
            first_iteration: 1
            last_iteration: 120
            pattern: [1,0,0,0,0,0,0,0,0,0]
        mode: 
            first_iteration: 1
            last_iteration: 120
            pattern: [0,0,0,0,1,0,0,0,0,0]
        timing: 
            first_iteration: 1
            last_iteration: 120
            pattern: [0,0,0,0,0,1,0,0,0,0]
    step_size: 2.0
workplace_stabilization:
    enabled: true
    schedule:
        first_iteration: 1
        last_iteration: 60
        pattern: [1,1,1,1,1,0,0,0,0,0]

Here, calibration_schedule defines when each component is run in the overall model run. The exact parameters are based on experience and can be adjusted, but there are some guiedelines to keep in mind: Each demand model change leads to a change in the network state, which needs to be reflected in the average level of service that is used in generating the demand. This is especially true for work location choice, which has a strong influence on overall network conditions. The above example therefore sets workplace stabilization to run for 5 iterations (workplace_stabilization: pattern: [1,1,1,1,1,0,0,0,0,0]) after updating the corresponding calibration parameter on the first iteration (calibration_schedule: destination: pattern: [1,0,0,0,0,0,0,0,0,0]). On the 5th iteration, mode choice parameters are also adjusted (calibration_schedule: mode: pattern: [0,0,0,0,1,0,0,0,0,0]), while the timing choice and activity frequency adjustments are performed on iteration 6 and 7 respectively. The system is then left to stabilize for a further 3 iterations, before the pattern starts again at iteration 11. Workplace stabilization is turned off after 60 iterations, while all other components are left to adjust until 120 iterations are reached.