Dear Stephane,
I am building Mixed Logit Model allowed the inclusion of latent variables. I am interested in understanding whether the two external treatments influence consumers' preferences for attribute2 therefore the interaction term attribute2 * treatment is included, and how individual socio-demographic characteristics and attitudes impact the effects of these treatments.
Specifically, I draw on Hao et al.'s paper (See Hao, F., Qiu, R. T. R., Park, J., & Chon, K. (2023). The Myth of Contactless Hospitality Service: Customers’ Willingness to Pay. Journal of Hospitality & Tourism Research, 47(8), 1478-1502. https://doi.org/10.1177/10963480221081781), where the preference parameter is specified as a function of latent values, which differs from the approach in the Apollo manual (where personal characteristics and latent variables are directly incorporated into the utility function).
Below is my code, though I am unsure if it achieves my aim. Additionally, after implementing this, I don't how to estimate willingness to pay, can you advise accordingly? Many thanks.
# Mixed logit with latent variable and socio-demographic ###
apollo_beta = c(
asc_a = 0,
asc_b = 0,
asc_c = 0,
mu_log_b_attribute1 = 0,
sigma_log_b_attribute1= 1,
mu_log_b_attribute2 = 0,
sigma_log_b_attribute2 = 1,
mu_log_b_attribute2_treat1 = 0,
sigma_log_b_attribute2_treat1= 1,
mu_log_b_attribute2_treat2 = 0,
sigma_log_b_attribute2_treat2= 1,
mu_log_b_attribute3 = 0,
sigma_log_b_attribute3 = 1,
mu_log_b_price = 0,
sigma_log_b_price = 1,
lambda_attribute1_LV1=0,
lambda_attribute1_LV2=0,
lambda_attribute2_LV1=0,
lambda_attribute2_LV2=0,
lambda_attribute2_treat1_LV1=0,
lambda_attribute2_treat1_LV2=0,
lambda_attribute2_treat2_LV1=0,
lambda_attribute2_treat2_LV2=0,
lambda_attribute3_LV1=0,
lambda_attribute3_LV2=0,
b_gender_LV1 = 0,
b_age_LV1 = 0,
b_edu_2_LV1 = 0,
b_edu_3_LV1 = 0,
b_edu_4_LV1 = 0,
b_gender_ES = 0,
b_age_ES = 0,
b_edu_2_ES = 0,
b_edu_3_ES = 0,
b_edu_4_ES = 0,
zeta_LV1_1 = 0,
zeta_LV1_2 = 0,
zeta_LV1_3 = 0,
zeta_LV1_4 = 0,
zeta_LV2_1 = 0,
zeta_LV2_2 = 0,
zeta_LV2_3 = 0,
zeta_LV2_4 = 0,
sigma_LV1_1 = 1,
sigma_LV1_2 = 1,
sigma_LV1_3 = 1,
sigma_LV1_4 = 1,
sigma_LV2_1 = 1,
sigma_LV2_2 = 1,
sigma_LV2_3 = 1,
sigma_LV2_4 = 1,
)
### 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_a')
apollo_draws = list(
interDrawsType="halton",
interNDraws=100,
interUnifDraws=c(),
interNormDraws=c('eta01','eta02','eta03','eta04',
"eta1", 'eta2'),
intraDrawsType="",
intraNDraws=0,
intraUnifDraws=c(),
intraNormDraws=c()
)
apollo_randCoeff=function(apollo_beta, apollo_inputs){
randcoeff = list()
randcoeff[["LV1"]] =
eta1 +
b_gender_LV1 * gender +
b_age_LV1 * age +
b_edu_2_LV1 * edu_2 +
b_edu_3_LV1 * edu_3 +
b_edu_4_LV1 * edu_4
randcoeff[["LV2"]] =
eta2 +
b_gender_LV2 * gender +
b_age_LV2 * age +
b_edu_2_LV2 * edu_2 +
b_edu_3_LV2 * edu_3 +
b_edu_4_LV2 * edu_4
randcoeff[["attribute1coef"]]=mu_log_b_attribute1 + sigma_log_b_attribute1 * eta01
randcoeff[["attribute2coef"]]=mu_log_b_attribute2 + sigma_log_b_attribute2 * eta02
randcoeff[["attribute2coef_treat1"]]=mu_log_b_attribute2_treat1 + sigma_log_b_attribute2_treat1 * eta02
randcoeff[["attribute2coef_treat2"]]=mu_log_b_attribute2_treat2 + sigma_log_b_attribute2_treat2 * eta02
randcoeff[["attribute3coef"]]=mu_log_b_attribute3 + sigma_log_b_attribute3 * eta03
randcoeff[["pricecoef"]]=-exp(mu_log_b_price + sigma_log_b_price * eta04)
return(randcoeff)
}
# ################################################################# #
#### GROUP AND VALIDATE INPUTS ####
# ################################################################# #
apollo_inputs = apollo_validateInputs()
# ################################################################# #
#### DEFINE MODEL AND LIKELIHOOD FUNCTION ####
# ################################################################# #
apollo_probabilities=function(apollo_beta, apollo_inputs, functionality="estimate"){
apollo_attach(apollo_beta, apollo_inputs)
on.exit(apollo_detach(apollo_beta, apollo_inputs))
P = list()
normalDensity_settings1 = list(
outcomeNormal = LV1_1,
xNormal = zeta_LV1_1 * LV1,
mu = 0,
sigma = sigma_LV1_1,
componentName = "indic_LV1_1")
normalDensity_settings2 = list(
outcomeNormal = LV1_2,
xNormal = zeta_LV1_2 * LV1,
mu = 0,
sigma = sigma_LV1_2,
componentName = "indic_LV1_2")
normalDensity_settings3 = list(
outcomeNormal = LV1_3,
xNormal = zeta_LV1_3 * LV1,
mu = 0,
sigma = sigma_LV1_3,
componentName = "indic_LV1_3")
normalDensity_settings4 = list(
outcomeNormal = LV1_4,
xNormal = zeta_LV1_4 * LV1,
mu = 0,
sigma = sigma_LV1_4,
componentName = "indic_LV1_4")
normalDensity_settings21 = list(
outcomeNormal = LV2_1,
xNormal = zeta_LV2_1 * LV2,
mu = 0,
sigma = sigma_LV2_1,
componentName = "indic_LV2_1")
normalDensity_settings22 = list(
outcomeNormal = LV2_2,
xNormal = zeta_LV2_2 * LV2,
mu = 0,
sigma = sigma_LV2_2,
componentName = "indic_LV2_2")
normalDensity_settings23 = list(
outcomeNormal = LV2_3,
xNormal = zeta_LV2_3 * LV2,
mu = 0,
sigma = sigma_LV2_3,
componentName = "indic_LV2_3")
normalDensity_settings24 = list(
outcomeNormal = LV2_4,
xNormal = zeta_LV2_4 * LV2,
mu = 0,
sigma = sigma_LV2_4,
componentName = "indic_LV2_4")
P[["indic_LV1_1"]] = apollo_normalDensity(normalDensity_settings1, functionality)
P[["indic_LV1_2"]] = apollo_normalDensity(normalDensity_settings2, functionality)
P[["indic_LV1_3"]] = apollo_normalDensity(normalDensity_settings3, functionality)
P[["indic_LV1_4"]] = apollo_normalDensity(normalDensity_settings4, functionality)
P[["indic_LV2_1"]] = apollo_normalDensity(normalDensity_settings21, functionality)
P[["indic_LV2_2"]] = apollo_normalDensity(normalDensity_settings22, functionality)
P[["indic_LV2_3"]] = apollo_normalDensity(normalDensity_settings23, functionality)
P[["indic_LV2_4"]] = apollo_normalDensity(normalDensity_settings24, functionality)
attribute1coefLV = attribute1coef + lambda_attribute1_LV1 * LV1 + lambda_attribute1_LV2 * LV2
attribute2coefLV = attribute2coef + lambda_attribute2_LV1 * LV1 + lambda_attribute2_LV2 * LV2
attribute3coefLV = attribute3coef + lambda_attribute3_LV1 * LV1 + lambda_attribute3_LV2 * LV2
attribute2coef_treat1LV = attribute2coef_treat1 + lambda_attribute2_treat1_LV1 * LV1 + lambda_attribute2_treat1_LV2 * LV2
attribute2coef_treat2LV = attribute2coef_treat2 + lambda_attribute2_treat2_LV1 * LV1 + lambda_attribute2_treat2_LV2 * LV2
V = list()
V[['a']] = asc_a +
attribute2coefLV * attribute2A +
attribute2coef_treat1LV * attribute2A * treatment1+
attribute2coef_treat2LV * attribute2A * treatment2+
attribute1coefLV * attribute1A +
attribute3coefLV * attribute3A +
pricecoef * priceA
V[['b']] = asc_b +
attribute2coefLV * attribute2B+
attribute2coef_treat1LV * attribute2B * treatment1 +
attribute2coef_treat2LV * attribute2B * treatment2 +
attribute1coefLV * attribute1B +
attribute3coefLV * attribute3B +
pricecoef * priceB
V[['c']] = asc_c +
attribute2coefLV * attribute2C+
attribute2coef_treat1LV * attribute2C * treatment1 +
attribute2coef_treat2LV * attribute2C * treatment2 +
attribute1coefLV * attribute1C +
attribute3coefLV * attribute3C +
pricecoef * priceC
mnl_settings = list(
alternatives = c(a = 'a', b = 'b', c = 'c'),
# avail = list(Q1=1, N2=1, Q3=1),
choiceVar = choice,
utilities = V,
componentName = "choice"
)
### 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 = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs,
estimate_settings = list(estimationRoutine = "bfgs",
maxIterations = 1000))
Important: Read this before posting to this forum
- 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.
- 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
- Before asking a question on the forum, users are kindly requested to follow these steps:
- Check that the same issue has not already been addressed in the forum - there is a search tool.
- 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
- Check the frequently asked questions section on the Apollo website, which discusses some common issues/failures. Please see http://www.apollochoicemodelling.com/faq.html
- Make sure that R is using the latest official release of Apollo.
- Users can check which version they are running by entering packageVersion("apollo").
- Then check what is the latest full release (not development version) at http://www.ApolloChoiceModelling.com/code.html.
- To update to the latest official version, just enter install.packages("apollo"). To update to a development version, download the appropriate binary file from http://www.ApolloChoiceModelling.com/code.html, and install the package from file
- If the above steps do not resolve the issue, then users should follow these steps when posting a question:
- provide full details on the issue, including the entire code and output, including any error messages
- 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.
Mixed logit with latent variable and socio-demographic
-
stephanehess
- Site Admin
- Posts: 1355
- Joined: 24 Apr 2020, 16:29
Re: Mixed logit with latent variable and socio-demographic
Hi
in the online examples, we interact the LVs with the ASCs. It's the same principle as interacting them with betas that multiply attributes.
You can then either do that inside apollo_randCoeff, e.g.
randCoeff[["beta"]] = mu_beta + sigma_beta * draws_beta + tau_beta_LV1 * randcoeff[["LV1"]]
or inside apollo_probabilities. The above is probably easier.
Note that in my example above, I also have independent random heterogeneity to ensure that the model does not misassociate the impact of the LV. Have a look at https://www.sciencedirect.com/science/a ... 452030049X
Also, in your code, you refer to eta1 in the LV when that is not defined anywhere. I assume you mean eta01. But in the coefficients, you should then include the entire LV, not just the random part eta
Stephane
in the online examples, we interact the LVs with the ASCs. It's the same principle as interacting them with betas that multiply attributes.
You can then either do that inside apollo_randCoeff, e.g.
randCoeff[["beta"]] = mu_beta + sigma_beta * draws_beta + tau_beta_LV1 * randcoeff[["LV1"]]
or inside apollo_probabilities. The above is probably easier.
Note that in my example above, I also have independent random heterogeneity to ensure that the model does not misassociate the impact of the LV. Have a look at https://www.sciencedirect.com/science/a ... 452030049X
Also, in your code, you refer to eta1 in the LV when that is not defined anywhere. I assume you mean eta01. But in the coefficients, you should then include the entire LV, not just the random part eta
Stephane