Efficient design with interaction in contextual variables

This forum is for posts that specifically focus on Ngene.

Moderators: Andrew Collins, Michiel Bliemer, johnr

Efficient design with interaction in contextual variables

Postby Xin Dou » Fri Apr 26, 2024 4:45 pm

Dear Ngene team,

I want to conduct an efficient design with interaction between contextual variables and alternative specific variables.

I get some questions about pilot survey.

(1) Which one is better? Use orthogonal design or efficient design with 0 for prior parameter.
(2) Can orthogonal design be used to design interactions between environmental variables and alternative-specific variables?
(3) Here is the code for efficient design with 0 prior parameter. I want to confirm if the code can be used for the pilot survey.
Code: Select all
Design
;alts = altA, altB
;rows = 64
;eff = (mnl, d)
;block = 8
;model:
U(altA) = b1[0] +
          b_tp.dummy[0|0|0]   *  tp[1,2,3,4] +
          b_otc.dummy[0|0|0]  * otc[30,60,90,120] +
          b_occ.dummy[0]      * occ[1,2] +
          b_fc.dummy[0|0|0]   *  fc[0,1,2,3] +

          b_atc.dummy[0|0|0]  * atc[-15,-5,5,15] +
          b_acc.dummy[0|0|0]  * acc[-23,-8,8,23] +
          b_am.dummy[0|0|0]  *  am[0.75,1,1.25,1.5] +

          iat1[0] * otc.dummy[30] *  atc.dummy[-15] +
          iat2[0] * otc.dummy[30] *  atc.dummy[-5] +
          iat3[0] * otc.dummy[30] *  atc.dummy[5] +


          iat4[0] * otc.dummy[60] *  atc.dummy[-15] +
          iat5[0] * otc.dummy[60] *  atc.dummy[-5] +
          iat6[0] * otc.dummy[60] *  atc.dummy[5] +

          iat7[0] * otc.dummy[90] *  atc.dummy[-15] +
          iat8[0] * otc.dummy[90] *  atc.dummy[-5] +
          iat9[0] * otc.dummy[90] *  atc.dummy[5] +


          iac1[0] * occ.dummy[1] *  acc.dummy[-23] +
          iac2[0] * occ.dummy[1] *  acc.dummy[-8] +
          iac3[0] * occ.dummy[1] *  acc.dummy[8]


 /

U(altB) = 
          b_btc.dummy[0|0|0]  * btc[-15,-5,5,15] +
          b_bcc.dummy[0|0|0]  * bcc[-23,-8,8,23] +

          ibt1[0] * otc[otc][30] *  btc.dummy[-15] +
          ibt2[0] * otc[otc][30] *  btc.dummy[-5] +
          ibt3[0] * otc[otc][30] *  btc.dummy[5] +

          ibt4[0] * otc[otc][60] *  btc.dummy[-15] +
          ibt5[0] * otc[otc][60] *  btc.dummy[-5] +
          ibt6[0] * otc[otc][60] *  btc.dummy[5] +

          ibt7[0] * otc[otc][90] *  btc.dummy[-15] +
          ibt8[0] * otc[otc][90] *  btc.dummy[-5] +
          ibt9[0] * otc[otc][90] *  btc.dummy[5] +

          ibc1[0] * occ[occ][1] *  bcc.dummy[-23] +
          ibc2[0] * occ[occ][1] *  bcc.dummy[-8] +
          ibc3[0] * occ[occ][1] *  bcc.dummy[8]


$

Looking forward to your reply.
Best regards,
Xin Dou
Xin Dou
 
Posts: 2
Joined: Fri Apr 26, 2024 11:51 am

Re: Efficient design with interaction in contextual variable

Postby Michiel Bliemer » Sat Apr 27, 2024 11:06 pm

Orthogonal designs are good if no other constraints need to be imposed on the design, but it may be challenging to find an orthogonal design that works with so many interaction effects. An efficient design has a lot more flexibility in imposing constraints and interaction effects, so in your case an efficient design with zero priors would likely be preferred.

I doubt that it is possible to generate a design that is orthogonal in both main and interaction effects. But you can generate a design that is orthogonal in the main effects, plus the scenario variable. Then you would simply need to verify that the interaction effects are not perfectly correlated. First, you generate an orthogonal design for the main effects only, including the scenario variable in one of the alternatives. You can do that using Script 1 below. Then you can copy and paste the design in Excel, copy the column for the scenario variable also in the other alternative, and manually add columns that represent the required interactions. Finally, you let Excel compute the correlation matrix. If there are no perfect correlations then you can use that orthogonal design.

Script 1:
Code: Select all
Design
;alts = altA, altB
;rows = 64
;orth = sim
;block = 8
;model:
U(altA) = b1[0] +
          b_tp.dummy[0|0|0]   *  tp[1,2,3,4] +
          b_otc.dummy[0|0|0]  * otc[30,60,90,120] +
          b_occ.dummy[0]      * occ[1,2] +
          b_fc.dummy[0|0|0]   *  fc[0,1,2,3] +
          b_atc.dummy[0|0|0]  * atc[-15,-5,5,15] +
          b_acc.dummy[0|0|0]  * acc[-23,-8,8,23] +
          b_am.dummy[0|0|0]  *  am[0.75,1,1.25,1.5]
 /
U(altB) =
          b_btc.dummy[0|0|0]  * btc[-15,-5,5,15] +
          b_bcc.dummy[0|0|0]  * bcc[-23,-8,8,23]
$


If you would like to generate an efficient design, which will automatically avoid perfect correlations, then you need to modify your script. The syntax otc[otc][30] is not proper, the shortcut otc[otc] cannot be used for categorical variables in interactions, and if it would work it would likely be specified as otc[otc].dummy[30].
Instead, you need to use require constraints to create the scenario variable. In AltB you are including otc and occ only as interaction effect and not as a main effect, and that causes issues because Ngene does not know the levels of otc and occ in altB. There is a workaround, which is not pretty, but it does work, see Script 2. In this script, I define otc and occ in both altA and altB as main effect only in model_a, but I only optimise the design for model_b where otc and occ only appears as an interaction effect in altB. By defining the variable in model_a Ngene now understands the levels for model_b, this is a bit of a 'trick'. Note that you have almost 50 parameters in your model, which is a lot.

Script 2:
Code: Select all
Design
;alts(model_a) = altA, altB
;alts(model_b) = altA, altB
;rows = 64
;eff = model_b(mnl, d)
;alg = mfederov
;require:
alta.otc = altb.otc,
alta.occ = altb.occ
;block = 8
;model(model_a):
U(altA) = b1[0] +
          b_tp.dummy[0|0|0]   *  tp[1,2,3,4] +
          b_otc.dummy[0|0|0]  * otc[30,60,90,120] +
          b_occ.dummy[0]      * occ[1,2] +
          b_fc.dummy[0|0|0]   *  fc[0,1,2,3] +
          b_atc.dummy[0|0|0]  * atc[-15,-5,5,15] +
          b_acc.dummy[0|0|0]  * acc[-23,-8,8,23] +
          b_am.dummy[0|0|0]  *  am[0.75,1,1.25,1.5]
 /
U(altB) =
          b_btc.dummy[0|0|0]  * btc[-15,-5,5,15] +
          b_bcc.dummy[0|0|0]  * bcc[-23,-8,8,23] +
          b_otc.dummy[0|0|0]  * otc[30,60,90,120] +
          b_occ.dummy[0]      * occ[1,2]
;model(model_b):
U(altA) = b1[0] +
          b_tp.dummy[0|0|0]   *  tp[1,2,3,4] +
          b_otc.dummy[0|0|0]  * otc[30,60,90,120] +
          b_occ.dummy[0]      * occ[1,2] +
          b_fc.dummy[0|0|0]   *  fc[0,1,2,3] +
          b_atc.dummy[0|0|0]  * atc[-15,-5,5,15] +
          b_acc.dummy[0|0|0]  * acc[-23,-8,8,23] +
          b_am.dummy[0|0|0]  *  am[0.75,1,1.25,1.5] +
          iat1[0] * otc.dummy[30] *  atc.dummy[-15] +
          iat2[0] * otc.dummy[30] *  atc.dummy[-5] +
          iat3[0] * otc.dummy[30] *  atc.dummy[5] +
          iat4[0] * otc.dummy[60] *  atc.dummy[-15] +
          iat5[0] * otc.dummy[60] *  atc.dummy[-5] +
          iat6[0] * otc.dummy[60] *  atc.dummy[5] +
          iat7[0] * otc.dummy[90] *  atc.dummy[-15] +
          iat8[0] * otc.dummy[90] *  atc.dummy[-5] +
          iat9[0] * otc.dummy[90] *  atc.dummy[5] +
          iac1[0] * occ.dummy[1] *  acc.dummy[-23] +
          iac2[0] * occ.dummy[1] *  acc.dummy[-8] +
          iac3[0] * occ.dummy[1] *  acc.dummy[8]
/
U(altB) =
          b_btc.dummy[0|0|0]  * btc[-15,-5,5,15] +
          b_bcc.dummy[0|0|0]  * bcc[-23,-8,8,23] +
          ibt1[0] * otc.dummy[30] *  btc.dummy[-15] +
          ibt2[0] * otc.dummy[30] *  btc.dummy[-5] +
          ibt3[0] * otc.dummy[30] *  btc.dummy[5] +
          ibt4[0] * otc.dummy[60] *  btc.dummy[-15] +
          ibt5[0] * otc.dummy[60] *  btc.dummy[-5] +
          ibt6[0] * otc.dummy[60] *  btc.dummy[5] +
          ibt7[0] * otc.dummy[90] *  btc.dummy[-15] +
          ibt8[0] * otc.dummy[90] *  btc.dummy[-5] +
          ibt9[0] * otc.dummy[90] *  btc.dummy[5] +
          ibc1[0] * occ.dummy[1] *  bcc.dummy[-23] +
          ibc2[0] * occ.dummy[1] *  bcc.dummy[-8] +
          ibc3[0] * occ.dummy[1] *  bcc.dummy[8]
$


Michiel
Michiel Bliemer
 
Posts: 1885
Joined: Tue Mar 31, 2009 4:13 pm

Re: Efficient design with interaction in contextual variable

Postby Xin Dou » Mon May 06, 2024 5:50 pm

Dear Professer Michiel,

Thank you very much for your suggestions.

I have been running Script 2 for one week. The d-error decrease form 1.78981 to 1.081167 after 2137345 evaluation within first two days. Since then, there have been no further updates on the output.

Does this indicate that the design is now ready for application?

I look forward to your guidance on whether further modifications or tests are necessary.

Best regards,
Xin Dou
Xin Dou
 
Posts: 2
Joined: Fri Apr 26, 2024 11:51 am

Re: Efficient design with interaction in contextual variable

Postby Michiel Bliemer » Tue May 07, 2024 3:39 pm

D-errors are case specific so I cannot say if the D-error is good or bad, but usually Ngene cannot find much better designs anymore after a couple of hours running and then I usually stop and use the found design.

Michiel
Michiel Bliemer
 
Posts: 1885
Joined: Tue Mar 31, 2009 4:13 pm


Return to Choice experiments - Ngene

Who is online

Users browsing this forum: Google [Bot] and 23 guests

cron