Nested logit choice#
simple_choice runs a multinomial logit model by default. Give it an
ActivitySim-style nest_spec to run a nested logit model instead. The same
methods remain available in both cases: utility, probability, logsum,
simulate_choice, analytic_share, and the analytic-share calibration methods.
from traveler.steps import simple_choice
tour_mode = simple_choice(
"tour_mode",
tour_mode_utilities,
altnames=("SOV", "HOV", "Walk", "Bike"),
param={"auto_nest": 0.7},
on=Tours,
result_name="tour_mode",
nest_spec={
"name": "root",
"coefficient": 1.0,
"alternatives": [
{
"name": "auto",
"coefficient": "auto_nest",
"alternatives": ["SOV", "HOV"],
},
{
"name": "nonmotorized",
"coefficient": 0.8,
"alternatives": ["Walk", "Bike"],
},
],
},
)
Each nest has a unique name, a coefficient, and a non-empty list of
alternatives. An alternative may be another nest or one of the values in
altnames. Every elemental alternative must appear exactly once. The root
coefficient is 1; lower-level coefficients must be greater than zero and no
larger than one.
Nested logit currently requires explicit string or integer altnames; the
categorical-group shorthand (such as "@TAZ") is available only for MNL.
A coefficient may be a number or the name of an entry in param. Named nest
coefficients participate in JAX automatic differentiation, so they can be used
with analytic-share calibration. Coefficients use ActivitySim’s relative
convention: an elemental utility is divided by the product of coefficients on
its path from the root.