Page 1 of 1

CNL models with individual alphas

Posted: 04 Dec 2020, 07:47
by mastermoses
Hi,

I am currently estimating CNL models for mode choice based on SP-RP data. The SP data was mainly conducted among users of a ride pooling service. Depending on their ride pooling usage (one time user vs. regular user), the alphas vary heavily. So, I wondered if there is a possibility to use individual alphas or at least sociodemographic influences on the alphas when estimating CNL models with Apollo (or even in general)? First tries were of course not successful, since sociodemographic influences are treated as vectors, whereas the alphas have to be single values.

Thanks
Michael

Re: CNL models with individual alphas

Posted: 05 Dec 2020, 17:25
by dpalma
Hi Michael,

I am afraid the CNL model cannot use different alphas across individuals, neither it can use random alphas. We might allow this in future versions of Apollo.

One possible way to work around this restriction would be to jointly estimate multiple CNL models, one for each group of individuals with the same alphas. The key would be excluding observations using the "rows" setting inside "cnl_setting". For example, let's imagine you have two groups of individuals: low and high income individuals. The code below assumes both groups to have the same preferences, except for their alphas.

Code: Select all

# ################################################################# #
#### LOAD LIBRARY AND DEFINE CORE SETTINGS                       ####
# ################################################################# #

### Initialise
rm(list = ls())
library(apollo)
apollo_initialise()

### Set core controls
apollo_control = list(
  modelName  ="CNL2",
  modelDescr ="CNL model with two sets of alpha parameters",
  indivID    ="ID"
)

# ################################################################# #
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS                     ####
# ################################################################# #

data("apollo_modeChoiceData", package='apollo')
database = apollo_modeChoiceData
rm(apollo_modeChoiceData)

# ################################################################# #
#### DEFINE MODEL PARAMETERS                                     ####
# ################################################################# #

### Parameters, e.g.: c(name1=value1, name2=value2, ...)
apollo_beta=c(asc_bus  = 0,
              asc_air  = 0,
              asc_rail = 0,
              bTT      = 0,
              bAcc     = 0,
              bCost    = 0,
              bWifi    = 0,
              bFood    = 0,
              lFPT     = 0.95, 
              lGPT     = 0.95,
              a1Rail_GPT = 0,
              a2Rail_GPT = 0)

### Name of parameters fixed to their starting values, e.g. c("name1")
apollo_fixed = c()

# ################################################################# #
#### GROUP AND VALIDATE INPUTS                                   ####
# ################################################################# #

apollo_inputs = apollo_validateInputs()

# ################################################################# #
#### DEFINE MODEL AND LIKELIHOOD FUNCTION                        ####
# ################################################################# #

apollo_probabilities=function(apollo_beta, apollo_inputs, 
                              functionality="estimate"){

  ### Initialise
  apollo_attach(apollo_beta, apollo_inputs)
  on.exit(apollo_detach(apollo_beta, apollo_inputs))
  P = list()
  
  ### Utilities are common for low and high income individuals
  V = list()
  V[['car']]  =            bTT*time_car                     + bCost*cost_car
  V[['bus']]  = asc_bus  + bTT*time_bus  + bAcc*access_bus  + bCost*cost_bus 
  V[['air']]  = asc_air  + bTT*time_air  + bAcc*access_air  + bCost*cost_air  + bWifi*(service_air ==2) + bFood*(service_air ==3)
  V[['rail']] = asc_rail + bTT*time_rail + bAcc*access_rail + bCost*cost_rail + bWifi*(service_rail==2) + bFood*(service_rail==3)
  
  ### Nest scale parameters are common for low and high income individuals
  cnlNests = list(fastPT   = lFPT, 
                  groundPT = lGPT, 
                  car      = 1)

  ### Nest allocation parameters (alpha) are different  for low and high income individuals
  a1 = 1 / (1 + exp(-a1Rail_GPT))
  a2 = 1 / (1 + exp(-a2Rail_GPT))
  #                       car bus air  rail
  cnlStructure1 = matrix(c( 0,  0,  1, 1-a1, # fastPT
                            0,  1,  0,   a1, # groundPT
                            1,  0,  0,    0),# car
                         nrow=length(cnlNests), ncol=length(V), byrow=TRUE)
  #                       car bus air  rail
  cnlStructure2 = matrix(c( 0,  0,  1, 1-a2, # fastPT
                            0,  1,  0,   a2, # groundPT
                            1,  0,  0,    0),# car
                         nrow=length(cnlNests), ncol=length(V), byrow=TRUE)
  
  ### Likelihood for low income individuals
  cnl_settings <- list(
    alternatives = c(car=1, bus=2, air=3, rail=4),
    avail        = list(car=av_car, bus=av_bus, air=av_air, rail=av_rail),
    choiceVar    = choice,
    V            = V,
    cnlNests     = cnlNests,
    cnlStructure = cnlStructure1,
    rows         = income<45000
  )
  P[["lowInc"]] = apollo_cnl(cnl_settings, functionality)
  
  ### Likelihood for high income individuals
  cnl_settings$cnlStructure = cnlStructure2
  cnl_settings$rows         = income>=45000
  P[["highInc"]] = apollo_cnl(cnl_settings, functionality)
  
  ### Comment out as necessary 
  P = apollo_combineModels(P, apollo_inputs, functionality)
  P = apollo_panelProd(P, apollo_inputs, functionality)
  P = apollo_prepareProb(P, apollo_inputs, functionality)
  return(P)
}

# ################################################################# #
#### MODEL ESTIMATION & OUTPUT                                   ####
# ################################################################# #

model = apollo_estimate(apollo_beta, apollo_fixed, 
                        apollo_probabilities, apollo_inputs, 
                        estimate_settings=list(writeIter=FALSE))

apollo_modelOutput(model)

apollo_saveOutput(model)

Re: CNL models with individual alphas

Posted: 11 Dec 2020, 11:03
by mastermoses
Hi David,

thanks for your suggestion, it worked perfectly for my case! I am looking forward to see those features in future version of Apollo.

Best,
Michael