Heterogenous pivot design around multiple ref alts.

This forum is for posts that specifically focus on the Windows desktop version of Ngene (i.e. all version 1.x releases).

Moderators: Andrew Collins, Michiel Bliemer, johnr

Heterogenous pivot design around multiple ref alts.

Postby nayeem » Thu May 22, 2025 4:18 am

I am designing a labelled choice experiment to estimate WTP for more reliable freight transport along a particular corridor. There are three labelled alternatives:
    Normal Road Transport
    Normal Intermodal Transport
    High speed Intermodal Transport
The different attributes are:
    Transport Cost
    Transport time (origin to destination)
    Travel time reliability (mean-variance method)
    Frequency (for intermodal transport only)
    Safety (for road transport only)-categorical variable
My questions are:
1. In the Ngene manual (last updated on Feb 24, 2025), script 9.6 shows an efficient design pivoted around multiple sets of reference alternatives but where the reference alternative is shown in each case. I want a pivot design optimized around multiple sets of reference levels with the assumption that reference alternative is not shown in each design. How can this be done in Ngene?
2. For this type of experimental design (pivoted around multiple sets of reference alternatives), are there any challenges involved in estimating a single model based on choice data coming from difference classes of respondents?
3. Since I am using 3 labelled alternatives, I am already using 2 ASC constants in my utility equations. Do I need to specify another constant to estimate order effects if I am changing the order of my alternatives in the survey instrument?
nayeem
 
Posts: 4
Joined: Sat Oct 14, 2023 2:38 am

Re: Heterogenous pivot design around multiple ref alts.

Postby Michiel Bliemer » Thu May 22, 2025 9:18 pm

1. This is shown in Script 9.5, see also the last paragraph on page 148 where this is discussed. Alternatively, you can simply generate a design with absolute levels (around average attribute values) as usual, and then convert these into percentages in Excel.

2. This is similar to RP data where also distance classes etc are different per respondent, but in the end one pools all the data to estimate a model. You may want to estimate a heteroskedastic choice model that accounts for differences in scale (or error variance), e.g. based on travel distance.

3. You cannot simply add another constant as it would make the model unidentified. You need to randomise the order of the alternatives across respondents, e.g. some respondents see Normal Road Transport on the left and others see it on the right. In your data set, you add a variable that indicates the position of each alternative (i.e., position 1, 2 or 3). You convert this into a dummy coded variable and add it to the utility function of each labelled alternative (which means estimating two extra coefficients). Since the position varies across respondents, this way you can disentangle the order effect from the label-specific constants. So you need to randomise the order of the alternatives in the survey instrument, this is the only way to do it, as otherwise the two effects are confounded.

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

Re: Heterogenous pivot design around multiple ref alts.

Postby nayeem » Fri May 23, 2025 12:15 am

Dear Michiel,

This was the original code:
Code: Select all
design   ? mode choice of shippers without reference alternative 
;alts(withref)=ref, truck, train, etrain
;alts(withoutref)=truck, train, etrain
;rows=24
;block=2
;eff= withoutref(mnl,d)
;con
;model(withref): ?auxiliary model with reference alternative
U(ref)=    brefcost[-0.000000001]     *  cost.ref[150]                                 
        +  breftime[-0.000000001]     *  time.ref[10]                                   
        +  brefttr[-0.000000001]      *  ttrzero.ref[0.8]                               
        /
U(truck)=  b1[-0.000000001]           *  cost.piv[-10%, -5%,0%,5%,10%]                 
        +  b2[-0.000000001]           *  time.piv[-2,-1,0,1,2]                         
        +  b3[-0.000000001]           *  ttr1[0.8,1.47,1.71,1.96,2.4]                   
        +  b4.dummy[-0.000000001]     *  risk[1,0]                                     
U(train)=  con_train                                                                   
        +  b5[-0.000000001]           *  cost.piv[ -15%,-10%,-5%]                       
        +  b6[-0.000000001]           *  time.piv[1,2,3,4]                             
        +  b3                         *  ttr1                                           
        +  b11[0.000000001]           *  frequency2[5,6,7]
        /
U(etrain)= con_etrain                                                                   
        +  b7[-0.000000001]           *  cost.piv[5%,10%,15%]                           
        +  b8[-0.000000001]           *  time.piv[-2,-1.5,-1]                           
        +  b9[-0.000000001]           *  ttr2[0.8,1.47]                                 
        +  b10[0.000000001]           *  frequency[2,3,5]                               

;model(withoutref): ?model without reference alternative
U(truck)=  b1                         *  cost.piv[-10%, -5%,0%,5%,10%]                 
        +  b2                         *  time.piv[-2,-1,0,1,2]                         
        +  b3                         *  ttr1[0.8,1.47,1.71,1.96,2.4]                   
        +  b4.dummy                   *  risk[1,0]                                     
        /
U(train)=  con_train                                                                   
        +  b5                         *  cost.piv[-15%,-10%,-5%]                       
        +  b6                         *  time.piv[1,2,3,4]                             
        +  b3                         *  ttr1                                           
        +  b11                        *  frequency2[5,6,7]
        /
U(etrain)= con_etrain                                                                   
        +  b7                         *  cost.piv[5%,10%,15%]                           
        +  b8                         *  time.piv[-2,-1.5,-1]                           
        +  b9                         *  ttr2[0.8,1.47]                                 
        +  b10                        *  frequency[2,3,5]                               
$

I tried to add another model using a different reference alternative with an aim to generate a heterogeneous pivot design.

Code: Select all
design   ? mode choice of shippers without reference alternative

?First model
;alts(withref1)=ref1, truck, train, etrain
;alts(withoutref1)=truck, train, etrain


?Second model
;alts(withref2)=ref2, truck, train, etrain
;alts(withoutref2)=truck, train, etrain


;rows=8
;block=1
;eff= alldistances(mnl,d)
;fisher(alldistances)=des1(withoutref1[0.5])+ des2(withoutref2[0.5])
;con
? Model when cost=$150 and time=10 hours
;model(withref1): ?auxiliary model with reference alternative1
U(ref1)=   brefcost[-0.000000001]     *  cost.ref1[150]                                 
        +  breftime[-0.000000001]     *  time.ref1[10]                                   
        +  brefttr[-0.000000001]      *  ttrzero.ref[0.8]                               
        /
U(truck)=  b1[-0.000000001]           *  cost.piv[-10%, -5%,0%,5%,10%]                 
        +  b2[-0.000000001]           *  time.piv[-2,-1,0,1,2]                         
        +  b3[-0.000000001]           *  ttr1[0.8,1.47,1.71,1.96,2.4]                   
        +  b4.dummy[-0.000000001]     *  risk[1,0]                                       
        /
U(train)=  con_train                                                                   
        +  b5[-0.000000001]           *  cost.piv[ -15%,-10%,-5%]                       
        +  b6[-0.000000001]           *  time.piv[1,2,3,4]                             
        +  b3                         *  ttr1                                           
        +  b11[0.000000001]           *  frequency2[5,6,7]
        /
U(etrain)= con_etrain                                                                   
        +  b7[-0.000000001]           *  cost.piv[5%,10%,15%]                           
        +  b8[-0.000000001]           *  time.piv[-2,-1.5,-1]                           
        +  b9[-0.000000001]           *  ttr2[0.8,1.47]                                 
        +  b10[0.000000001]           *  frequency[2,3,5]                               

;model(withoutref1): ?model without reference alternative1
U(truck)=  b1                         *  cost.piv[-10%, -5%,0%,5%,10%]                 
        +  b2                         *  time.piv[-2,-1,0,1,2]                         
        +  b3                         *  ttr1[0.8,1.47,1.71,1.96,2.4]                   
        +  b4.dummy                   *  risk[1,0]                                     
        /
U(train)=  con_train                                                                   
        +  b5                         *  cost.piv[-15%,-10%,-5%]                       
        +  b6                         *  time.piv[1,2,3,4]                             
        +  b3                         *  ttr1                                           
        +  b11                        *  frequency2[5,6,7]
        /
U(etrain)= con_etrain                                                                   
        +  b7                         *  cost.piv[5%,10%,15%]                           
        +  b8                         *  time.piv[-2,-1.5,-1]                           
        +  b9                         *  ttr2[0.8,1.47]                                 
        +  b10                        *  frequency[2,3,5]                               




? Model when cost=$200 and time=10 hours
;model(withref2): ?auxiliary model with reference alternative2
U(ref2)=   brefcost[-0.000000001]     *  cost.ref2[180]                                 
        +  breftime[-0.000000001]     *  time.ref2[10]                                   
        +  brefttr[-0.000000001]      *  ttrzero.ref[0.8]                               
        /
U(truck)=  b1[-0.000000001]           *  cost.piv[-10%, -5%,0%,5%,10%]                 
        +  b2[-0.000000001]           *  time.piv[-2,-1,0,1,2]                         
        +  b3[-0.000000001]           *  ttr1[0.8,1.47,1.71,1.96,2.4]                   
        +  b4.dummy[-0.000000001]     *  risk[1,0]                                     
        /
U(train)=  con_train                                                                   
        +  b5[-0.000000001]           *  cost.piv[ -15%,-10%,-5%]                       
        +  b6[-0.000000001]           *  time.piv[1,2,3,4]                             
        +  b3                         *  ttr1                                           
        +  b11[0.000000001]           *  frequency2[5,6,7]
        /
U(etrain)= con_etrain                                                                   
        +  b7[-0.000000001]           *  cost.piv[5%,10%,15%]                           
        +  b8[-0.000000001]           *  time.piv[-2,-1.5,-1]                           
        +  b9[-0.000000001]           *  ttr2[0.8,1.47]                                 
        +  b10[0.000000001]           *  frequency[2,3,5]                               

;model(withoutref2): ?model without reference alternative2
U(truck)=  b1                         *  cost.piv[-10%, -5%,0%,5%,10%]                 
        +  b2                         *  time.piv[-2,-1,0,1,2]                         
        +  b3                         *  ttr1[0.8,1.47,1.71,1.96,2.4]                   
        +  b4.dummy                   *  risk[1,0]                                       
        /
U(train)=  con_train                                                                   
        +  b5                         *  cost.piv[-15%,-10%,-5%]                       
        +  b6                         *  time.piv[1,2,3,4]                             
        +  b3                         *  ttr1                                           
        +  b11                        *  frequency2[5,6,7]
        /
U(etrain)= con_etrain                                                                   
        +  b7                         *  cost.piv[5%,10%,15%]                           
        +  b8                         *  time.piv[-2,-1.5,-1]                           
        +  b9                         *  ttr2[0.8,1.47]                                 
        +  b10                        *  frequency[2,3,5]                               

$

But this does not work.
nayeem
 
Posts: 4
Joined: Sat Oct 14, 2023 2:38 am

Re: Heterogenous pivot design around multiple ref alts.

Postby Michiel Bliemer » Fri May 23, 2025 1:54 am

Ngene does not support optimising pivot designs for different reference levels simultaneously. You would need to generate them separately.

Noting that you have uninformative priors, the reference levels play no role in the optimisation, so you could just generate a homogeneous design using design coding as explained in Section 9.1 (of the Ngene Online manual) and apply to all reference levels. You can relabel the design coding with pivot levels. With (near) zero priors, the actual levels do not matter when generating an efficient design.

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

Re: Heterogenous pivot design around multiple ref alts.

Postby nayeem » Sat May 24, 2025 5:27 pm

Dear Michiel,
The example given in section 9.1 is related to unlabeled alternatives. My design has labelled alternatives and all attributes are not generic. But still I tried to follow the code given in script 9.1:
Code: Select all
design   ? mode choice of shippers with HOMOGENOUS DESIGN CODING   
;alts=truck, train, etrain
;rows=24
;block=3
;eff=(mnl,d)
;con
;model: ?model using DESIGN CODING
U(truck)=  b1.dummy                *  COST1[0,1,2,3,4]                               
        +  b2.dummy                *  TIME1[0,1,2,3,4]                               
        +  b3.dummy                *  TTR1[0,1,2]                                   
        +  b4.dummy                *  risk[1,0]                                     
        /
U(train)=  con_train                                                                 
        +  b5.dummy                *  COST2[0,1,2]                                   
        +  b6.dummy                *  TIME2[0,1,2,3]                                 
        +  b3.dummy                *  TTR1                                           
        +  b7.dummy                *  frequency[0,1,2]
        /
U(etrain)= con_etrain                                                               
        +  b5.dummy                *  COST2                                         
        +  b8.dummy                *  TIME3[0,1,2]                                   
        +  b9.dummy                *  TTR2[0,1]                                     
        +  b7.dummy                *  frequency                                     
$

The error message shown is: An attribute has the wrong number of levels for dummy or effects coding. 'cost1'


I have also noticed that when I try to indicate the sign of the uninformed priors in my design as in script 9.1:

Code: Select all
design   ? mode choice of shippers with HOMOGENOUS DESIGN CODING   
;alts=truck, train, etrain
;rows=24
;block=3
;eff=(mnl,d)
;con
;model: ?model using DESIGN CODING
U(truck)=  b1.dummy[-]             *  COST1[0,1,2,3,4]                               
        +  b2.dummy                *  TIME1[0,1,2,3,4]                               
        +  b3.dummy                *  TTR1[0,1,2]                                   
        +  b4.dummy                *  risk[1,0]                                     
        /
U(train)=  con_train                                                                 
        +  b5.dummy                *  COST2[0,1,2]                                   
        +  b6.dummy                *  TIME2[0,1,2,3]                                 
        +  b3.dummy                *  TTR1                                           
        +  b7.dummy                *  frequency[0,1,2]
        /
U(etrain)= con_etrain                                                               
        +  b5.dummy                *  COST2                                         
        +  b8.dummy                *  TIME3[0,1,2]                                   
        +  b9.dummy                *  TTR2[0,1]                                     
        +  b7.dummy                *  frequency                                     
$

I get the error message: The 'model' property contains a prior that has an incorrectly configured Bayesian component. '-'

I am using Desktop version of Ngene 1.4.0 and Build 24011. Even the script 9.1 is not running in Ngene.
Code: Select all
design
;alts = pt1, pt2
;rows = 12
;eff = (mnl,d)
;model:
U(pt1, pt2) = time.dummy[-]  * TIME[0,1,2]
            + wait.dummy[-]  * WAIT[0,1,2]
            + trans.dummy[-] * TRANSFERS[0,1]
            + cost.dummy[-]  * FARE[0,1,2]
$

The error message shown is: A model in the utility expressions was not specified in the ';alts' property. ''
nayeem
 
Posts: 4
Joined: Sat Oct 14, 2023 2:38 am

Re: Heterogenous pivot design around multiple ref alts.

Postby Michiel Bliemer » Tue Jun 03, 2025 1:43 am

If you are using Ngene version 1.4 you need to refer to the manual for Ngene Destop (Windows) version 1.4. You are now reading the manual for Ngene Online, which is the latest release (version 2) and has several new features. You can find both versions of the manual on the ChoiceMetrics website: https://www.choice-metrics.com/pricinganddownloads
Direct link to the version 1.4 manual: https://files.choice-metrics.com/NgeneManual140.pdf

Below I have changed the script to run on version 1.4.

Code: Select all
design   ? mode choice of shippers with HOMOGENOUS DESIGN CODING   
;alts=truck, train, etrain
;rows=24
;block=3
;eff=(mnl,d)
;con
;model: ?model using DESIGN CODING
U(truck)=  b1.dummy[0|0|0|0]       *  COST1[0,1,2,3,4]                               
        +  b2.dummy[0|0|0|0]       *  TIME1[0,1,2,3,4]                               
        +  b3.dummy[0|0]           *  TTR1[0,1,2]                                   
        +  b4.dummy[0]             *  risk[1,0]                                     
        /
U(train)=  con_train                                                                 
        +  b5.dummy[0|0]           *  COST2[0,1,2]                                   
        +  b6.dummy[0|0|0]         *  TIME2[0,1,2,3]                                 
        +  b3.dummy                *  TTR1                                           
        +  b7.dummy[0|0]           *  frequency[0,1,2]
        /
U(etrain)= con_etrain                                                               
        +  b5.dummy                *  COST2                                         
        +  b8.dummy[0|0]           *  TIME3[0,1,2]                                   
        +  b9.dummy[0]             *  TTR2[0,1]                                     
        +  b7.dummy                *  frequency                                     
$


The plus and minus does not work in version 1.4, you will need to define the preference order manually, see below. Note that indicating the preference order of attribute levels is only useful for unlabelled alternatives where dominance checks are needed, they are not useful for labelled alternatives as in your case because there is no issue with strict dominance.

U(truck)= b1.dummy[0.004|0.003|0.002|0.001] * COST1[0,1,2,3,4]

Regarding your last script, you need to specify:

U(pt1) = ... /
U(pt2) = ...

The shortcut U(pt1,pt2) only works in Ngene Online.

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


Return to Support for Ngene Desktop (v1.x)

Who is online

Users browsing this forum: No registered users and 9 guests