Important: Read this before posting to this forum

  1. This forum is for questions related to the use of Apollo. We will answer some general choice modelling questions too, where appropriate, and time permitting. We cannot answer questions about how to estimate choice models with other software packages.
  2. There is a very detailed manual for Apollo available at http://www.ApolloChoiceModelling.com/manual.html. This contains detailed descriptions of the various Apollo functions, and numerous examples are available at http://www.ApolloChoiceModelling.com/examples.html. In addition, help files are available for all functions, using e.g. ?apollo_mnl
  3. Before asking a question on the forum, users are kindly requested to follow these steps:
    1. Check that the same issue has not already been addressed in the forum - there is a search tool.
    2. Ensure that the correct syntax has been used. For any function, detailed instructions are available directly in Apollo, e.g. by using ?apollo_mnl for apollo_mnl
    3. Check the frequently asked questions section on the Apollo website, which discusses some common issues/failures. Please see http://www.apollochoicemodelling.com/faq.html
    4. Make sure that R is using the latest official release of Apollo.
  4. If the above steps do not resolve the issue, then users should follow these steps when posting a question:
    1. provide full details on the issue, including the entire code and output, including any error messages
    2. posts will not immediately appear on the forum, but will be checked by a moderator first. We check the forum at least twice a week. It may thus take a couple of days for your post to appear and before we reply. There is no need to submit the post multiple times.

Errors in estimating LC-MMNL

Ask questions about errors you encouunter. Please make sure to include full details about your model specifications, and ideally your model file.
Post Reply
arohamirai1
Posts: 3
Joined: 24 Sep 2024, 12:38

Errors in estimating LC-MMNL

Post by arohamirai1 »

Dear Stephane and David,

Thank you for providing this platform for Appolo users. I have a question about a LC-MMNL model used for identifying ANA behaviour.

Setting
Choices are allocated to two classes, the first class is the ANA class where only cost and ASC parameters are freely estimated and other attribute parameters are fixed at zero. All parameters in the second class are freely estimated and are assumed to be normally distributed.
Questions
(1) I estimated the model using the code below and a error message popped up: Error in apollo_avgInterDraws(P[[paste0("Class_", s)]], apollo_inputs, : SPECIFICATION ISSUE - No Inter-individuals draws to average over!
Could you let me know what can be the issue?

(2) I see in the manual example that you also assumed a normal distribution for the parameter delta_a. Is there a reason for this?

Codes

Code: Select all

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

### Clear memory
rm(list = ls())

### Load Apollo library
library(apollo)

### Initialise code
apollo_initialise()

### Set core controls
apollo_control = list(
  modelName  ="LC_MMNL_ANA2_taxASC",
  modelDescr ="LC_MMNL_ANA2_taxASC",
  mixing     = TRUE,               #if no random then turn it off
  indivID    ="id",
  nCores     = 4
)

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

database = read.csv("R_ANAanalysis.csv",header=TRUE)

database= subset(database, database$Version==1|Version==3)


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

### Vector of parameters, including any that are kept fixed in estimation
apollo_beta = c(asc1             = 0,
                
                
                asc3_a           = 0,
                asc3_b_mu        = 0,
                asc3_b_sig       = 0,
                
                fleet_a           = 0,
                fleet_b_mu        = 0,
                fleet_b_sig        = 0,
                
                seasonal_a           = 0,
                seasonal_b_mu        = 0,
                seasonal_b_sig        = 0,            
                
                plastic_a           = 0,
                plastic_b_mu        = 0,
                plastic_b_sig        = 0,
                
                
                buildings_a           = 0,
                buildings_b_mu        = 0,
                buildings_b_sig        = 0,
                
                
                devices_a           = 0,
                devices_b_mu        = 0,
                devices_b_sig        = 0,
                
                fund_a           = 0,
                fund_b_mu        = 0,
                fund_b_sig        = 0,
                
                nature_a           = 0,
                nature_b_mu        = 0,
                nature_b_sig        = 0,
                
                medicine_a           = 0,
                medicine_b_mu        = 0,
                medicine_b_sig        = 0,
                
                tax_a               = 0,
                log_tax_b_mu        = -3,
                log_tax_b_sig       = 1,
                
                gamma_age_a       = 0,
                gamma_male_a      = 0,
                gamma_edu_a       = 0,
                gamma_child_a     = 0,
                gamma_income_a    = 0,
                gamma_climate_a   = 0,
                gamma_urgent_a    = 0,
                gamma_PernotNHS_a = 0,
                
                gamma_age_b       = 0,
                gamma_male_b      = 0,
                gamma_edu_b       = 0,
                gamma_child_b     = 0,
                gamma_income_b    = 0,
                gamma_climate_b   = 0,
                gamma_urgent_b    = 0,
                gamma_PernotNHS_b = 0,               
                
                delta_a           = 0,
                delta_b           = 0

)

### Vector with names (in quotes) of parameters to be kept fixed at their starting value in apollo_beta, use apollo_beta_fixed = c() if none
apollo_fixed = c("delta_a", "asc1",
                 "fleet_a","seasonal_a","plastic_a","buildings_a","devices_a","fund_a","nature_a","medicine_a",
                 "gamma_age_a" ,     
                 "gamma_male_a",      
                 "gamma_edu_a",       
                 "gamma_child_a",     
                 "gamma_income_a",    
                 "gamma_climate_a",   
                 "gamma_urgent_a",    
                 "gamma_PernotNHS_a" 
                 )                


# ################################################################# #
#### DEFINE RANDOM COMPONENTS                                    ####
# ################################################################# #

### Set parameters for generating draws
apollo_draws = list(
  interDrawsType="mlhs",       
  interNDraws=500,                   
  interUnifDraws=c(),                
  interNormDraws=c("draws_fleet", "draws_seasonal", "draws_plastic",
                   "draws_buildings","draws_devices", "draws_fund","draws_nature","draws_medicine","draws_tax","draws_asc3"
  ),    
  
  intraDrawsType="mlhs",
  intraNDraws=0,        
  intraUnifDraws=c(),   
  intraNormDraws=c()    
)

### Create random parameters
apollo_randCoeff = function(apollo_beta, apollo_inputs){
  randcoeff = list()
  randcoeff[["fleet_b"]] = fleet_b_mu + fleet_b_sig*draws_fleet
  randcoeff[["seasonal_b"]] = seasonal_b_mu + seasonal_b_sig*draws_seasonal
  randcoeff[["plastic_b"]] = plastic_b_mu + plastic_b_sig*draws_plastic
  randcoeff[["buildings_b"]] = buildings_b_mu + buildings_b_sig*draws_buildings
  randcoeff[["devices_b"]] = devices_b_mu + devices_b_sig*draws_devices
  randcoeff[["fund_b"]] = fund_b_mu + fund_b_sig*draws_fund
  randcoeff[["nature_b"]] = nature_b_mu + nature_b_sig*draws_nature
  randcoeff[["medicine_b"]] = medicine_b_mu + medicine_b_sig*draws_medicine
  randcoeff[["tax_b"]] = -exp(log_tax_b_mu + log_tax_b_sig*draws_tax)
  
  randcoeff[["asc3_b"]] = asc3_b_mu + asc3_b_sig*draws_asc3

  
  return(randcoeff)
}

# ################################################################# #
#### DEFINE LATENT CLASS COMPONENTS                              ####
# ################################################################# #

apollo_lcPars=function(apollo_beta, apollo_inputs){
  lcpars = list()
  
  
  lcpars[["fleet"]] = list(fleet_a, fleet_b)
  lcpars[["seasonal"]] = list(seasonal_a, seasonal_b)
  lcpars[["plastic"]] = list(plastic_a, plastic_b)
  lcpars[["buildings"]] = list(buildings_a, buildings_b)
  lcpars[["devices"]] = list(devices_a, devices_b)
  lcpars[["fund"]] = list(fund_a, fund_b)
  lcpars[["nature"]] = list(nature_a, nature_b)
  lcpars[["medicine"]] = list(medicine_a, medicine_b)
  lcpars[["tax"]] = list(tax_a, tax_b)
  lcpars[["asc3"]] = list(asc3_a, asc3_b)
  
  

  #add membership function
  
  V=list()
  V[["class_a"]] = delta_a + gamma_age_a*D_age + gamma_male_a*male + gamma_edu_a*degree + gamma_child_a*has_children + 
                             gamma_income_a*D_Lowincome + gamma_climate_a*D_Crn_climate + gamma_urgent_a*urgent_threat + 
                             gamma_PernotNHS_a*D_pers_Notnhs_res
  V[["class_b"]] = delta_b + gamma_age_b*D_age + gamma_male_b*male + gamma_edu_b*degree + gamma_child_b*has_children + 
                             gamma_income_b*D_Lowincome + gamma_climate_b*D_Crn_climate + gamma_urgent_b*urgent_threat + 
                             gamma_PernotNHS_b*D_pers_Notnhs_res                   

  
  classAlloc_settings = list(
    classes      = c(class_a=1, class_b=2), 
    utilities    = V
  )
  
  lcpars[["pi_values"]] = apollo_classAlloc(classAlloc_settings)
  
  return(lcpars)
}

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

apollo_inputs = apollo_validateInputs()

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

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()
  
  ### Define settings for MNL model component that are generic across classes
  mnl_settings = list(
    alternatives = c(alt1=1, alt2=1,alt3=1),
    avail        = list(alt1=1, alt2=1,alt3=1),
    choiceVar    = choice
  )
  
  ### Loop over classes
  for(s in 1:2){

    ### Compute class-specific utilities
    V=list()
    V[['alt1']]  = asc1 + fleet[[s]]*replace_fleet1 + seasonal[[s]]*seasonal1 + plastic[[s]]*less_plastic1 + buildings[[s]]*new_buildings1 + 
                           devices[[s]]*return_devices1 + fund[[s]]*fund1 + nature[[s]]*improve_nature1 + medicine[[s]]*green_medicine1 + tax[[s]]*tax1
    
    V[['alt2']]  = asc1 + fleet[[s]]*replace_fleet2 + seasonal[[s]]*seasonal2 + plastic[[s]]*less_plastic2 + buildings[[s]]*new_buildings2 + 
                           devices[[s]]*return_devices2 + fund[[s]]*fund2 + nature[[s]]*improve_nature2 + medicine[[s]]*green_medicine2 + tax[[s]]*tax2
    
    V[['alt3']]  = asc3[[s]] 
    
    mnl_settings$utilities = V
    mnl_settings$componentName = paste0("Class_",s)
    
    ### Compute within-class choice probabilities using MNL model
    P[[paste0("Class_",s)]] = apollo_mnl(mnl_settings, functionality)
    
    ### Take product across observation for same individual
    P[[paste0("Class_",s)]] = apollo_panelProd(P[[paste0("Class_",s)]], apollo_inputs ,functionality)
    
    ### Average across inter-individual draws within classes
    P[[paste0("Class_",s)]] = apollo_avgInterDraws(P[[paste0("Class_",s)]], apollo_inputs, functionality)
  }
  
  ### Compute latent class model probabilities
  lc_settings  = list(inClassProb = P, classProb=pi_values)
  P[["model"]] = apollo_lc(lc_settings, apollo_inputs, functionality)
  
  ### Average across inter-individual draws in class allocation probabilities
  P[["model"]] = apollo_avgInterDraws(P[["model"]], apollo_inputs, functionality)
  
  ### Prepare and return outputs of function
  P = apollo_prepareProb(P, apollo_inputs, functionality)
  return(P)
}


# ################################################################# #
#### MODEL ESTIMATION AND OUTPUT                                 ####
# ################################################################# #

### Estimate model
model = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs)
Thank you very much for your time.

Best wishes,
Hangjian Wu
stephanehess
Site Admin
Posts: 1355
Joined: 24 Apr 2020, 16:29

Re: Errors in estimating LC-MMNL

Post by stephanehess »

Hi

I think this happens as you have continuous heterogeneity only in class 2.

You can probably make it work by changing

Code: Select all

P[[paste0("Class_",s)]] = apollo_avgInterDraws(P[[paste0("Class_",s)]], apollo_inputs, functionality)
to

Code: Select all

if(s==2) P[[paste0("Class_",s)]] = apollo_avgInterDraws(P[[paste0("Class_",s)]], apollo_inputs, functionality)
Stephane
--------------------------------
Stephane Hess
www.stephanehess.me.uk
arohamirai1
Posts: 3
Joined: 24 Sep 2024, 12:38

Re: Errors in estimating LC-MMNL

Post by arohamirai1 »

Dear Stephane,

Thank you for the solution. However, I still got the same error message. I tried a couple of other ways but still didn't work. Could you help to have a further look and let me know the mistakes in my code please. I will very appreciate it. Thank you very much.

Best wishes,
Hangjian
stephanehess
Site Admin
Posts: 1355
Joined: 24 Apr 2020, 16:29

Re: Errors in estimating LC-MMNL

Post by stephanehess »

Hi

can you send me your model and data via e-mail and I'll have a look

Thanks

Stephane
--------------------------------
Stephane Hess
www.stephanehess.me.uk
stephanehess
Site Admin
Posts: 1355
Joined: 24 Apr 2020, 16:29

Re: Errors in estimating LC-MMNL

Post by stephanehess »

Hi

I looked at your code and data.

First, you have an issue in your code because you are trying to average over draws twice, inside the classes and then at the model level. So in addition to my suggestion of changing

Code: Select all

P[[paste0("Class_",s)]] = apollo_avgInterDraws(P[[paste0("Class_",s)]], apollo_inputs, functionality)
to

Code: Select all

if(s==2)  P[[paste0("Class_",s)]] = apollo_avgInterDraws(P[[paste0("Class_",s)]], apollo_inputs, functionality)
you also need to drop

Code: Select all

P[["model"]] = apollo_avgInterDraws(P[["model"]], apollo_inputs, functionality)
Next, Apollo tells you:

Code: Select all

WARNING: Your database contains some entries that are NA. This may well
  be intentional, but be advised that if these entries are
  used in your model, the behaviour may be unexpected. 
You have 16 rows where has_children is NA, and then you try to use this inside the class allocation utilities. That's causing another failure.

Finally, you had

Code: Select all

alternatives = c(alt1=1, alt2=1,alt3=1)
which needs to be

Code: Select all

alternatives = c(alt1=1, alt2=2,alt3=3)
Stephane
--------------------------------
Stephane Hess
www.stephanehess.me.uk
arohamirai1
Posts: 3
Joined: 24 Sep 2024, 12:38

Re: Errors in estimating LC-MMNL

Post by arohamirai1 »

Dear Stephane,

Thank you very much for looking at the code. These are very helpful and I have resolved the issues.

Could I ask a follow-up question presented in the Apollo manual: I see in the manual example that you assumed a normal distribution for the parameter delta_a. Is there a reason behind for this assumption? thank you very much.

Best wishes,
Hangjian
stephanehess
Site Admin
Posts: 1355
Joined: 24 Apr 2020, 16:29

Re: Errors in estimating LC-MMNL

Post by stephanehess »

Hi

we're in the process of updating the manual and the new example (already on the website but not the manual) will have mixing only within classes. If you want a random constant in the class allocation model, then normal makes sense as it allows for both positive and negative values

Stephane
--------------------------------
Stephane Hess
www.stephanehess.me.uk
Post Reply