Page 1 of 1

Latent Variable Models and Best-Worst Scaling

Posted: 20 Sep 2022, 16:16
by ksmith
Hi all,

I have more of a conceptual question (and I am a social psychologist so please excuse if its kinda simplistic!). I have been working with a BWS dataset and am interested in explicitly modeling the effect of latent psychological factors on choice. So far I have run this as a simple BWS exercise and then as a HCM with the inclusion of a latent attitude construct variable (and have coded their 'best' response as singular choice). I hope to make the next step to be a BWS model that incorporates the attitude LV, but I am hestiant because I am unsure conceptually how to operationalize the LV in the context of best and worst choices (ie how latent attitude "trust" effects both their 'best' choice and then effects the 'worst' choice -- I would expect that the effects would be highly correlated, but not totally). Would you be able to point me in the right direction about this?

Re: Latent Variable Models and Best-Worst Scaling

Posted: 25 Sep 2022, 02:56
by stephanehess
Hi

one option would be to use separate parameters for the impact on best and worst and see if they differ in their absolute values

Stephane

Re: Latent Variable Models and Best-Worst Scaling

Posted: 27 Sep 2022, 21:05
by ksmith
Hi Stephane -- Thanks for your insight. From my initial analysis the coefficient estimates for separate parameters (one for best and one for worst) have very similar absolute values. To clarify, the dataset I am working with is Case 1 BWS -- is it reasonable to assume that it can still be modeled using MNL? I am happy to provide additional info/data/code if that is helpful. Thanks again

Re: Latent Variable Models and Best-Worst Scaling

Posted: 28 Sep 2022, 08:57
by stephanehess
You probably want to have a look at a simultaneous model to avoid having to make assumptions about whether best or worst is chosen first. See http://apollochoicemodelling.com/files/ ... ltaneous.r

Re: Latent Variable Models and Best-Worst Scaling

Posted: 01 Oct 2022, 16:23
by ksmith
Thanks for the recommendation. Is it still possible to include a latent variable component in a simultaneous BWS model? When I augment and run the code I get the error: Parameters zeta_mgmtsatisfaction, zeta_trust, sigma_trust, sigma_mgmtsatisfaction (trust and mgmt_satisfaction are the latent attitudes included in the model) do not influence the log-likelihood of your model!

Thanks for your ongoing insight it has been a huge help.

Code below:

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

#Indicator P
normalDensity_settings2 = list(outcomeNormal = attitude_mgmtsatisfaction,
xNormal = zeta_mgmtsatisfaction*LV,
mu = 0,
sigma = sigma_mgmtsatisfaction,
rows = (Q==1),
componentName = "indic_mgmtsatisfaction")
normalDensity_settings3 = list(outcomeNormal = attitude_trust,
xNormal = zeta_trust*LV,
mu = 0,
sigma = sigma_trust,
rows = (Q==1),
componentName = "indic_trust")


P[["indic_mgmtsatisfaction"]] = apollo_normalDensity(normalDensity_settings2, functionality)
P[["indic_trust"]] = apollo_normalDensity(normalDensity_settings3, functionality)


### Likelihood of choices -- because of how the analysis was done, the alts look a little funky

V = list()
V[["alt1"]] = (b_obj_Communication*Communication.1 + b_obj_Communication*Communication.2 +
b_obj_Communication*Communication.3 + lambda*LV) #for model testing just including on 1 var
V[["alt2"]] = (b_obj_Satisfaction*Satisfaction.1 + b_obj_Satisfaction*Satisfaction.2 +
b_obj_Satisfaction*Satisfaction.1)
V[["alt3"]] = (b_obj_Inform*Inform.1 +b_obj_Inform*Inform.2 +b_obj_Inform*Inform.3)

V[["alt4"]] = (b_obj_Health*Health.1 +b_obj_Health*Health.2 +b_obj_Health*Health.3)

V[["alt5"]] = b_obj_Habitat*Habitat.1 +b_obj_Habitat*Habitat.2 +b_obj_Habitat*Habitat.3

V[["alt6"]] = (b_obj_Impact *Impact.1) + (b_obj_Impact *Impact.2) +(b_obj_Impact *Impact.3)

V[["alt7"]] = b_obj_Cost*Cost.1+ b_obj_Cost*Cost.2+ b_obj_Cost*Cost.3


### Define settings for MNL model component
mnl_settings_best = list(
alternatives = c(alt1=1, alt2=2, alt3=3, alt4=4, alt5=5, alt6=6, alt7=7),
avail = list(alt1=1, alt2=1, alt3=1, alt4=1, alt5=1, alt6=1, alt7=1),
choiceVar = bestfull,
utilities = V,
componentName = "choice"
)
### Compute probabilities for MNL model component
P[["choice_best"]] = apollo_mnl(mnl_settings_best, functionality)


### Compute probabilities for "worst" choice using MNL model
mnl_settings = list(
alternatives = c(alt_b1_w2=12,
alt_b1_w3=13,
alt_b1_w4=14,
alt_b1_w5=15,
alt_b1_w6=16,
alt_b1_w7=17,
alt_b2_w1=21,
alt_b2_w3=23,
alt_b2_w4=24,
alt_b2_w5=25,
alt_b2_w6=26,
alt_b2_w7=27,
alt_b3_w1=31,
alt_b3_w2=32,
alt_b3_w4=34,
alt_b3_w5=35,
alt_b3_w6=36,
alt_b3_w7=37,
alt_b4_w1=41,
alt_b4_w2=42,
alt_b4_w3=43,
alt_b4_w5=45,
alt_b4_w6=46,
alt_b4_w7=47,
alt_b5_w1=51,
alt_b5_w2=52,
alt_b5_w3=53,
alt_b5_w4=54,
alt_b5_w6=56,
alt_b5_w7=57,
alt_b6_w1=61,
alt_b6_w2=62,
alt_b6_w3=63,
alt_b6_w4=64,
alt_b6_w5=65,
alt_b6_w7=67,
alt_b7_w1=71,
alt_b7_w2=72,
alt_b7_w3=73,
alt_b7_w4=74,
alt_b7_w5=75,
alt_b7_w6=76),
choiceVar = 10*bestfull+worstfull,
utilities = list(alt_b1_w2=V[["alt1"]]-mu_worst*V[["alt2"]], #because its estimating likelihood of choosing Best Alt 1 and W Alt 2, is there where
alt_b1_w3=V[["alt1"]]-mu_worst*V[["alt3"]], #there are issues with the inclusion of a latent variable?
alt_b1_w4=V[["alt1"]]-mu_worst*V[["alt4"]],
alt_b1_w5=V[["alt1"]]-mu_worst*V[["alt5"]],
alt_b1_w6=V[["alt1"]]-mu_worst*V[["alt6"]],
alt_b1_w7=V[["alt1"]]-mu_worst*V[["alt7"]],
alt_b2_w1=V[["alt2"]]-mu_worst*V[["alt1"]],
alt_b2_w3=V[["alt2"]]-mu_worst*V[["alt3"]],
alt_b2_w4=V[["alt2"]]-mu_worst*V[["alt4"]],
alt_b2_w5=V[["alt2"]]-mu_worst*V[["alt5"]],
alt_b2_w6=V[["alt2"]]-mu_worst*V[["alt6"]],
alt_b2_w7=V[["alt2"]]-mu_worst*V[["alt7"]],
alt_b3_w1=V[["alt3"]]-mu_worst*V[["alt1"]],
alt_b3_w2=V[["alt3"]]-mu_worst*V[["alt2"]],
alt_b3_w4=V[["alt3"]]-mu_worst*V[["alt4"]],
alt_b3_w5=V[["alt3"]]-mu_worst*V[["alt5"]],
alt_b3_w6=V[["alt3"]]-mu_worst*V[["alt6"]],
alt_b3_w7=V[["alt3"]]-mu_worst*V[["alt7"]],
alt_b4_w1=V[["alt4"]]-mu_worst*V[["alt1"]],
alt_b4_w2=V[["alt4"]]-mu_worst*V[["alt2"]],
alt_b4_w3=V[["alt4"]]-mu_worst*V[["alt3"]],
alt_b4_w5=V[["alt4"]]-mu_worst*V[["alt5"]],
alt_b4_w6=V[["alt4"]]-mu_worst*V[["alt6"]],
alt_b4_w7=V[["alt4"]]-mu_worst*V[["alt7"]],
alt_b5_w1=V[["alt5"]]-mu_worst*V[["alt1"]],
alt_b5_w2=V[["alt5"]]-mu_worst*V[["alt2"]],
alt_b5_w3=V[["alt5"]]-mu_worst*V[["alt3"]],
alt_b5_w4=V[["alt5"]]-mu_worst*V[["alt4"]],
alt_b5_w6=V[["alt5"]]-mu_worst*V[["alt6"]],
alt_b5_w7=V[["alt5"]]-mu_worst*V[["alt7"]],
alt_b6_w1=V[["alt6"]]-mu_worst*V[["alt1"]],
alt_b6_w2=V[["alt6"]]-mu_worst*V[["alt2"]],
alt_b6_w3=V[["alt6"]]-mu_worst*V[["alt3"]],
alt_b6_w4=V[["alt6"]]-mu_worst*V[["alt4"]],
alt_b6_w5=V[["alt6"]]-mu_worst*V[["alt5"]],
alt_b6_w7=V[["alt6"]]-mu_worst*V[["alt7"]],
alt_b7_w1=V[["alt7"]]-mu_worst*V[["alt1"]],
alt_b7_w2=V[["alt7"]]-mu_worst*V[["alt2"]],
alt_b7_w3=V[["alt7"]]-mu_worst*V[["alt3"]],
alt_b7_w4=V[["alt7"]]-mu_worst*V[["alt4"]],
alt_b7_w5=V[["alt7"]]-mu_worst*V[["alt5"]],
alt_b7_w6=V[["alt7"]]-mu_worst*V[["alt6"]] )
)

#I am assuming this is where I am running into issues
P[["model"]] = apollo_mnl(mnl_settings, 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)

}

Re: Latent Variable Models and Best-Worst Scaling

Posted: 04 Oct 2022, 12:29
by stephanehess
I've made some changes to your model below. Does that help? You were not including the latent variable measurement model as you didn't use apollo_combineModels. You also don't need the mnl for best choice only (this was also wrong in the online example, fixed it last week).

Code: Select all

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

#Indicator P
normalDensity_settings2 = list(outcomeNormal = attitude_mgmtsatisfaction,
xNormal = zeta_mgmtsatisfaction*LV,
mu = 0,
sigma = sigma_mgmtsatisfaction,
rows = (Q==1),
componentName = "indic_mgmtsatisfaction")
normalDensity_settings3 = list(outcomeNormal = attitude_trust,
xNormal = zeta_trust*LV,
mu = 0,
sigma = sigma_trust,
rows = (Q==1),
componentName = "indic_trust")


P[["indic_mgmtsatisfaction"]] = apollo_normalDensity(normalDensity_settings2, functionality)
P[["indic_trust"]] = apollo_normalDensity(normalDensity_settings3, functionality)


### Likelihood of choices -- because of how the analysis was done, the alts look a little funky

V = list()
V[["alt1"]] = (b_obj_Communication*Communication.1 + b_obj_Communication*Communication.2 +
b_obj_Communication*Communication.3 + lambda*LV) #for model testing just including on 1 var
V[["alt2"]] = (b_obj_Satisfaction*Satisfaction.1 + b_obj_Satisfaction*Satisfaction.2 +
b_obj_Satisfaction*Satisfaction.1)
V[["alt3"]] = (b_obj_Inform*Inform.1 +b_obj_Inform*Inform.2 +b_obj_Inform*Inform.3)

V[["alt4"]] = (b_obj_Health*Health.1 +b_obj_Health*Health.2 +b_obj_Health*Health.3)

V[["alt5"]] = b_obj_Habitat*Habitat.1 +b_obj_Habitat*Habitat.2 +b_obj_Habitat*Habitat.3

V[["alt6"]] = (b_obj_Impact *Impact.1) + (b_obj_Impact *Impact.2) +(b_obj_Impact *Impact.3)

V[["alt7"]] = b_obj_Cost*Cost.1+ b_obj_Cost*Cost.2+ b_obj_Cost*Cost.3



### Compute probabilities for "worst" choice using MNL model
mnl_settings = list(
alternatives = c(alt_b1_w2=12,
alt_b1_w3=13,
alt_b1_w4=14,
alt_b1_w5=15,
alt_b1_w6=16,
alt_b1_w7=17,
alt_b2_w1=21,
alt_b2_w3=23,
alt_b2_w4=24,
alt_b2_w5=25,
alt_b2_w6=26,
alt_b2_w7=27,
alt_b3_w1=31,
alt_b3_w2=32,
alt_b3_w4=34,
alt_b3_w5=35,
alt_b3_w6=36,
alt_b3_w7=37,
alt_b4_w1=41,
alt_b4_w2=42,
alt_b4_w3=43,
alt_b4_w5=45,
alt_b4_w6=46,
alt_b4_w7=47,
alt_b5_w1=51,
alt_b5_w2=52,
alt_b5_w3=53,
alt_b5_w4=54,
alt_b5_w6=56,
alt_b5_w7=57,
alt_b6_w1=61,
alt_b6_w2=62,
alt_b6_w3=63,
alt_b6_w4=64,
alt_b6_w5=65,
alt_b6_w7=67,
alt_b7_w1=71,
alt_b7_w2=72,
alt_b7_w3=73,
alt_b7_w4=74,
alt_b7_w5=75,
alt_b7_w6=76),
choiceVar = 10*bestfull+worstfull,
utilities = list(alt_b1_w2=V[["alt1"]]-mu_worst*V[["alt2"]], #because its estimating likelihood of choosing Best Alt 1 and W Alt 2, is there where
alt_b1_w3=V[["alt1"]]-mu_worst*V[["alt3"]], #there are issues with the inclusion of a latent variable?
alt_b1_w4=V[["alt1"]]-mu_worst*V[["alt4"]],
alt_b1_w5=V[["alt1"]]-mu_worst*V[["alt5"]],
alt_b1_w6=V[["alt1"]]-mu_worst*V[["alt6"]],
alt_b1_w7=V[["alt1"]]-mu_worst*V[["alt7"]],
alt_b2_w1=V[["alt2"]]-mu_worst*V[["alt1"]],
alt_b2_w3=V[["alt2"]]-mu_worst*V[["alt3"]],
alt_b2_w4=V[["alt2"]]-mu_worst*V[["alt4"]],
alt_b2_w5=V[["alt2"]]-mu_worst*V[["alt5"]],
alt_b2_w6=V[["alt2"]]-mu_worst*V[["alt6"]],
alt_b2_w7=V[["alt2"]]-mu_worst*V[["alt7"]],
alt_b3_w1=V[["alt3"]]-mu_worst*V[["alt1"]],
alt_b3_w2=V[["alt3"]]-mu_worst*V[["alt2"]],
alt_b3_w4=V[["alt3"]]-mu_worst*V[["alt4"]],
alt_b3_w5=V[["alt3"]]-mu_worst*V[["alt5"]],
alt_b3_w6=V[["alt3"]]-mu_worst*V[["alt6"]],
alt_b3_w7=V[["alt3"]]-mu_worst*V[["alt7"]],
alt_b4_w1=V[["alt4"]]-mu_worst*V[["alt1"]],
alt_b4_w2=V[["alt4"]]-mu_worst*V[["alt2"]],
alt_b4_w3=V[["alt4"]]-mu_worst*V[["alt3"]],
alt_b4_w5=V[["alt4"]]-mu_worst*V[["alt5"]],
alt_b4_w6=V[["alt4"]]-mu_worst*V[["alt6"]],
alt_b4_w7=V[["alt4"]]-mu_worst*V[["alt7"]],
alt_b5_w1=V[["alt5"]]-mu_worst*V[["alt1"]],
alt_b5_w2=V[["alt5"]]-mu_worst*V[["alt2"]],
alt_b5_w3=V[["alt5"]]-mu_worst*V[["alt3"]],
alt_b5_w4=V[["alt5"]]-mu_worst*V[["alt4"]],
alt_b5_w6=V[["alt5"]]-mu_worst*V[["alt6"]],
alt_b5_w7=V[["alt5"]]-mu_worst*V[["alt7"]],
alt_b6_w1=V[["alt6"]]-mu_worst*V[["alt1"]],
alt_b6_w2=V[["alt6"]]-mu_worst*V[["alt2"]],
alt_b6_w3=V[["alt6"]]-mu_worst*V[["alt3"]],
alt_b6_w4=V[["alt6"]]-mu_worst*V[["alt4"]],
alt_b6_w5=V[["alt6"]]-mu_worst*V[["alt5"]],
alt_b6_w7=V[["alt6"]]-mu_worst*V[["alt7"]],
alt_b7_w1=V[["alt7"]]-mu_worst*V[["alt1"]],
alt_b7_w2=V[["alt7"]]-mu_worst*V[["alt2"]],
alt_b7_w3=V[["alt7"]]-mu_worst*V[["alt3"]],
alt_b7_w4=V[["alt7"]]-mu_worst*V[["alt4"]],
alt_b7_w5=V[["alt7"]]-mu_worst*V[["alt5"]],
alt_b7_w6=V[["alt7"]]-mu_worst*V[["alt6"]] )
)

#I am assuming this is where I am running into issues
P[["bw"]] = apollo_mnl(mnl_settings, functionality)

### Combine models
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)

}