Page 1 of 2
Nested Logit - fixed lambda (NNNL vs. UMNL)
Posted: 21 Dec 2021, 18:41
by bartosz
I am working on a tour-based model for transport mode choice, and want to use Nested Logit to replicate the relationship between tour complexity and mode choice, as shown below:

- NL structure.png (5.04 KiB) Viewed 22699 times
Given that I have two nests, there are two nesting parameters *lambda* to be estimated - lambda_simple and lambda_complex.
However, I am a bit confused about how to specify them in the model. Hensher & Reyes (2000), for an identical case, fixed one of the inclusive value parameters to 1.0, which is not really clear for me why. May it have to do with the software they used and the two alternative implementations of Nested Logit that exist in many packages:
- non-normalized nested logit (NNNL) by Daly (1987; 2001)
- and utility maximizing nested logit (UMNL) advocated by Koppelman & Wen (1998) ??
Is it the normalization "trick" that they used possibly due to the software they used or what could be the reason for that?
From section 5.1.1 of Apollo manual and from the examples, I would conclude that Apollo employs the UMNL form, which does not need any further normalizations, but I am still a bit confused.
Thus, I would have following questions:
- which NL form is implemented in Apollo: NNNL or UMNL?
- is a normalization of one of the lambdas needed in NL in Apollo?
- even if it is not needed, what would it change in the estimation and interpretation of the other lambdas and the coefficients, should I fix one of the lambdas to = 1.0?
I would appreciate if you could clarify it a little. Thank you for your time!
Bartosz
Re: Nested Logit - fixed lambda (NNNL vs. UMNL)
Posted: 03 Jan 2022, 15:55
by stephanehess
Bartosz
Apollo uses the normalised NL model, but that's not the point in this context (as even in the ALogit version you do not need to fix one lambda to 1).
The role of the lambda parameter is to explain differences in the error variances for choices between alternatives within a nest in contrast with choices between alternatives in different nests. You could thus estimate lambdas both for simple and complex, given that you still have the root lambda fixed to 1.
Fixing the lambda in one nest to 1 is the approach that people used to use when combining data from different sources to understand differences in error variance (e.g. RP vs SP), but with software that allows for non-linear utilities like Apollo, you can just do this within MNL.
Now what's not clear to me is whether your alternatives in different nests are available at the same time. If not, then you would not be able to estimate all the lambdas as you would not have any choices between alternatives in different nests
Stephane
Re: Nested Logit - fixed lambda (NNNL vs. UMNL)
Posted: 05 Jan 2022, 11:21
by bartosz
Stephane, thank you for clarifying the issue of normalizing the lambdas and NL versions.
The reason I was concerned about this fixing of one of the lambdas to 1 was because:
- without fixing, I obtain absolutely crazy results:
Code: Select all
Model name : TNL_1.1_summer
Model description : Tour-based NL model with TT + COST generic. Nesting: simple vs. complex
Model run at : 2022-01-05 12:09:24
Estimation method : bfgs
Model diagnosis : successful convergence
Number of individuals : 289
Number of rows in database : 511
Number of modelled outcomes : 511
Number of cores used : 1
Model without mixing
LL(start) : -679.7981
LL(0) : -679.7981
LL(C) : -508.264
LL(final) : -416.8293
Rho-square (0) : 0.3868
Adj.Rho-square (0) : 0.3707
Rho-square (C) : 0.1799
Adj.Rho-square (C) : 0.1583
AIC : 855.66
BIC : 902.26
Estimated parameters : 11
Time taken (hh:mm:ss) : 00:00:11.92
pre-estimation : 00:00:0.22
estimation : 00:00:10.18
post-estimation : 00:00:1.52
Iterations : 157
Unconstrained optimisation.
Estimates:
Estimate s.e. t.rat.(0) p(1-sided) t.rat(1) p(1-sided) Rob.s.e. Rob.t.rat.(0) p(1-sided) Rob.t.rat.(1) p(1-sided)
asc_car_simple 0.00000 NA NA NA NA NA NA NA NA NA NA
asc_car_complex -0.52828 NA NA NA NA NA NA NA NA NA NA
asc_walk_simple 763.28248 NA NA NA NA NA NA NA NA NA NA
asc_walk_complex 760.48058 NA NA NA NA NA NA NA NA NA NA
asc_transit_simple -50.67288 NA NA NA NA NA NA NA NA NA NA
asc_transit_complex -64.44870 NA NA NA NA NA NA NA NA NA NA
b_tt_car 0.01214 NA NA NA NA NA NA NA NA NA NA
b_tt_walk -11.44721 NA NA NA NA NA NA NA NA NA NA
b_tt_transit -2.87021 NA NA NA NA NA NA NA NA NA NA
b_cost 20.00123 NA NA NA NA NA NA NA NA NA NA
lambda_simple 208.10415 NA NA NA NA NA NA NA NA NA NA
lambda_complex 210.33763 NA NA NA NA NA NA NA NA NA NA
Nesting structure for NL model component :
Nest: root (1)
|-Nest: simple (208.1042)
| |-Alternative: car_simple
| |-Alternative: walk_simple
| '-Alternative: transit_simple
'-Nest: complex (210.3376)
|-Alternative: car_complex
|-Alternative: walk_complex
'-Alternative: transit_complex
WARNING: The nesting parameter for nest "simple" should be between 0 and 1 (the nesting parameter for nest "root"), yet its value is 208.1042.
WARNING: The nesting parameter for nest "complex" should be between 0 and 1 (the nesting parameter for nest "root"), yet its value is 210.3376.
- with lambda_simple = 1, the results look much more reasonable (except the positive cost coefficient), but the interpretation the lambda_simple fixed to 1.0 and the estimated lambda_complex remains a mystery to me:
Code: Select all
Model name : TNL_1.1_summer
Model description : Tour-based NL model with TT + COST generic. Nesting: simple vs. complex
Model run at : 2022-01-05 12:14:20
Estimation method : bfgs
Model diagnosis : successful convergence
Number of individuals : 289
Number of rows in database : 511
Number of modelled outcomes : 511
Number of cores used : 1
Model without mixing
LL(start) : -633.4515
LL(0) : -679.7981
LL(C) : -508.264
LL(final) : -428.6949
Rho-square (0) : 0.3694
Adj.Rho-square (0) : 0.3547
Rho-square (C) : 0.1566
Adj.Rho-square (C) : 0.1369
AIC : 877.39
BIC : 919.75
Estimated parameters : 10
Time taken (hh:mm:ss) : 00:00:3.89
pre-estimation : 00:00:0.13
estimation : 00:00:2.5
post-estimation : 00:00:1.26
Iterations : 40
Min abs eigenvalue of Hessian : 1.354019
Unconstrained optimisation.
Estimates:
Estimate s.e. t.rat.(0) p(1-sided) t.rat(1) p(1-sided) Rob.s.e. Rob.t.rat.(0) p(1-sided) Rob.t.rat.(1) p(1-sided)
asc_car_simple 0.000000 NA NA NA NA NA NA NA NA NA NA
asc_car_complex -1.123765 0.14984 -7.4996 3.197e-14 -14.173 0.00000 0.20371 -5.5166 1.728e-08 -10.4256 0.00000
asc_walk_simple 3.278206 0.37951 8.6381 0.00000 6.003 9.680e-10 0.46147 7.1039 6.064e-13 4.9369 3.969e-07
asc_walk_complex 1.770551 0.37789 4.6854 1.397e-06 2.039 0.02072 0.39147 4.5229 3.050e-06 1.9684 0.02451
asc_transit_simple -1.424081 0.36593 -3.8917 4.977e-05 -6.624 1.743e-11 0.38414 -3.7071 1.0480e-04 -6.3103 1.392e-10
asc_transit_complex -1.740878 0.76023 -2.2899 0.01101 -3.605 1.5589e-04 1.45577 -1.1958 0.11588 -1.8828 0.02987
b_tt_car -0.013776 0.02971 -0.4637 0.32145 -34.119 0.00000 0.06378 -0.2160 0.41450 -15.8942 0.00000
b_tt_walk -0.047172 0.01057 -4.4648 4.007e-06 -99.115 0.00000 0.02079 -2.2686 0.01165 -50.3613 0.00000
b_tt_transit -0.006009 0.01269 -0.4735 0.31794 -79.263 0.00000 0.02686 -0.2237 0.41149 -37.4519 0.00000
b_cost 0.023027 0.03520 0.6542 0.25650 -27.755 0.00000 0.03894 0.5913 0.27715 -25.0892 0.00000
lambda_simple 1.000000 NA NA NA NA NA NA NA NA NA NA
lambda_complex 0.477712 0.34821 1.3719 0.08505 -1.500 0.06682 0.71996 0.6635 0.25350 -0.7254 0.23409
Nesting structure for NL model component :
Nest: root (1)
|-Nest: simple (1)
| |-Alternative: car_simple
| |-Alternative: walk_simple
| '-Alternative: transit_simple
'-Nest: complex (0.4777)
|-Alternative: car_complex
|-Alternative: walk_complex
'-Alternative: transit_complex
Regarding your question:
- My assumptions is that alternatives on simple tours may share some unobserved characteristics that are different to alternatives on complex tours, which could be reflected in the lambda parameter significantly different from 1.
- I have no nest-specific variables. Travel time is of course mode-specific. Cost is generic. Utilities are as follows:
Code: Select all
V <- list()
V[['car_simple']] <- asc_car_simple +
b_tt_car * tour_tt_driving +
b_cost * tour_cost_driving
V[['car_complex']] <- asc_car_complex +
b_tt_car * tour_tt_driving +
b_cost * tour_cost_driving
V[['walk_simple']] <- asc_walk_simple +
b_tt_walk * tour_tt_walk
V[['walk_complex']] <- asc_walk_complex +
b_tt_walk * tour_tt_walk
V[['transit_simple']] <- asc_transit_simple +
b_tt_transit * tour_tt_transit +
b_cost * tour_cost_transit
V[['transit_complex']] <- asc_transit_complex +
b_tt_transit * tour_tt_transit +
b_cost * tour_cost_transit
- The availabilities are controlled by the same variables for both simple and complex. I have of course cases when only one alternative is available (e.g. captive drivers), but it doesn't affect the estimation I guess, does it?
Code: Select all
avail = list(car_simple = tour_avail_car, walk_simple = tour_avail_walk, transit_simple = tour_avail_transit,
car_complex = tour_avail_car, walk_complex = tour_avail_walk, transit_complex = tour_avail_transit)
What is going wrong here?
Bartosz
Re: Nested Logit - fixed lambda (NNNL vs. UMNL)
Posted: 06 Jan 2022, 07:02
by stephanehess
Bartosz
are you able to share the data with me?
Best wishes
Stephane
Re: Nested Logit - fixed lambda (NNNL vs. UMNL)
Posted: 07 Jan 2022, 08:39
by bartosz
Of course, you should have it on your mailbox already.
Thanks again for your time.
Bartosz
Re: Nested Logit - fixed lambda (NNNL vs. UMNL)
Posted: 07 Jan 2022, 18:07
by stephanehess
Bartosz
we had a look at this. In your model, the attributes do not differ between the simple and complex version of each alternative. So the model is able to explain the choice between these only through the constant, and as the constants are nest-specific, you cannot then estimate the structural parameter for a nest. Is this really what you in mind for your model?
Stephane
Re: Nested Logit - fixed lambda (NNNL vs. UMNL)
Posted: 11 Jan 2022, 09:47
by bartosz
Stephane
Thank you very much for having a look at the data and pointing out the problems with my model.
You are correct, the attributes do not differ between simple and complex tours because I do not suppose that people perceive time and cost in a different way depending on how complex their daily schedule is (but I will give it a try).
However, I suspect that there are some common characteristics of driving, walking, and transit on a simple tour that are different from common characteristics of driving, walking, and transit on a complex tour. And that it is not about time and cost - that's why I didn't make them nest-specific. This is one reason for the NL specification with this particular nesting structure. Another reason is that I wanted to model two choices actually: (1) choice of tour complexity, (2) and choice of travel mode.
So, if I want to give the NL model some sense and make it estimable, I have the following options:
- make time and cost coefficients nest-specific
- make ASCs mode-specific (but not nest-specific)
- introduce some nest-specific or mode&nest-specific variables that would affect the decision between simple and complex (e.g. age or company on a tour)
Am I right regarding the above?
Bartosz
Re: Nested Logit - fixed lambda (NNNL vs. UMNL)
Posted: 14 Jan 2022, 16:57
by stephanehess
Bartosz
I'm still not clear what you are trying to do here exactly, or why you want a nested logit model for it. Nested logit is not a model of sequential choice behaviour. So it would not model the choice of tour type followed by mode, as the dependent variable in your model is the mode
But making the coefficients nest specific will not help. The problem is that the attributes are the same
Stephane
Re: Nested Logit - fixed lambda (NNNL vs. UMNL)
Posted: 18 Jan 2022, 17:15
by bartosz
Stephane
thanks again for looking at this.
stephanehess wrote: 14 Jan 2022, 16:57
I'm still not clear what you are trying to do here exactly, or why you want a nested logit model for it. Nested logit is not a model of sequential choice behaviour. So it would not model the choice of tour type followed by mode, as the dependent variable in your model is the mode
Actually, the dependent variable is a combination of tour complexity and transport mode: simple car, simple transit, complex car, ...
Alternatively, instead of using the combined DVs as above, one could use a bivariate model with two separate dependent variables: (1) mode choice and (2) tour complexity, as Ye & Pendyala (2007) did. They write:
The relationship between these two aspects of travel behavior is represented in this paper by considering three different causal structures: one structure in which the trip chaining pattern is determined first and influences mode choice, another structure in which mode choice is determined first and influences the complexity of the trip chaining pattern, and a third structure in which neither is predetermined but both are determined simultaneously. The first two structures are estimated within a recursive bivariate probit modeling framework that accommodates error covariance. The simultaneous logit model is estimated for the third structure that allows a bidirectional simultaneous causality.
Is it possible to specify a bivariate model in Apollo?
----------------------------------------
stephanehess wrote: 14 Jan 2022, 16:57
But making the coefficients nest specific will not help. The problem is that the attributes are the same
Ok, I think I finally get it. I was trying to follow what Hensher & Reyes (2000) did in their paper, where they applied MNL, NL and MMNL to Sydney HTS data to study trip chain choices. They combined different trip chaining patterns (H-W-H, H-W-NW-H, etc.) and two modes (car, PT) into 11 mode-chain combinations. So did I, by creating 6 alternatives from 2 levels of complexity and 3 modes.
What I did differently, however, is that I started with a "base" model with only travel time and cost (with a plan to expand it), and no other variables, and got stuck at the confusing outcomes that I obtained. As you noticed in a previous post, I tried to model a choice between e.g. transit on a simple tour and transit on a complex tour without actually having any variable affecting this choice, because I only had time and cost, which are identical in this case. Whereas Hensher & Reyes operated with characteristics of the individuals (age, income, ...) and alternative-specific coefficients, which made it possible to capture e.g. the effect of age on the choice of car for a simple tour and for a complex tour separately.
I need to modify the utility functions (= add sociodemographic variables), so that the utility of simple and complex can be different. I will test it with MNL and then NL and see whether it performs better.
Re: Nested Logit - fixed lambda (NNNL vs. UMNL)
Posted: 24 Jan 2022, 13:21
by stephanehess
Hi
if you can write probabilities for such a model, then you can implement yourself in Apollo
Stephane