Model Definition

The Multinomial Probit Model

The multinomial probit model1 provides a mathematical representation of process of choosing one out of a finite number of mutually exclusive alternatives depending on a number of regressor variables characterizing the alternatives and the decider. It possesses the interpretation of a random utility maximization (RUM) model, whereby a decider assigns a utility value to each alternative and picks the one with highest utility. As the modeler does not have full information, the model represents the utility using a systematic part, depending on regressor variables, plus an additive error term, which for probit models is normally distributed (Agresti 2015).

The model output are conditional choice probabilities depending on the regressor values.2 The regressor variables potentially consist of characteristics describing the alternatives and the deciders. To be concrete, assume that we possess data of NN decision makers which choose between J≥2J \geq 2 alternatives at each of TT choice occasions3. One example can be the choice of one out of a number of cars, both conventional and electric, for the next purchase. Specific to each decision maker, alternative and choice occasion, we observe PP choice attributes (like the purchase price, for example) that we use to explain the choices. Decider nn’s utility UntjU_{ntj} for alternative jj at choice occasion tt is modeled as

Untj=Xntj′β+Snt′γj+Zntj′δj+αj+ϵntjU_{ntj} = X_{ntj}'\beta + S_{nt}' \gamma_j + Z_{ntj}'\delta_j + \alpha_j + \epsilon_{ntj}

for n=1,…,Nn=1,\dots,N, t=1,…,Tt=1,\dots,T and j=1,…,Jj=1,\dots,J, where

The three types of regressor variables are called

Now let ynt=jy_{nt}=j denote the event that decision maker nn chooses alternative jj at her tt-th choice occasion. Assuming utility maximizing behavior of the decision makers, the decisions are linked to the utilities via4

ynt=arg⁡max⁡j=1,…,JUntj.y_{nt} = {\arg \max}_{j = 1,\dots,J} U_{ntj}.

Model Formula

In Rprobit the model is represented using a formula as in the mlogit R package (Croissant 2020). The following formula describes the dependent variable choice as a function of the type I variable V1, the type II variable V2 and the type III variable V3:

formula <- choice ~ V1 | V2 | V3

Hereby the following rules apply:

Example: Choice of a New Car

Consider a household deciding between different power trains for the car to be purchased. The options are a battery powered electric vehicle (BEV) and an internal combustion engine (ICE).

The alternative specific variables may include:

All of these depend on the alternative at the time of buying. The driving range coefficient for the BEV will be much higher than for the ICEV, as the refilling of the ICEV is simpler.

The decider characteristics may include:

The corresponding formula might be assuming that Attitude is not measured:

formula <- choice ~  PS + Main | HI + HS + loc + CF + 0 | range

The tradeoff between the purchase price and the driving range of a car may depend on the commuting habits of the deciders that are not represented well in the data.

Identifiability

When maximizing utilities the level is not of importance: Adding a constant to all utilities does not change the maximizing alternative. Also the scale is not of importance: Multiplying all utilities with a positive constant leaves the maximizing alternative indifferent. This implies identifiability issues. (Train 2009)

For type I variables the difference between two utilities Untj−UntkU_{ntj}-U_{ntk} depends on the difference Xntj−XntkX_{ntj}-X_{ntk} between the regressor variables. Therefore variables that do not vary over alternatives (resulting in Xntj−Xntk=0X_{ntj}-X_{ntk}=0) cannot be used as type I variables. Additionally, β\beta needs to be identified from Xntj′βX_{ntj}'\beta. Thus the type I variables must not be multicollinear.

For each type II variable the model includes JJ coefficients γj,j=1,...,J\gamma_j, j=1,...,J. Subtracting Snt′γ1S_{nt}'\gamma_1 from all utilities eliminates the coefficients corresponding to the first alternative from the model. The remaining (J−1)⋅PS(J-1) \cdot P_S coefficients for the type II variables are identifiable, if there are no multicollinearities between the type II variables. Here the choice of the first variable is arbitrary and any base alternative (=reference) can be chosen.

For type III variables we obtain Zntj′δj−Zntk′δkZ_{ntj}'\delta_j - Z_{ntk}'\delta_k in the utility differences. It follows that here all J⋅PZJ \cdot P_Z coefficients are identified, if ZntjZ_{ntj} vary over alternatives and are not multicollinear.

The same issue arises for the error terms: Subtracting the error ϵnt1\epsilon_{nt1} from all utilities does not change the maximizing alternative. Thus we can without restriction of generality assume that ϵnt1=0\epsilon_{nt1} = 0 (or pick any alternative as a reference alternative in this respect).

Finally for the identification of the scale one may either restrict one coefficient to unity (or minus unity). Or one might restrict one variance to a particular value (typically 1 or 0.5). For details see Train (2009) Section 5.2. Numerically fixing one coefficient to ±1\pm 1 is more stable than fixing a variance.

Model Unification

While the specification of type I, type II and type III variables is convenient for model specification and data storage, it is inconvenient in the estimation phase. Thus Rprobit uses a unified framework, recoding type II and type III variables into a set of type I variables. This is exemplified below. The choice data object (described in detail in the vignette Data and Simulation) provides the method build_design to perform the recoding according to a model formulation.

Representing Type II Variables as a Set of Type I Variables

A type II variable is specific to the decider but not the alternatives. There are J−1J-1 parameters corresponding to the type II variable, one for each alternative except for the base alternative. By interacting the type II variable with indicators of the J−1J-1 alternatives we obtain J−1J-1 variables varying over the alternatives: Xntjl=SntI(l=j)X_{ntjl} = S_{nt}{\mathbb I}(l=j), where I{\mathbb I} denotes the indicator function. This renders the vector of utilities (using the first alternative as the base):

(Unt1Unt2⋮UntJ)=(0γ2Snt⋮γJSnt)=(0…0Xnt22…Xnt2J⋮⋮⋮XntJ2…XntJJ)(γ2γ3⋮γJ)=Xntγ.\begin{pmatrix} U_{nt1} \\ U_{nt2} \\ \vdots \\ U_{ntJ} \end{pmatrix} = \begin{pmatrix} 0 \\ \gamma_2 S_{nt} \\ \vdots \\ \gamma_J S_{nt} \end{pmatrix} = \begin{pmatrix} 0 & \dots & 0 \\ X_{nt22} & \dots & X_{nt2J} \\ \vdots & \vdots & \vdots \\ X_{ntJ2} & \dots & X_{ntJJ} \end{pmatrix} \begin{pmatrix} \gamma_2 \\ \gamma_3 \\ \vdots \\ \gamma_J \end{pmatrix} = X_{nt} \gamma.

This transforms the scalar type II variable SntS_{nt} in J−1J-1 type I variables listed as the columns of the matrix XntX_{nt}.

Representing Type III Variables as a Set of Type I Variables

The reformulation of one scalar type III variable into JJ type I variables (listed as the diagonal of a matrix) follows a similar pattern:

(Unt1Unt2⋮UntJ)=(δ1Znt1δ2Znt2⋮δJZntJ)=(Znt10…00Znt2⋱⋮⋮⋱⋱00…0ZntJ)(δ1δ2⋮δJ)=Zntδ.\begin{pmatrix} U_{nt1} \\ U_{nt2} \\ \vdots \\ U_{ntJ} \end{pmatrix} = \begin{pmatrix} \delta_1 Z_{nt1} \\ \delta_2 Z_{nt2} \\ \vdots \\ \delta_J Z_{ntJ} \end{pmatrix} = \begin{pmatrix} Z_{nt1} & 0 & \dots & 0 \\ 0 & Z_{nt2} & \ddots & \vdots \\ \vdots & \ddots & \ddots & 0 \\ 0 & \dots & 0 & Z_{ntJ} \end{pmatrix} \begin{pmatrix} \delta_1 \\ \delta_2 \\ \vdots \\ \delta_J \end{pmatrix} = Z_{nt} \delta.

Note that contrary to type II variables, for type III variables we obtain JJ new type I variables.

Choice Behavior Heterogeneity

Note that all coefficient vectors β,γj,δj\beta, \gamma_j, \delta_j above are constant across decision makers. This assumption is too restrictive for many applications.5 Unobserved heterogeneity in choice behavior can be modeled by imposing a distribution on any element of β,γj,δj\beta, \gamma_j, \delta_j such that each decider can have their own preferences.

Such models use a random coefficient setup wherein the random coefficients are assumed to be drawn independent of all regressor variables and the errors. Mathematically this implies a mixing of the implied choice probabilities (the expectation over the random terms mathematically leads to an integration). Rprobit currently only implements normally distributed random parameters, that can be correlated across coefficients.

More precisely, in the unified model representation using only type I variables some of the components of β\beta can be mixed using a normal distribution for mixing. We assume that the mixed coefficients appear in the trailing part of β\beta, that is β=[βf′,βr′],βr∈RR,βr∼N(br,Ω),βf=bf∈RK−R\beta = [\beta_f',\beta_r'], \beta_r \in {\mathbb R}^R, \beta_r \sim {\mathcal N}(b_r, \Omega), \beta_f = b_f \in {\mathbb R}^{K-R}.

It is assumed that all coefficients corresponding to one original type II or type III variables are either mixed or not mixed. Thus the mixed coefficients can be specified by providing the names of their corresponding variables. For example in the model formula <- choice ~ V1 | V2 | V3 the coefficients to variable V1 and V3 are defined as mixing via

re <- c("V1", "V3")

Model Parameterization

According to the unification described above we achieve model specification using only type I variables as

Untj=Xntj′β+ϵntj,j=1,...,J,Xntj,(ϵnt:)∈RJ,β∈RK.U_{ntj} = X_{ntj}'\beta + \epsilon_{ntj}, j = 1,...,J, X_{ntj} , (\epsilon_{nt:}) \in {\mathbb R}^J, \beta \in {\mathbb R}^K.

Some of the components of β\beta can be mixed using a normal distribution for mixing. We assume that the mixed coefficients appear in the trailing part of β\beta, that is β=[βf′,βr′],βr∈RR,βr∼N(br,Ω),βf=bf∈RK−R\beta = [\beta_f',\beta_r'], \beta_r \in {\mathbb R}^R, \beta_r \sim {\mathcal N}(b_r, \Omega), \beta_f = b_f \in {\mathbb R}^{K-R}.

Therefore the parameterization of the model requires parameters for the vector b=(bf′,br′)′∈RKb = (b_f',b_r')' \in {\mathbb R}^K and the two variance matrices Ω∈RR×R\Omega \in {\mathbb R}^{R \times R} and Σ∈RJ×J\Sigma \in {\mathbb R}^{J \times J}. The parameterization has to conform to the restriction that variance matrices are positive semidefinite. Additionally the parameterization must ascertain identifiability of the parameters.

The parameter vector b∈RKb \in {\mathbb R}^{K} is parameterized using a linear affine mapping, to allow for the imposition of some restrictions:

b=Hbθb+fb.b = H_b \theta_b + f_b.

This allows to incorporate linear equality constraints on the parameters. For instance, restricting b1=1,b2=0,b3=−b4b_1 = 1, b_2 = 0, b_3 = - b_4 with b5b_5 free is achieved using

Hb=(000010−1001),fb=(10000).H_b = \begin{pmatrix} 0 & 0 \\ 0 & 0 \\ 1 & 0 \\ -1 & 0 \\ 0 & 1 \end{pmatrix}, f_b = \begin{pmatrix} 1 \\ 0 \\ 0 \\ 0 \\ 0 \end{pmatrix}.

A common device to ensure positive semidefiniteness of matrices is to use Cholesky factors. For each positive semidefinite matrix Σ∈RJ×J\Sigma \in {\mathbb R}^{J \times J} there exists a lower triangular matrix L∈RJ×JL \in {\mathbb R}^{J \times J} such that LL′=ΣL L' = \Sigma.

We chose to parameterize the vectorization of the lower half of the Cholesky matrices using a linear affine mapping:

vech⁡(L)=HLθL+fL\operatorname{vech}(L) = H_L \theta_L + f_L

where vech⁡\operatorname{vech} denotes columnwise vectorization of the lower triangular matrix (including the diagonal). Thus for J=3J=3, for example, the lower triangular Cholesky factor includes 6 entries:

L=(θ100θ2θ40θ3θ5θ6).\begin{align*} L = \begin{pmatrix} \theta_1 & 0 & 0 \\ \theta_2 & \theta_4 & 0 \\ \theta_3 & \theta_5 & \theta_6 \end{pmatrix}. \end{align*}

Here fLf_L can be used to fix entries for identifiability reasons. For example, for J=3J=3 parameterizing a diagonal matrix where the (1,1) entry is fixed to equal Σ1,1=1\Sigma_{1,1}=1 can be done using

HL=(000000100001),fL=(100000).\begin{align*} H_L &= \begin{pmatrix} 0 & 0 \\ 0 & 0 \\ 0 & 0 \\ 1 & 0 \\ 0 & 0 \\ 0 & 1 \end{pmatrix}, f_L = \begin{pmatrix} 1 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \end{pmatrix}. \end{align*}

Thus there are two parameters θ1\theta_1 and θ2\theta_2. We do not impose non-negativity of these parameters, which leads to a non-identifiability as without this restriction on the diagonal entries the Cholesky factors are not unique. The tradeoff made here is the inclusion of multiple well separated global optima in favor of being able to leave out parameter non-negativity restrictions.

Model Object

Rprobit collects all information related to the model in a mod object. This object is implemented as a R6 class. See here for the perils of R6 classes.

The following example parameterizes a model for mode choice depending on the price of the alternative modes (used as a type I variable) and time (used as a type III variable) featuring J=3J = 3 alternatives. The ASC are mixed using a normal distribution:

formula <- choice ~ price | 1 | time
re <- "ASC"
m_basic <- mod$new(formula, re, alt = 3)

Printing the object provides an overview of the specification:

print(m_basic)
#> <mod object>
#> 
#> Formula: choice ~ price | 1 | time
#> Random effects: ASC
#> Alternative names: A, B, C
#> Coefficients: 4 fixed, 2 random
#> Free parameters total: 10
#> 
#> Utility equations:
#> 
#>   U_A = b[1] * price_A + b[2] * time_A + eps[1]
#>   U_B = b[1] * price_B + b[3] * time_B + b[5] + eps[2]
#>   U_C = b[1] * price_C + b[4] * time_C + b[6] + eps[3]
#> 
#> Parameter restrictions:
#> 
#>   b = H_b theta_b
#>   length(theta_b): 6
#>   H_b (6 x 6) =
#>             theta_1 theta_2 theta_3 theta_4 theta_5 theta_6
#> b[1]:price        1       0       0       0       0       0
#> b[2]:time_A       0       1       0       0       0       0
#> b[3]:time_B       0       0       1       0       0       0
#> b[4]:time_C       0       0       0       1       0       0
#> b[5]:ASC_B        0       0       0       0       1       0
#> b[6]:ASC_C        0       0       0       0       0       1
#> 
#> 
#>   O = vech(chol(Omega)) = H_O theta_O
#>   length(theta_O): 2
#>   H_O (3 x 2) =
#>               theta_7 theta_8
#> ASC_B_:_ASC_B       1       0
#> ASC_C_:_ASC_B       0       0
#> ASC_C_:_ASC_C       0       1
#> 
#> 
#>   L = vech(chol(Sigma)) = H_L theta_L + f_L
#>   length(theta_L): 2
#>   H_L (6 x 2) =
#>       theta_9 theta_10
#> A_:_A       0        0
#> B_:_A       0        0
#> C_:_A       0        0
#> B_:_B       0        0
#> C_:_B       1        0
#> C_:_C       0        1
#>   f_L (6 x 1) =
#>        
#> A_:_A 0
#> B_:_A 0
#> C_:_A 0
#> B_:_B 1
#> C_:_B 0
#> C_:_C 0

We can see that six coefficient parameters (length_theta_b = 6) are free, the two ASCs are random leading to a 2×22 \times 2 covariance matrix Ω∈R2×2\Omega \in {\mathbb R}^{2 \times 2} that is modeled as a diagonal matrix using two parameters (length_theta_O = 2). Finally the variance Σ\Sigma uses two parameters (length_theta_L = 2):

HL=(000000001001),fL=(000100)⇒L=(0000100θ1θ2)⇒Σ=LL′=(0000100θ1θ12+θ22).\begin{align*} H_L &= \begin{pmatrix} 0 & 0 \\ 0 & 0 \\ 0 & 0 \\ 0 & 0 \\ 1 & 0 \\ 0 & 1 \end{pmatrix}, f_L = \begin{pmatrix} 0 \\ 0 \\ 0 \\ 1 \\ 0 \\ 0 \end{pmatrix} \Rightarrow L = \begin{pmatrix} 0 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & \theta_1 & \theta_2 \end{pmatrix} \Rightarrow \Sigma = LL' = \begin{pmatrix} 0 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & \theta_1 & \theta_1^2 + \theta_2^2 \end{pmatrix}. \end{align*}

There are more options to initialize a mod object:

alt_names <- c("train", "bus", "car")

m <- mod$new(
  formula = formula, re = re, alt = 3,
  alt_names = alt_names,            # alternative labels
  ref_alt = "train",                # reference alternative (for type-2 effects)
  corr_re = FALSE,                  # structure for Omega
  error_struc = "diag"              # structure for Sigma
)

print(m)
#> <mod object>
#> 
#> Formula: choice ~ price | 1 | time
#> Random effects: ASC
#> Alternative names: train, bus, car
#> Coefficients: 4 fixed, 2 random
#> Free parameters total: 10
#> 
#> Utility equations:
#> 
#>   U_train = b[1] * price_train + b[2] * time_train + eps[1]
#>   U_bus = b[1] * price_bus + b[3] * time_bus + b[5] + eps[2]
#>   U_car = b[1] * price_car + b[4] * time_car + b[6] + eps[3]
#> 
#> Parameter restrictions:
#> 
#>   b = H_b theta_b
#>   length(theta_b): 6
#>   H_b (6 x 6) =
#>                 theta_1 theta_2 theta_3 theta_4 theta_5 theta_6
#> b[1]:price            1       0       0       0       0       0
#> b[2]:time_train       0       1       0       0       0       0
#> b[3]:time_bus         0       0       1       0       0       0
#> b[4]:time_car         0       0       0       1       0       0
#> b[5]:ASC_bus          0       0       0       0       1       0
#> b[6]:ASC_car          0       0       0       0       0       1
#> 
#> 
#>   O = vech(chol(Omega)) = H_O theta_O
#>   length(theta_O): 2
#>   H_O (3 x 2) =
#>                   theta_7 theta_8
#> ASC_bus_:_ASC_bus       1       0
#> ASC_car_:_ASC_bus       0       0
#> ASC_car_:_ASC_car       0       1
#> 
#> 
#>   L = vech(chol(Sigma)) = H_L theta_L + f_L
#>   length(theta_L): 2
#>   H_L (6 x 2) =
#>               theta_9 theta_10
#> train_:_train       0        0
#> bus_:_train         0        0
#> car_:_train         0        0
#> bus_:_bus           1        0
#> car_:_bus           0        0
#> car_:_car           0        1
#>   f_L (6 x 1) =
#>                
#> train_:_train 1
#> bus_:_train   0
#> car_:_train   0
#> bus_:_bus     0
#> car_:_bus     0
#> car_:_car     0

This adds labels to the alternatives and changes the error covariance matrix to a diagonal structure. For the recoding ref_alt defines the reference alternative, for which no ASC or type II regressors are generated to avoid non-identifiability. The correlation structure of Ω\Omega is set to FALSE leading to a diagonal matrix. The error variance matrix is chosen diagonal. The available error structures are:

Working with the Model Objects

Having defined objects, one wants to manipulate the models. To do this, we must know the fields of the model object. These can be grouped into fields that are read-only and fields that can be adapted.

Read-only fields are:

These cannot be changed directly but are inferred from the adjustable fields:

The last field suppresses warnings issued by the object. Changing model-defining fields such as formula, re, alt_names, or ref_alt can automatically adapt dependent restriction matrices and vectors. By default, the object warns about these adaptations.

To demonstrate this behavior, consider adding a random coefficient for price:

m$suppress_warnings <- TRUE
m$re <- c("ASC", "price")
m
#> <mod object>
#> 
#> Formula: choice ~ price | 1 | time
#> Random effects: ASC, price
#> Alternative names: train, bus, car
#> Coefficients: 3 fixed, 3 random
#> Free parameters total: 11
#> 
#> Utility equations:
#> 
#>   U_train = b[1] * time_train + b[4] * price_train + eps[1]
#>   U_bus = b[2] * time_bus + b[4] * price_bus + b[5] + eps[2]
#>   U_car = b[3] * time_car + b[4] * price_car + b[6] + eps[3]
#> 
#> Parameter restrictions:
#> 
#>   b = H_b theta_b
#>   length(theta_b): 6
#>   H_b (6 x 6) =
#>                 theta_1 theta_2 theta_3 theta_4 theta_5 theta_6
#> b[1]:time_train       1       0       0       0       0       0
#> b[2]:time_bus         0       1       0       0       0       0
#> b[3]:time_car         0       0       1       0       0       0
#> b[4]:price            0       0       0       1       0       0
#> b[5]:ASC_bus          0       0       0       0       1       0
#> b[6]:ASC_car          0       0       0       0       0       1
#> 
#> 
#>   O = vech(chol(Omega)) = H_O theta_O
#>   length(theta_O): 3
#>   H_O (6 x 3) =
#>                   theta_7 theta_8 theta_9
#> price_:_price           1       0       0
#> ASC_bus_:_price         0       0       0
#> ASC_car_:_price         0       0       0
#> ASC_bus_:_ASC_bus       0       1       0
#> ASC_car_:_ASC_bus       0       0       0
#> ASC_car_:_ASC_car       0       0       1
#> 
#> 
#>   L = vech(chol(Sigma)) = H_L theta_L + f_L
#>   length(theta_L): 2
#>   H_L (6 x 2) =
#>               theta_10 theta_11
#> train_:_train        0        0
#> bus_:_train          0        0
#> car_:_train          0        0
#> bus_:_bus            1        0
#> car_:_bus            0        0
#> car_:_car            0        1
#>   f_L (6 x 1) =
#>                
#> train_:_train 1
#> bus_:_train   0
#> car_:_train   0
#> bus_:_bus     0
#> car_:_bus     0
#> car_:_car     0

Since suppress_warnings is set to TRUE, no warning is issued. If we set suppress_warnings to FALSE and change the model back, we get a warning:

m$suppress_warnings <- FALSE
m$re <- c("ASC")
m
#> <mod object>
#> 
#> Formula: choice ~ price | 1 | time
#> Random effects: ASC
#> Alternative names: train, bus, car
#> Coefficients: 4 fixed, 2 random
#> Free parameters total: 10
#> 
#> Utility equations:
#> 
#>   U_train = b[1] * price_train + b[2] * time_train + eps[1]
#>   U_bus = b[1] * price_bus + b[3] * time_bus + b[5] + eps[2]
#>   U_car = b[1] * price_car + b[4] * time_car + b[6] + eps[3]
#> 
#> Parameter restrictions:
#> 
#>   b = H_b theta_b
#>   length(theta_b): 6
#>   H_b (6 x 6) =
#>                 theta_1 theta_2 theta_3 theta_4 theta_5 theta_6
#> b[1]:price            1       0       0       0       0       0
#> b[2]:time_train       0       1       0       0       0       0
#> b[3]:time_bus         0       0       1       0       0       0
#> b[4]:time_car         0       0       0       1       0       0
#> b[5]:ASC_bus          0       0       0       0       1       0
#> b[6]:ASC_car          0       0       0       0       0       1
#> 
#> 
#>   O = vech(chol(Omega)) = H_O theta_O
#>   length(theta_O): 2
#>   H_O (3 x 2) =
#>                   theta_7 theta_8
#> ASC_bus_:_ASC_bus       1       0
#> ASC_car_:_ASC_bus       0       0
#> ASC_car_:_ASC_car       0       1
#> 
#> 
#>   L = vech(chol(Sigma)) = H_L theta_L + f_L
#>   length(theta_L): 2
#>   H_L (6 x 2) =
#>               theta_9 theta_10
#> train_:_train       0        0
#> bus_:_train         0        0
#> car_:_train         0        0
#> bus_:_bus           1        0
#> car_:_bus           0        0
#> car_:_car           0        1
#>   f_L (6 x 1) =
#>                
#> train_:_train 1
#> bus_:_train   0
#> car_:_train   0
#> bus_:_bus     0
#> car_:_bus     0
#> car_:_car     0

To impose a restriction on β\beta, we may change the matrices H_b, f_b directly. For example, restricting b(1)b(1) to equal b[1]=1b[1]=1 we may use the following commands:

m$H_b <- m$H_b[, -1]
m$f_b[1] <- 1
m
#> <mod object>
#> 
#> Formula: choice ~ price | 1 | time
#> Random effects: ASC
#> Alternative names: train, bus, car
#> Coefficients: 4 fixed, 2 random
#> Free parameters total: 9
#> 
#> Utility equations:
#> 
#>   U_train = b[1] * price_train + b[2] * time_train + eps[1]
#>   U_bus = b[1] * price_bus + b[3] * time_bus + b[5] + eps[2]
#>   U_car = b[1] * price_car + b[4] * time_car + b[6] + eps[3]
#> 
#> Parameter restrictions:
#> 
#>   b = H_b theta_b + f_b
#>   length(theta_b): 5
#>   H_b (6 x 5) =
#>                 theta_1 theta_2 theta_3 theta_4 theta_5
#> b[1]:price            0       0       0       0       0
#> b[2]:time_train       1       0       0       0       0
#> b[3]:time_bus         0       1       0       0       0
#> b[4]:time_car         0       0       1       0       0
#> b[5]:ASC_bus          0       0       0       1       0
#> b[6]:ASC_car          0       0       0       0       1
#>   f_b (6 x 1) =
#>             
#> price      1
#> time_train 0
#> time_bus   0
#> time_car   0
#> ASC_bus    0
#> ASC_car    0
#> 
#> 
#>   O = vech(chol(Omega)) = H_O theta_O
#>   length(theta_O): 2
#>   H_O (3 x 2) =
#>                   theta_6 theta_7
#> ASC_bus_:_ASC_bus       1       0
#> ASC_car_:_ASC_bus       0       0
#> ASC_car_:_ASC_car       0       1
#> 
#> 
#>   L = vech(chol(Sigma)) = H_L theta_L + f_L
#>   length(theta_L): 2
#>   H_L (6 x 2) =
#>               theta_8 theta_9
#> train_:_train       0       0
#> bus_:_train         0       0
#> car_:_train         0       0
#> bus_:_bus           1       0
#> car_:_bus           0       0
#> car_:_car           0       1
#>   f_L (6 x 1) =
#>                
#> train_:_train 1
#> bus_:_train   0
#> car_:_train   0
#> bus_:_bus     0
#> car_:_bus     0
#> car_:_car     0

To check that the first element is restricted to one, we can draw a random parameter vector and calculate the system corresponding to this parameter vector:

set.seed(1)
theta <- runif(m$length_theta)
(parameter <- m$build_parameter(theta))
#> $b
#>                     
#> price      1.0000000
#> time_train 0.2655087
#> time_bus   0.3721239
#> time_car   0.5728534
#> ASC_bus    0.9082078
#> ASC_car    0.2016819
#> 
#> $O
#>                            
#> ASC_bus_:_ASC_bus 0.8983897
#> ASC_car_:_ASC_bus 0.0000000
#> ASC_car_:_ASC_car 0.9446753
#> 
#> $Omega_chol
#>           ASC_bus   ASC_car
#> ASC_bus 0.8983897 0.0000000
#> ASC_car 0.0000000 0.9446753
#> 
#> $Omega
#>          ASC_bus   ASC_car
#> ASC_bus 0.807104 0.0000000
#> ASC_car 0.000000 0.8924114
#> 
#> $L
#>                        
#> train_:_train 1.0000000
#> bus_:_train   0.0000000
#> car_:_train   0.0000000
#> bus_:_bus     0.6607978
#> car_:_bus     0.0000000
#> car_:_car     0.6291140
#> 
#> $Sigma_chol
#>       train       bus      car
#> train     1 0.0000000 0.000000
#> bus       0 0.6607978 0.000000
#> car       0 0.0000000 0.629114
#> 
#> $Sigma
#>       train       bus       car
#> train     1 0.0000000 0.0000000
#> bus       0 0.4366537 0.0000000
#> car       0 0.0000000 0.3957845

Sometimes it is useful to go the other way and calculate the parameter vector corresponding to a particular system:

theta2 <- m$build_theta(
  b = parameter$b,
  Omega = parameter$Omega,
  Sigma = parameter$Sigma
)
all.equal(theta, theta2)
#> [1] TRUE

This helps for example when a given variance matrix Σ\Sigma shall be parameterized.

Restrictions on Ω\Omega and Σ\Sigma can be handled analogously. Note, that Rprobit provides much freedom with respect to choosing the parameterization of the model. The user can change the matrices and vectors in the three affine linear mappings within the dimensions implied by the model. Consequently, the user has to make sure that her parameterization is identifiable. (Train 2009) discusses in section 5.2. guidelines to achieve identification. This is supported via the method check_identifiability which performs a numeric check by calculating the column rank of the Jacobian of a normalized representation of bb, Ω\Omega, and the differenced Σ\Sigma for a randomly chosen parameter vector θ\theta.

If in the example above, for example, we change the parameterization back to estimate all entries in β\beta and to also include the (2,2)(2,2)-element of LL as a free parameter, then the model loses its identifiability due to a lack of identifying the scale of the utility. Some problems with identifiability can be checked using the check_identifiability() function. The first model is identifiable…

m$H_b <- diag(6)
m$check_identifiability()
#> [1] TRUE

… while the second is not:

m2 <- m$clone()
m2$H_L <- diag(6)[, -c(1, 2, 3)]
m2$f_L <- matrix(0, ncol = 1, nrow = 6)
m2$check_identifiability()
#> Warning: The parameter set may not be identified; check the specification.
#> [1] FALSE

Note, that instead of just assigning m to the second model m2 we need to clone() the object. R6 objects have reference semantics, so a direct assignment would refer to the same object. Cloning creates an independent object.

References

Agresti, A. 2015. Foundations of Linear and Generalized Linear Models. Wiley.
Bliss, C. 1934. “The Method of Probits.” Science 79 (2037): 38–39. https://doi.org/10.1126/science.79.2037.38.
Croissant, Y. 2020. “Estimation of Random Utility Models in R: The mlogit Package.” Journal of Statistical Software 95 (11). https://doi.org/10.18637/jss.v095.i11.
Train, K. 2009. Discrete Choice Methods with Simulation. Cambridge University Press. https://doi.org/10.1017/CBO9780511805271.

  1. The name probit is a portmanteau of probability and unit. (Bliss 1934)↩︎

  2. An alternative way to view the probit model is that it provides a function linking regressors to choice probabilities. The RUM interpretation is only one viewpoint. Thus one does not have to believe in rational behavior to use the probit models.↩︎

  3. For notational simplicity, the number of choice occasions TT is assumed to be the same for each decision maker here. However, we are not restricted to this case: Rprobit allows for unbalanced panels, i.e. varying TT over deciders. Of course, the cross-sectional case T=1T = 1 is possible.↩︎

  4. Here, arg⁡max⁡{\arg \max} picks the smallest maximizing argument in the unlikely case of a draw.↩︎

  5. For example, the tradeoff between the purchase price and the driving range may depend on the commuting habits of the deciders that are not represented well in the data.↩︎