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.

Latent class model with covariates in class allocation model

Ask questions about how to estimate models and how to change your settings for estimation.
Post Reply
malemu588@gmail.com
Posts: 12
Joined: 03 Mar 2022, 18:36

Latent class model with covariates in class allocation model

Post by malemu588@gmail.com »

Dear Stephane,

Thanks for your support in this forum.

I am running a model with many parameters and using Apollo’s search functions for starting values. Models with up to four classes run fine, but with five classes, one parameter (ercr2) has an extreme estimate (-250.99 vs. others mostly below 2), and Apollo reports "Singular Hessian, cannot calculate s.e." The starting values come from Apollo. I tried implementing your forum suggestion by fixing that parameter and re-estimating, but I received the error: Error in dim(dr_vec) <- c(n,p):

I suspect the large number of parameters may be an issue, but I would appreciate any insights. Codes are below. Thanks.

Kind regards,
Mohammed

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

### Set your working directory
setwd("C:/Users/zsc245/OneDrive - University of Copenhagen/NOVASOIL/Ferdinand Stuff/Main survey/Main analysis/Final for paper")
getwd()

###Install packages
###install.packages("dplyr")
###library(dplyr)

###install.packages("apollo")

### Load Apollo library
library(apollo)

### Initialise code
apollo_initialise()

### Set core controls
apollo_control = list(
modelName = "LC-MNL",
modelDescr = "LC-MNL-classes",
indivID = "id",
#mixing = TRUE,
#panelData = TRUE,
outputDirectory = "latentMNLout",
nCores = 25
)

# ################################################################# #
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS ####
# ################################################################# #
database = read.csv("Ferd_data_analyse.csv",header=TRUE, na.strings=".")
###database <- as.data.frame(database)
database$female <- ifelse(database$gender==1, 1, 0)
database$educ <- ifelse(database$education==3, 1, 0)
database$supp <- ifelse(database$finansuport==1, 1, 0)
database$envlab <- ifelse(database$envlabel<=4, 1, 0)
database<-subset(database,database$protest==0)
database<-subset(database,database$postc==0)


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

### Vector of parameters, including any that are kept fixed in estimation
#apollo_beta = model$estimate
apollo_beta=c(ASC1 = -1.7282,
ASC2 = 0.4544,
ASC3 = -2.2466,
ASC4 = -0.7735,
ASC5 = 0.4816,
eros1 = 1.5483,
eros2 = -0.0062,
eros3 = 0.8200,
eros4 = 0.9534,
eros5 = 0.6443,
pest01 = 1.5754,
pest02 = 0.9726,
pest03 = 0.8735,
pest04 = 1.6237,
pest05 = 1.0637,
carb1 = 0.6198,
carb2 = 0.7234,
carb3 = 1.0534,
carb4 = 1.1632,
carb5 = 0.1001,
erps1 = 1.8612,
erps2 = 0.3790,
erps3 = 1.4313,
erps4 = 1.3597,
erps5 = 0.7433,
ercr1 = 1.1524,
ercr2 = -1.9438,
ercr3 = 1.2695,
ercr4 = 1.5886,
ercr5 = 0.4662,
pscr1 = 0.8561,
pscr2 = 1.1112,
pscr3 = 1.1670,
pscr4 = 1.7155,
pscr5 = 0.6849,
psercr1 = 2.1870,
psercr2 = 0.4965,
psercr3 = 1.2782,
psercr4 = 2.0376,
psercr5 = 0.6306,
plant01 = 1.3194,
plant02 = -0.2691,
plant03 = 0.8183,
plant04 = 1.8685,
plant05 = 0.9673,
animal01 = 0.4955,
animal02 = 0.2182,
animal03 = 1.0008,
animal04 = 2.1295,
animal05 = 0.6525,
poll1 = 0.9064,
poll2 = 0.0747,
poll3 = 0.8762,
poll4 = 1.3980,
poll5 = 0.3886,
plantanimal01 = 0.6636,
plantanimal02 = 1.6554,
plantanimal03 = 1.3781,
plantanimal04 = 2.6684,
plantanimal05 = 1.1034,
plantpoll1 = 0.6523,
plantpoll2 = 0.7871,
plantpoll3 = 0.8940,
plantpoll4 = 2.1846,
plantpoll5 = 0.7574,
animalpoll1 = 0.5650,
animalpoll2 = 0.8603,
animalpoll3 = 0.9152,
animalpoll4 = 2.1790,
animalpoll5 = 1.3962,
plantanimalpoll1 = 0.9457,
plantanimalpoll2 = 1.0229,
plantanimalpoll3 = 1.1408,
plantanimalpoll4 = 3.3318,
plantanimalpoll5 = 1.3498,
fund151 = 0.4559,
fund152 = -0.7449,
fund153 = 0.4291,
fund154 = 0.5229,
fund155 = -0.0811,
fund301 = 0.9818,
fund302 = 0.4890,
fund303 = 0.7186,
fund304 = 0.6585,
fund305 = 0.1087,
fund451 = 0.5449,
fund452 = 0.3007,
fund453 = 0.5559,
fund454 = 0.6622,
fund455 = 0.0631,
cost1 = -0.1171,
cost2 = -0.1456,
cost3 = -0.0209,
cost4 = 0.0034,
cost5 = -0.0159,
age1 = 0.0194,
age2 = 0.0317,
age3 = 0.0067,
age4 = 0.0112,
female1 = 0.3495,
female2 = 0.0621,
female3 = 0.1540,
female4 = -0.2613,
educ1 = -0.1476,
educ2 = -0.7284,
educ3 = -0.0264,
educ4 = -0.2999,
env1 = -0.4418,
env2 = -1.3529,
env3 = 0.4687,
env4 = -1.2924,
delta1 = -0.3535,
delta2 = -0.7715,
delta3 = 0.1367,
delta4 = -0.2078)


## 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()


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

apollo_lcPars = function(apollo_beta, apollo_inputs){
lcpars = list()
lcpars[["b_asc"]] = list(ASC1, ASC2, ASC3, ASC4, ASC5)
lcpars[["b_eros"]] = list(eros1, eros2, eros3, eros4, eros5)
lcpars[["b_pest"]] = list(pest01, pest02, pest03, pest04, pest05)
lcpars[["b_carb"]] = list(carb1, carb2, carb3, carb4, carb5)
lcpars[["b_erps"]] = list(erps1, erps2, erps3, erps4, erps5)
lcpars[["b_ercr"]] = list(ercr1, ercr2, ercr3, ercr4, ercr5)
lcpars[["b_pscr"]] = list(pscr1, pscr2, pscr3, pscr4, pscr5)
lcpars[["b_psercr"]] = list(psercr1, psercr2, psercr3, psercr4, psercr5)
lcpars[["b_plant"]] = list(plant01, plant02, plant03, plant04, plant05)
lcpars[["b_animal"]] = list(animal01, animal02, animal03, animal04, animal05)
lcpars[["b_poll"]] = list(poll1, poll2, poll3, poll4, poll5)
lcpars[["b_plantanimal"]] = list(plantanimal01, plantanimal02, plantanimal03, plantanimal04, plantanimal05)
lcpars[["b_plantpoll"]] = list(plantpoll1, plantpoll2, plantpoll3, plantpoll4, plantpoll5)
lcpars[["b_animalpoll"]] = list(animalpoll1, animalpoll2, animalpoll3, animalpoll4, animalpoll5)
lcpars[["b_plantanimalpoll"]] = list(plantanimalpoll1, plantanimalpoll2, plantanimalpoll3, plantanimalpoll4, plantanimalpoll5)
lcpars[["b_fund15"]] = list(fund151, fund152, fund153, fund154, fund155)
lcpars[["b_fund30"]] = list(fund301, fund302, fund303, fund304, fund305)
lcpars[["b_fund45"]] = list(fund451, fund452, fund453, fund454, fund455)
lcpars[["b_cost"]] = list(cost1, cost2, cost3, cost4, cost5)

V=list()
V[["class_a"]] = delta1 + age1 * age + female1 * female + educ1 * educ + env1 * envlab
V[["class_b"]] = delta2 + age2 * age + female2 * female + educ2 * educ + env2 * envlab
V[["class_c"]] = delta3 + age3 * age + female3 * female + educ3 * educ + env3 * envlab
V[["class_d"]] = delta4 + age4 * age + female4 * female + educ4 * educ + env4 * envlab
V[["class_e"]] = 0

classAlloc_settings = list(
classes = c(class_a=1, class_b=2, class_c=3, class_d=4, class_e=5),
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
mnl_settings = list(
alternatives = c(alt1=1, alt2=2, alt3=3),
avail = list(alt1=1, alt2=1, alt3=1),
choiceVar = choice
)

### Loop over classes
for(s in 1:5){

### Compute class-specific utilities
V=list()

V[['alt1']] = (b_eros[[s]] * erosion1 + b_pest[[s]] * pest1 + b_carb[[s]] * carbon1 + b_erps[[s]] * erosionpest1 + b_ercr[[s]] * erosioncarbon1 + b_pscr[[s]] * pestcarbon1
+ b_psercr[[s]] * pesterosioncarbon1 + b_plant[[s]] * plant1 + b_animal[[s]] * animal1 + b_poll[[s]] * pollination1 + b_plantanimal[[s]] * plantanimal1
+ b_plantpoll[[s]] * plantpollinat1 + b_animalpoll[[s]] * animalpolinat1 + b_plantanimalpoll[[s]] * plantanimalpolinat1 + b_fund15[[s]] * fiftper1
+ b_fund30[[s]] * thritper1 + b_fund45[[s]] * fourtfper1 + b_cost[[s]] * price1)
V[['alt2']] = (b_eros[[s]] * erosion2 + b_pest[[s]] * pest2 + b_carb[[s]] * carbon2 + b_erps[[s]] * erosionpest2 + b_ercr[[s]] * erosioncarbon2 + b_pscr[[s]] * pestcarbon2
+ b_psercr[[s]] * pesterosioncarbon2 + b_plant[[s]] * plant2 + b_animal[[s]] * animal2 + b_poll[[s]] * pollination2 + b_plantanimal[[s]] * plantanimal2
+ b_plantpoll[[s]] * plantpollinat2 + b_animalpoll[[s]] * animalpolinat2 + b_plantanimalpoll[[s]] * plantanimalpolinat2 + b_fund15[[s]] * fiftper2
+ b_fund30[[s]] * thritper2 + b_fund45[[s]] * fourtfper2 + b_cost[[s]] * price2)
V[['alt3']] = (b_asc[[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)

}

### Compute latent class model probabilities
lc_settings = list(inClassProb = P, classProb=pi_values)
P[["model"]] = apollo_lc(lc_settings, apollo_inputs, functionality)


### Prepare and return outputs of function
P = apollo_prepareProb(P, apollo_inputs, functionality)
return(P)

}

### Estimate model
###apollo_beta=apollo_searchStart(apollo_beta, apollo_fixed,apollo_probabilities, apollo_inputs)

###apollo_beta=apollo_searchStart(apollo_beta, apollo_fixed,apollo_probabilities, apollo_inputs)

model = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs)


RESULTS
stephanehess
Site Admin
Posts: 1339
Joined: 24 Apr 2020, 16:29

Re: Latent class model with covariates in class allocation model

Post by stephanehess »

Hi

5 classes is almost always too many. Did you look at how the model fit changes when you increase classes?

Stephane
--------------------------------
Stephane Hess
www.stephanehess.me.uk
malemu588@gmail.com
Posts: 12
Joined: 03 Mar 2022, 18:36

Re: Latent class model with covariates in class allocation model

Post by malemu588@gmail.com »

Hi Stephane,

Many thanks for your time and response.

The model fit didn’t change much—only around a 1% difference in AIC, BIC, and CAIC—so I decided to keep the model with four classes (see below - D is difference).

Classes #parametrs LL Adjusted R squared BIC AIC CAIC
2 43 -10296.43 0.1924 21000.25 20678.87 20681.37316 DBIC DAIC DCAIC
3 67 -9566.73 0.2477 19768.21 19267.46 19273.48311 5.8667873 6.825372953 6.807526962
4 91 -9375.92 0.2609 19613.96 18933.84 18944.99515 0.780293208 1.731520398 1.704351802
5 115 -9246.55 0.2693 19582.6 18723.09 18741.06616 0.159886122 1.11308641 1.076426726


Kind regards,
Mohammed
Post Reply