I am currently estimating a nested logit model with location choice (randomly choose three alternatives, 'alt2', 'alt3', 'alt4', from all TAZ zones, and 'alt1' is always the choosing TAZ zone for an individual ) as the upper level and utility for four different travel modes ('Auto,'' Passenger,' 'Rideshare,' 'PT') as the lower level. I encountered two questions with the model specification, and I am writing to ask for your kind suggestions.
The two questions are:
1) I have both TAZ alternative-specific variables (b_LogCensusEmploy & b_LogCensuspop) and mode-specific variables (c_AutoPassUtil, C_Rideshare, C_PTUtil). Currently, I am coding the utility function as follows:
Code: Select all
### List of utilities
V = list()
for(s in 1:4){
V[[paste0("Auto",s)]] = 0
V[[paste0("Passenger",s)]] = get(paste0("asc_AutoPassen",s)) +
b_LogCensusEmploy* get(paste0("CensusEmploy",s )) +
b_LogCensuspop* get(paste0("CensusPop",s )) +
C_AutoPassUtil* get(paste0("Auto_util",s))
V[[paste0("Rideshare",s)]] = get(paste0("asc_Rideshare",s))+
b_LogCensusEmploy* get(paste0("CensusEmploy",s )) +
b_LogCensuspop* get(paste0("CensusPop",s )) +
C_Rideshare* get(paste0("Auto_util",s)) *0.8
V[[paste0("PT",s)]] = get(paste0("asc_PT",s)) +
b_LogCensusEmploy* get(paste0("CensusEmploy",s )) +
b_LogCensuspop* get(paste0("CensusPop",s )) +
C_PTUtil* get(paste0("PT_util",s))
It seems inappropriate to put both alternative-specific variables and mode-specific variables in the same format as above, but I don't know what the appropriate way is to join both alternative and mode-specific variables in the utility function.
2) For the nlStructure settings, I tried to code it as a loop as I want to join more TAZ alternatives for the next step (currently random select 3 out of 1757 TAZs, extend it to random select 219 out of 1757 TAZs afterward). I coded the tree structure based on one of the questions you answered in the forum. However, when I estimated using the following codes, the LLstart became 0. I think there should be something wrong with the tree structure setting part, but when I ran the code separately, it generated the right tree structure.
Code: Select all
### Specify tree structure for NL model
list_alt = paste0("alt",1:4)
nlStructure = matrix(paste0(rep(c('Auto','Passenger','Rideshare','PT'), times=4), rep(1:4, each=4)), ncol=4, byrow=TRUE)
nlStructure = setNames(split(nlStructure, 1:length(list_alt)), list_alt)
nlStructure[['root']] = as.character(list_alt)
Attached code below:
Code: Select all
rm(list = ls())
library(apollo)
apollo_initialise()
# #################################################################
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS
# #################################################################
database = read.csv(".\\02_TAZ_availablematrix_V2.csv", header = TRUE)
database <- database %>%
mutate(jointchoice = groupe_modes)
#View(database)
apollo_control = list(
modelName ="Apollo_NL",
modelDescr ="Two-level NL model with Location and Mode choice",
nCores = 4,
panelData=FALSE,
indivID = "AID"
)
list_loc <- unique(seq(1, 4, by=1))
apollo_beta=c(c(
asc_AutoPassen1 = 0,
asc_Rideshare1 = 0,
asc_PT1 = 0,
asc_AutoPassen2 = 0,
asc_Rideshare2 = 0,
asc_PT2 = 0,
asc_AutoPassen3 = 0,
asc_Rideshare3 = 0,
asc_PT3 = 0,
asc_AutoPassen4 = 0,
asc_Rideshare4 = 0,
asc_PT4 = 0,
C_AutoPassUtil = 1,
C_Rideshare = 1,
C_PTUtil = 1,
# b_Dist = 0,
b_LogCensusEmploy = -3,
b_LogCensuspop = -3),
setNames(rep(0.5, length(list_loc)), paste0("lamda", list_loc))
)
apollo_fixed =c()
### Group and validate inputs
apollo_inputs = apollo_validateInputs()
apollo_probabilities=function(apollo_beta, apollo_inputs, functionality="estimate"){
### Attach inputs and detach after function exit
apollo_attach(apollo_beta, apollo_inputs)
on.exit(apollo_detach(apollo_beta, apollo_inputs))
### Create list of probabilities P
P = list()
### List of utilities: these must use the same names as in nl_settings, order is irrelevant
V = list()
for(s in 1:4){
V[[paste0("Auto",s)]] = 0
V[[paste0("Passenger",s)]] = get(paste0("asc_AutoPassen",s)) +
b_LogCensusEmploy* get(paste0("CensusEmploy",s )) +
b_LogCensuspop* get(paste0("CensusPop",s )) +
C_AutoPassUtil* get(paste0("Auto_util",s))
V[[paste0("Rideshare",s)]] = get(paste0("asc_Rideshare",s))+
b_LogCensusEmploy* get(paste0("CensusEmploy",s )) +
b_LogCensuspop* get(paste0("CensusPop",s )) +
C_Rideshare* get(paste0("Auto_util",s)) *0.8
V[[paste0("PT",s)]] = get(paste0("asc_PT",s)) +
b_LogCensusEmploy* get(paste0("CensusEmploy",s )) +
b_LogCensuspop* get(paste0("CensusPop",s )) +
C_PTUtil* get(paste0("PT_util",s))
}
nlNests = list(root=1)
for (loc in 1:4) {
nlNests[[paste0("alt",loc)]] <- get(paste0("lamda", loc))
}
### Specify tree structure for NL model
list_alt = paste0("alt",1:4)
nlStructure = matrix(paste0(rep(c('Auto','Passenger','Rideshare','PT'), times=4), rep(1:4, each=4)), ncol=4, byrow=TRUE)
nlStructure = setNames(split(nlStructure, 1:length(list_alt)), list_alt)
nlStructure[['root']] = as.character(list_alt)
#nlStructure= list()
#nlStructure[["root"]] = c("alt1","alt2","alt3","alt4")
#nlStructure[["alt1"]] = c("Auto1","Passenger1","Rideshare1","PT1")
#nlStructure[["alt2"]] = c("Auto2","Passenger2","Rideshare2","PT2")
#nlStructure[["alt3"]] = c("Auto3","Passenger3","Rideshare3","PT3")
#nlStructure[["alt4"]] = c("Auto4","Passenger4","Rideshare4","PT4")
# Define settings for NL model
nl_settings <- list(
alternatives = c(Auto1=1, Passenger1=2, Rideshare1=3, PT1=4,
Auto2=5, Passenger2=6, Rideshare2=7, PT2=8,
Auto3=9, Passenger3=10, Rideshare3=11, PT3=12,
Auto4=13, Passenger4=14, Rideshare4=15, PT4=16),
avail = 1,
choiceVar = jointchoice,
V = V,
nlNests = nlNests,
nlStructure = nlStructure
)
### Compute probabilities using NL model
## Take product across observation for same individual
#P = apollo_panelProd(P, apollo_inputs, functionality)
P[["model"]] = apollo_nl(nl_settings, functionality)
### Prepare and return outputs of function
P = apollo_prepareProb(P, apollo_inputs, functionality)
return(P)
}
estimate_settings <- list(maxIterations = 10000)
### Optional starting values search
apollo_beta=apollo_searchStart(apollo_beta, apollo_fixed,apollo_probabilities, apollo_inputs)
# #################################################################
#### MODEL ESTIMATION
# #################################################################
NLmodel = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs)
#tmp=apollo_probabilities(apollo_beta,apollo_inputs,functionality="output")
}
apollo_modelOutput(NLmodel)
predictions_base = apollo_prediction(NLmodel, apollo_probabilities, apollo_inputs,
prediction_settings=list(runs=30))
apollo_saveOutput(NLmodel)