Page 1 of 1

HCM with Ordered Logit

Posted: 06 May 2022, 21:27
by Yashin
Dear Concern,

Citing the example of the HCM model with ordered logit, I have a question to ask:

Lambda has been estimated while considering the starting value =1. Lambda has been multiplied with LV for the 2 alternatives (only for the branded products).

My question is:

1. I am setting the HCM for an unlabeled alternative. I have considered only 1 lambda for 2 alternatives (out of 3). I have 4 latent variables, which I have mentioned in my OL part of the models. I would like to know if I am making any mistakes (R code given).

2. I am a bit confused about the lambda, zeta, and gamma. I have gone through the manual, where lambda states that it is the estimated parameters for the Latent variable. and zeta is the estimated parameter that measures the impact of LV on attitudinal indicators.

I am still confused about Lambda. Do I need to set different lambda for the List of utilities? if so, how should I include the Lambda parameters in my utility functions of the generic design?

Note: the different alternatives are unlabeled and its a generic design (I have estimated generic parameters)


Please feel free to respond to the query.

Here is the code that I have written:

# ################################################################# #
#### 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 = "Hybrid_with_OL_16",
modelDescr = "Hybrid choice model on PeCASo data, using ordered measurement model for indicators",
indivID = "sys_RespNum",
mixing = TRUE,
nCores = 4,
outputDirectory = "output"
)

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

### Loading data from package
### if data is to be loaded from a file (e.g. called data.csv),
### the code would be: database = read.csv("data.csv",header=TRUE)
database = read.csv("combined_data_496_dummies_attributecoded_all.csv",header=TRUE)

# ################################################################# #
#### ANALYSIS OF CHOICES ####
# ################################################################# #

### Illustration of how to use apollo_choiceAnalysis with user-defined alternatives.
### This is useful in cases where the alternatives in the data differ across tasks.
#The same approach can then also be used with unlabelled data
#Named numeric vector. Names of alternatives and their corresponding value in ChoiceVAR, You can choose your value as per the attitudinal factors

choiceAnalysis_settings <- list(
alternatives = c(Option_1=1, Option_2=2, Option_3=3),
avail = 1,
choiceVar = database$Response,
explanators = database[,c("Age_d","Gender_d","income_d","Locations" , "KM","ECar",
"HHsize_d","workstatus_d", "Edu_d", "Travelmodes_r1")]
)

apollo_choiceAnalysis(choiceAnalysis_settings, apollo_control, database)

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

### Vector of parameters, including any that are kept fixed in estimation
apollo_beta = c( ASC_1=0,
ASC_2=0,
ASC_3=0,
lambda=0,
#lambda_p_2=1,
#lambda_p_3=1,
#lambda_EC_2=1,
#lambda_EC_3=1,
#lambda_SN_2=1,
#lambda_SN_3=1,
#lambda_ATB_2=1,
#lambda_ATB_3=1,
b_cpeed = 0,
b_dist = 0,
b_resv = 0,
b_cost = 0,
#gamma_T4_perceive=0,
#gamma_T4_SN=0,
#gamma_T4_EC=0,
#gamma_T4_ATB=0,
#gamma_loc_perceive=0,
#gamma_loc_EC=0,
#gamma_loc_SN=0,
#gamma_loc_ATB=0,
gamma_gen_perceive = 0,
gamma_Ecar_perceive=0,
gamma_Ecar_SN=0,
gamma_Ecar_EC=0,
gamma_Ecar_ATB=0,
gamma_KM_perceive=0,
gamma_KM_SN=0,
gamma_KM_EC=0,
gamma_KM_ATB=0,
#gamma_Age_perceive = 0,
gamma_inc_perceive=0,
gamma_hh_perceive = 0,
gamma_T1_perceive = 0,
#gamma_wrk_perceive = 0,
gamma_gen_EC = 0,
#gamma_Age_EC= 0,
#gamma_wrk_EC= 0,
gamma_hh_EC= 0,
gamma_inc_EC= 0,
gamma_T1_EC= 0,
#gamma_wrk_SN= 0,
gamma_T1_SN = 0,
gamma_inc_SN= 0,
gamma_gen_SN= 0,
#gamma_Age_SN= 0,
gamma_hh_SN = 0,
gamma_hh_ATB = 0,
gamma_gen_ATB= 0,
#gamma_Age_ATB = 0,
#gamma_wrk_ATB=0,
gamma_inc_ATB=0,
gamma_T1_ATB=0,
zeta_perceive_2= 1,
zeta_perceive_4= 1,
zeta_ATB_1= 1,
zeta_ATB_2= 1,
zeta_ATB_3= 1,
zeta_SN_4= 1,
zeta_SN_5 =1,
zeta_EC_1=1,
zeta_EC_2=1,
zeta_EC_3=1,
tau_perceive2_1=-2,
tau_perceive2_2=-1,
tau_perceive2_3= 1,
tau_perceive2_4= 2,
tau_perceive4_1=-2,
tau_perceive4_2=-1,
tau_perceive4_3= 1,
tau_perceive4_4= 2,
tau_ATB1_1=-2,
tau_ATB1_2=-1,
tau_ATB1_3= 1,
tau_ATB1_4=2,
tau_ATB2_1=-2,
tau_ATB2_2=-1,
tau_ATB2_3= 1,
tau_ATB2_4= 2,
tau_ATB3_1=-2,
tau_ATB3_2=-1,
tau_ATB3_3= 1,
tau_ATB3_4= 2,
tau_SN4_1= -2,
tau_SN4_2= -1,
tau_SN4_3= 1,
tau_SN4_4= 2,
tau_SN5_1= -2,
tau_SN5_2= -1,
tau_SN5_3= 1,
tau_SN5_4= 2,
tau_EC1_1=-2,
tau_EC1_2=-1,
tau_EC1_3=1,
tau_EC1_4=2,
tau_EC2_1=-2,
tau_EC2_2=-1,
tau_EC2_3=1,
tau_EC2_4=2,
tau_EC3_1=-2,
tau_EC3_2=-1,
tau_EC3_3=1,
tau_EC3_4=2)


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

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

### Set parameters for generating draws
apollo_draws = list(

interDrawsType="halton",
interNDraws=100,
interUnifDraws=c(),
interNormDraws=c("eta_perceive","eta_SN", "eta_ATB" , "eta_EC"),

intraDrawsType="",
intraNDraws=0,
intraUnifDraws=c(),
intraNormDraws=c()
)

### Create random parameters for latent variables

apollo_randCoeff=function(apollo_beta, apollo_inputs){
randcoeff = list()

randcoeff[["LV_1"]] = gamma_T1_perceive*(Travelmodes_r1)+gamma_hh_perceive*(HHsize==2)+
gamma_gen_perceive*(Gender_d)+gamma_KM_perceive*(KM==1)+ gamma_Ecar_perceive*(ECar==1)+ gamma_inc_perceive*(income_d)+
eta_perceive

randcoeff[["LV_2"]] = gamma_T1_SN*(Travelmodes_r1)+gamma_hh_SN*(HHsize==2)+
gamma_gen_SN*(Gender_d)+gamma_KM_SN*(KM==1)+gamma_Ecar_SN*(ECar==1)+gamma_inc_SN*(income_d)+eta_SN

randcoeff[["LV_3"]] = gamma_T1_EC*(Travelmodes_r1)+gamma_hh_EC*(HHsize==2)+
gamma_gen_EC*(Gender_d)+gamma_KM_EC*(KM==1)+gamma_Ecar_EC*(ECar==1)+gamma_inc_EC*(income_d)+eta_EC

randcoeff[["LV_4"]] = gamma_T1_ATB*(Travelmodes_r1)+gamma_hh_ATB*(HHsize==2)+
gamma_gen_ATB*(Gender_d)+gamma_KM_ATB*(KM==1)+ gamma_Ecar_ATB*(ECar==1)+gamma_inc_ATB*(income_d)+eta_ATB

return(randcoeff)
}

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

### Likelihood of indicators
ol_settings1 = list(outcomeOrdered = PBC2,
V = zeta_perceive_2*LV_1,
tau = list(tau_perceive2_1, tau_perceive2_2, tau_perceive2_3, tau_perceive2_4),
rows = (Task==1),
componentName = "PBC_2")
ol_settings2 = list(outcomeOrdered = PBC4,
V = zeta_perceive_4*LV_1,
tau = list(tau_perceive4_1, tau_perceive4_2, tau_perceive4_3, tau_perceive4_4),
rows = (Task==1),
componentName = "PBC_4")
ol_settings3 = list(outcomeOrdered = SN4,
V = zeta_SN_4*LV_2,
tau = list(tau_SN4_1, tau_SN4_2, tau_SN4_3, tau_SN4_4),
rows = (Task==1),
componentName = "SN_4")
ol_settings4 = list(outcomeOrdered = SN5,
V = zeta_SN_5*LV_2,
tau = list(tau_SN5_1, tau_SN5_2, tau_SN5_3, tau_SN5_4),
rows = (Task==1),
componentName = "SN_5")
ol_settings5 = list(outcomeOrdered = EC1,
V = zeta_EC_1*LV_3,
tau = list(tau_EC1_1, tau_EC1_2,tau_EC1_3,tau_EC1_4 ),
rows = (Task==1),
componentName = "EC_1")
ol_settings6 = list(outcomeOrdered = EC2,
V = zeta_EC_2*LV_3,
tau = list(tau_EC2_1, tau_EC2_2, tau_EC2_3, tau_EC2_4),
rows = (Task==1),
componentName = "EC_2")
ol_settings7 = list(outcomeOrdered = EC3,
V = zeta_EC_3*LV_3,
tau = list(tau_EC3_1, tau_EC3_2,tau_EC3_3,tau_EC3_4),
rows = (Task==1),
componentName = "EC_3")
ol_settings8 = list(outcomeOrdered = ATB1,
V = zeta_ATB_1*LV_4,
tau = list(tau_ATB1_1, tau_ATB1_2,tau_ATB1_3,tau_ATB1_4 ),
rows = (Task==1),
componentName = "ATB_1")
ol_settings9 = list(outcomeOrdered = ATB2,
V = zeta_ATB_2*LV_4,
tau = list(tau_ATB2_1, tau_ATB2_2, tau_ATB2_3, tau_ATB2_4),
rows = (Task==1),
componentName = "ATB_2")
ol_settings10 = list(outcomeOrdered = ATB3,
V = zeta_ATB_3*LV_4,
tau = list(tau_ATB3_1, tau_ATB3_2,tau_ATB3_3,tau_ATB3_4),
rows = (Task==1),
componentName = "ATB_3")


P[["PBC_2"]] = apollo_ol(ol_settings1, functionality)
P[["PBC_4"]] = apollo_ol(ol_settings2, functionality)
P[["SN_4"]] = apollo_ol(ol_settings3, functionality)
P[["SN_5"]] = apollo_ol(ol_settings4, functionality)
P[["EC_1"]] = apollo_ol(ol_settings5, functionality)
P[["EC_2"]] = apollo_ol(ol_settings6, functionality)
P[["EC_3"]] = apollo_ol(ol_settings7, functionality)
P[["ATB_1"]] = apollo_ol(ol_settings8, functionality)
P[["ATB_2"]] = apollo_ol(ol_settings9, functionality)
P[["ATB_3"]] = apollo_ol(ol_settings10, functionality)

### Likelihood of choices
### List of utilities: these must use the same names as in mnl_settings, order is irrelevant, since the forst two frugs are branded and the rest two are generic
V = list()
V[['Option_1']] = ASC_1+ b_dist * Distance_1 +b_resv * Reservation_1 + b_cost * Price_1 + b_cpeed * Charging_Speed_1

V[['Option_2']] =ASC_2+ b_dist * Distance_2 +b_resv * Reservation_2 + b_cost * Price_2 + b_cpeed * Charging_Speed_2 +
lambda*LV_1 +lambda*LV_2+lambda*LV_3 +lambda*LV_4

V[['Option_3']] =ASC_3+ b_dist *Distance_3 +b_resv * Reservation_3 + b_cost * Price_3 + b_cpeed * Charging_Speed_3 +
lambda*LV_1 +lambda*LV_2+lambda*LV_3 +lambda*LV_4

### Define settings for MNL model component
mnl_settings = list(
alternatives = c(Option_1=1, Option_2=2, Option_3=3),
avail = 1,
choiceVar = Response,
V = V
)

### Compute probabilities for MNL model component
P[["choice"]] = apollo_mnl(mnl_settings, functionality)

### Likelihood of the whole model
P = apollo_combineModels(P, apollo_inputs, functionality)

### Take product across observation for same individual
P = apollo_panelProd(P, apollo_inputs, functionality)

### Average across inter-individual draws
P = apollo_avgInterDraws(P, apollo_inputs, functionality)

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

# ################################################################# #
#### MODEL ESTIMATION ####
# ################################################################# #

### Optional: calculate LL before model estimation
apollo_llCalc(apollo_beta, apollo_probabilities, apollo_inputs)

### Estimate model
HCM_model16 = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs)

# ################################################################# #
#### MODEL OUTPUTS ####
# ################################################################# #

# ----------------------------------------------------------------- #
#---- FORMATTED OUTPUT (TO SCREEN) ----
# ----------------------------------------------------------------- #

apollo_modelOutput(HCM_model16,modelOutput_settings=list(printPVal=1))

################################################################

################################################################
# ----------------------------------------------------------------- #
#---- FORMATTED OUTPUT (TO FILE, using model name) ----
# ----------------------------------------------------------------- #

apollo_saveOutput(HCM_model16,saveOutput_settings=list(printPVal=1))

# ################################################################# #
##### POST-PROCESSING ####
# ################################################################# #

### Print outputs of additional diagnostics to new output file (remember to close file writing when complete)
apollo_sink()

# ----------------------------------------------------------------- #
#---- MODEL PREDICTIONS ----
# ----------------------------------------------------------------- #

forecast <- apollo_prediction(model, apollo_probabilities, apollo_inputs,
prediction_settings=list(modelComponent="indic_quality"))

# ----------------------------------------------------------------- #
#---- CONDITIONALS AND UNCONDITIONALS ----
# ----------------------------------------------------------------- #

conditionals <- apollo_conditionals(model,apollo_probabilities,apollo_inputs)

summary(conditionals)

unconditionals <- apollo_unconditionals(model,apollo_probabilities,apollo_inputs)

mean(unconditionals[[1]])
sd(unconditionals[[1]])

# ----------------------------------------------------------------- #
#---- switch off writing to file ----
# ----------------------------------------------------------------- #

apollo_sink()

Re: HCM with Ordered Logit

Posted: 12 May 2022, 16:03
by stephanehess
Hi

this question is really not related to Apollo but to hybrid choice theory and is addressed in many of the papers on that topic. So it's not really for this forum

Stephane