109: Swissmetro Nested Logit Mode Choice

This example is a mode choice model built using the Swissmetro example dataset. First we create the DB and Model objects. When we create the DB object, we will redefine the weight value:

d = larch.DB.Example('SWISSMETRO')
m = larch.Model(d)

We can attach a title to the model. The title does not affect the calculations as all; it is merely used in various output report styles.

m.title = "swissmetro example 09 (nested logit)"

The swissmetro dataset, as with all Biogeme data, is only in co format.

from larch.roles import P,X
m.utility[1] = ( P.ASC_TRAIN
               + P.B_TIME * X.TRAIN_TT
               + P.B_COST * X("TRAIN_CO*(GA==0)") )
m.utility[2] = ( P.B_TIME * X.SM_TT
               + P.B_COST * X("SM_CO*(GA==0)") )
m.utility[3] = ( P.ASC_CAR
               + P.B_TIME * X.CAR_TT
               + P.B_COST * X("CAR_CO") )

To create a new nest, we can use the new_nest command, although we’ll need to know what the alternative codes are for the alternatives in our dataset. To find out, we can do:

>>> m.df.alternatives()
[(1, 'Train'), (2, 'SM'), (3, 'Car')]

For this example, we want to nest together the Train and Car modes into a “existing” modes nest. It looks like those are modes 1 and 3, so we can use the new_nest command like this:

m.new_nest("existing", parent=m.root_id, children=[1,3])

Larch will find all the parameters in the model, but we’d like to output them in a particular order, so we want to reorder the parameters. We can use the reorder method to fix this:

m.reorder_parameters("ASC", "B_", "existing",)

We can estimate the models and check the results match up with those given by Biogeme:

>>> result = m.maximize_loglike()
>>> print(result.message)
Optimization terminated successfully...

>>> print(m.report('txt', sigfigs=3))
=========================================================================================...
swissmetro example 09 (nested logit)
=========================================================================================...
Model Parameter Estimates
-----------------------------------------------------------------------------------------...
Parameter       InitValue       FinalValue      StdError        t-Stat          NullValue
ASC_TRAIN        0.0            -0.512           0.0452         -11.3            0.0
ASC_CAR          0.0            -0.167           0.0371         -4.5             0.0
B_TIME           0.0            -0.00899         0.00057        -15.8            0.0
B_COST           0.0            -0.00857         0.000463       -18.5            0.0
existing         1.0             0.487           0.0279         -18.4            1.0
=========================================================================================...
Model Estimation Statistics
-----------------------------------------------------------------------------------------...
Log Likelihood at Convergence           -5236.90
Log Likelihood at Null Parameters       -6964.66
-----------------------------------------------------------------------------------------...
Rho Squared w.r.t. Null Parameters      0.248
=========================================================================================...

Tip

If you want access to the model in this example without worrying about assembling all the code blocks together on your own, you can load a read-to-estimate copy like this:

m = larch.Model.Example(109)