library(RprobitB)
RprobitB is an R package that can be used to fit latent class mixed multinomial probit (LCMMNP) models to simulated or empirical data. RprobitB is licensed under the GNU General Public License v3.0.
Do you found a bug or request a feature? Please tell us!
The package name RprobitB is a portmanteau, combining R (the programming language), probit (the model name) and B (for Bayes, the estimation method).
RprobitB is able to
At this point, you may ask yourself:
To install the latest version of RprobitB, run install.packages("RprobitB")
in your R console.
To use RprobitB, follow these steps:
RprobitB::rpb(<list of model specifications>)
.Assume that we observe the choices of \(N\) decision makers which decide between \(J\) alternatives at each of \(T\) choice occasions.1 Specific to each decision maker, alternative and choice occasion, we furthermore observe \(P_f+P_r\) choice attributes that we use to explain the choices. The first \(P_f\) attributes are connected to fixed coefficients, the other \(P_r\) attributes to random coefficients following a joint distribution mixed across decision makers. Person \(n\)’s utility \(\tilde{U}_{ntj}\) for alternative \(j\) at choice occasion \(t\) is modelled as \[\begin{equation} \tilde{U}_{ntj} = \tilde{W}_{ntj}'\alpha + \tilde{X}_{ntj}'\beta_n + \tilde{\epsilon}_{ntj} \end{equation}\] for \(n=1,\dots,N\), \(t=1,\dots,T\) and \(j=1,\dots,J\), where
As is well known, any utility model needs to be normalized with respect to level and scale in order to be identified. Therefore, we consider the transformed model \[\begin{equation} U_{ntj} = W_{ntj}'\alpha + X_{ntj}'\beta_n + \epsilon_{ntj}, \end{equation}\] \(n=1,\dots,N\), \(t=1,\dots,T\) and \(j=1,\dots,J-1\), where (choosing \(J\) as the reference alternative) \(U_{ntj}=\tilde{U}_{ntj} - \tilde{U}_{ntJ}\), \(W_{ntj}=\tilde{W}_{ntj}-\tilde{W}_{ntJ}\), \(X_{ntj}=\tilde{X}_{ntj}-\tilde{X}_{ntJ}\) and \(\epsilon_{ntj}=\tilde{\epsilon}_{ntj}-\tilde{\epsilon}_{ntJ}\), where \((\epsilon_{nt:}) = (\epsilon_{nt1},...,\epsilon_{nt(J-1)})' \sim \text{MVN}_{J-1} (0,\Sigma)\) and \(\Sigma\) denotes a covariance matrix with the top-left element restricted to one. While taking utility differences in order to normalize the model with respect to level is a standard procedure, alternatives to fixing an error term variance in order to normalize with respect to scale exist, for example fixing an element of \(\alpha\).
Let \(y_{nt}=j\) denote the event that decision maker \(n\) chooses alternative \(j\) at choice occasion \(t\). Assuming utility maximizing behaviour of the decision makers, the decisions are linked to the utilities via \[\begin{equation} y_{nt} = \sum_{j=1}^{J-1} j\cdot 1 \left (U_{ntj}=\max_i U_{nti}>0 \right) + J \cdot 1\left (U_{ntj}<0 ~\text{for all}~j\right), \end{equation}\] where \(1(A)\) equals \(1\) if condition \(A\) is true and \(0\) else.
We approximate the mixing distribution \(g_{P_r}\) for the random coefficients \(\beta=(\beta_n)_{n}\) by a mixture of \(P_r\)-variate normal densities \(\phi_{P_r}\) with mean vectors \(b=(b_c)_{c}\) and covariance matrices \(\Omega=(\Omega_c)_{c}\) using \(C\) components, i.e. \[\begin{equation} \beta_n\mid b,\Omega \sim \sum_{c=1}^{C} s_c \phi_{P_r} (\cdot \mid b_c,\Omega_c), \end{equation}\] where \((s_c)_{c}\) are weights satisfying \(0 < s_c\leq 1\) for \(c=1,\dots,C\) and \(\sum_c s_c=1\). One interpretation of the latent class model is obtained by introducing variables \(z=(z_n)_n\) allocating each decision maker \(n\) to class \(c\) with probability \(s_c\), i.e. \[\begin{equation} \text{Prob}(z_n=c)=s_c \quad \text{and} \quad \beta_n \mid z,b,\Omega \sim \phi_{P_r}(\cdot \mid b_{z_n},\Omega_{z_n}). \end{equation}\] We call this model the latent class mixed multinomial probit (LCMMNP) model.2
Updating the number \(C\) of latent classes is done within the algorithm by executing the following weight-based updating scheme.
RprobitB specifications are grouped in the named lists
model
(model information),data
(data information),parm
(true parameter values),lcus
(latent class updating scheme parameters),init
(initial values for the Gibbs sampler),prior
(prior parameters),mcmc
(Markov chain Monte Carlo parameters),norm
(normalization information),out
(output settings).You can either specify none, all, or selected parameters. Unspecified parameters are set to default values.
model
N
, the number (greater or equal one) of decision makersT
, the number (greater or equal one) or vector (of length N
) of choice occasions for each decision makerJ
, the number (greater or equal two) of choice alternatives (fixed across decision makers and choice occasions)P_f
, the number of attributes that are connected to fixed coefficients (can be zero)P_r
, the number of attributes that are connected to random, decision maker specific coefficients (can be zero)C
, the number of latent classes (ignored if P_r = 0
)data
If data = NULL
, data is simulated from the model defined by model
and parm
.
To model empirical data, specify
data_raw
, the data frame of choice data in wide format3, must contain columns named “id” (unique identifier for each decision maker) and “choice” (the chosen alternatives)cov_col
, a numeric vector specifying the columns of data_raw
with covariatescov_ord
, a character vector specifying the order of the covariates, where fixed-coefficient covariates come first (required for specifying random coefficients and interpretation of the model results)cov_zst
, a boolean determining whether covariates get z-standardizedparm
alpha
, the fixed coefficient vector (of length model[["P_f"]]
)s
, the vector of class weights (of length model[["C"]]
)b
, the matrix of class means as columns (of dimension model[["P_r"]]
x model[["C"]]
)Omega
, the matrix of class covariance matrices as columns (of dimension model[["P_r"]]*model[["P_r"]]
x model[["C"]]
)Sigma
, the error term covariance matrix (of dimension model[["J"]]-1
x model[["J"]]-1
)lcus
do_lcus
, a boolean determining whether to update the number of latent classesC0
, the initial number of latent classesCmax
, the maximal number of latent classes (greater or equal lcus[["C0"]]
)buffer
, the buffer for the updating (number of iterations to wait before the next update)epsmin
, the threshold weight for removing latent classes (between 0 and 1)epsmax
, the threshold weight for splitting latent classes (between 0 and 1)distmin
, the threshold for joining latent classes (greater 0)init
at_true
, a boolean determining whether to initialize at the true parameter values (only for simulated data)alpha0
, the initial fixed coefficient vector (of length model[["P_f"]]
)b0
, the initial matrix of the class means as columns (of dimension model[["P_r"]]
x model[["C"]]
)Omega0
, the inital matrix of the class covariance matrices as columns (of dimension model[["P_r"]]*model[["P_r"]]
x model[["C"]]
)Sigma0
, the initial error term covariance matrix (of dimension model[["J"]]-1
x model[["J"]]-1
)U0
, the initial matrix of utilities (of dimension model[["J"]]-1
x model[["N"]]*max(model[["T"]])
)beta0
, the initial matrix of random coefficients (of dimension model[["P_r"]]
x model[["N"]]
)m0
, the initial vector of class sizes (of length model[["C"]]
)prior
A priori, parm[["alpha"]]
~ Normal(eta
,Psi
) with
eta
, the expectation vector (of length model[["P_f"]]
)Psi
, the covariance matrix (of dimension model[["P_f"]]
x model[["P_f"]]
)A priori, parm[["s"]]
~ Dirichlet(delta
) with
delta
, the concentration parameter (of length 1)A priori, parm[["b"]][,c]
~ Normal(xi
,D
) with
xi
, the expectation vector (of length model[["P_r"]]
)D
, the covariance matrix (of dimension model[["P_r"]]
x model[["P_r"]]
)A priori, matrix(parm[["Omega"]][,c],nrow=model[["P_r"]],ncol=model[["P_r"]])
~ Inverse_Wishart(nu
,Theta
) with
nu
, the degrees of freedom (greater than model[["P_r"]]
)Theta
, the scale matrix (of dimension model[["P_r"]]
x model[["P_r"]]
)A priori, parm[["Sigma"]]
~ Inverse_Wishart(kappa
,E
) with
kappa
, the degrees of freedom (greater than model[["J"]]-1
)E
, the scale matrix (of dimension model[["J"]]-1
x model[["J"]]-1
)mcmc
R
: the number of iterationsB
: the length of the burn-in periodQ
: the thinning parameternprint
: the step number for printing the sampling progressnorm
RprobitB automatically normalizes with respect to level by computing utility differences, where model[["J"]]
is the base alternative. The normalization with respect to scale can be specified:
parameter
: the normalized parameter (either "a"
for a fixed non-random linear coefficient or "s"
for an error-term variance)index
: the index of the parameter (between 1 and model[["P_f"]]
or 1 and model[["J"]]-1
, respectively)value
: the value for the fixed parameter (greater 0 if parameter = "s"
)out
id
: a character, identifying the modelrdir
: a character, defining the (relative) path of the folder with the model resultspp
: a boolean, determining whether progress plots should be created (in any case only if model$P_r=2
)results
: a boolean, determining whether estimated parameters should be returned by the function rpb
.waic
: a boolean, determining whether to compute the widely applicable information criterion (WAIC)model
N = 100
T = 10
J = 2
P_f = 1
P_r = 0
C = NA
data
NULL
parm
Per default, parameters are randomly drawn.
lcus
do_lcus = FALSE
C0 = 5
Cmax = 10
buffer = 100
epsmin = 0.01
epsmax = 0.99
distmin = 0.1
init
at_true = FALSE
alpha0
: zero vectorb0
: zero matrices for each latent classOmega0
: unity matrices for each latent classSigma0
: unity matrixU0
: zero matrixbeta0
: zero matrixm0
: each latent class has twice the membership than the previous oneprior
eta = numeric(model[["P_f"]])
Psi = matrix(1,model[["P_f"]],model[["P_f"]]); diag(Psi) = 5
delta = 1
xi = numeric(model[["P_r"]])
D = matrix(1,model[["P_r"]],model[["P_r"]]); diag(D) = 5
nu = model[["P_r"]]+2
Theta = matrix(1,model[["P_r"]],model[["P_r"]]); diag(Theta) = 5
kappa = model[["J"]]+1
E = matrix(1,model[["J"]]-1,model[["J"]]-1); diag(E) = 5
mcmc
R = 10000
B = R/2
Q = 100
nprint = floor(R/10)
norm
parameter = "s"
index = "1"
value = "1"
out
id = test
rdir = tempdir()
pp = FALSE
return = FALSE
waic = FALSE
The code below fits a mixed multinomial probit model with
P_f = 1
fixedP_r = 2
random coefficientsto simulated data with
N = 100
decision makers,T = 10
and T = 20
,J = 3
choice alternatives,C = 2
true latent classes.The number of latent classes is updated, because do_lcus = TRUE
is set. The Gibbs sampler draws R = 20000
samples. By default, the model is named id = "test"
and results are saved in rdir = "tempdir()"
(the path of the per-session temporary directory).
set.seed(1)
### model specification
= list("N" = 100, "T" = sample(10:20,100,replace=TRUE), "J" = 3, "P_f" = 1, "P_r" = 2, "C" = 2)
model = list("do_lcus" = TRUE)
lcus = list("R" = 20000)
mcmc
### start estimation (about 3 minutes computation time)
::rpb("model" = model, "lcus" = lcus, "mcmc" = mcmc) RprobitB
The code below fits a mixed multinomial probit model with P_f = 2
fixed and P_r = 2
random coefficients to the “Train” dataset of the mlogit package with
"cov_col" = 4:11
,"cov_ord" = c("price","comfort","time","change")
(remember that fixed coefficients come first),"cov_zst" = TRUE
).For normalization, the price coefficient ("parameter" = "a", "index" = 1
) is fixed to "value" = -1
.
### load Train data
data("Train", package = "mlogit")
### model specification
= list("P_f" = 2, "P_r" = 2)
model = list("data_raw" = Train, "cov_col" = 4:11, "cov_ord" = c("price","comfort","time","change"), "cov_zst" = TRUE)
data = list("do_lcus" = TRUE)
lcus = list("R" = 1e5)
mcmc = list("parameter" = "a", "index" = 1, "value" = -1)
norm = list("id" = "train", "pp" = TRUE)
out
### start estimation (about 20 minutes computation time)
::rpb("model" = model, "data" = data, "lcus" = lcus, "mcmc" = mcmc, "norm" = norm, "out" = out) RprobitB
During estimation, you get the following on-screen information:
lcus[["do_lcus"]]=TRUE
) the latent class updating scheme parameterslcus[["do_lcus"]]=TRUE
) with
out[["waic"]]=TRUE
)In the output folder out[["rdir"]]/out[["id"]]
, you can find the files
model[["P_r"]] > 0
, contour.pdf, contour plot and progress contour plots (only if out[["pp"]] = TRUE
) of the Gibbs samples.For notational simplicity, the number of choice occasions \(T\) is assumend to be the same for each decision maker here. However, RprobitB allows for a different number of choice occasions for each decision maker.↩︎
We note that the model collapses to the (normally) mixed multinomial probit model if \(P_r>0\) and \(C=1\) and to the basic multinomial probit model if \(P_r=0\).↩︎
The wide data format presents each different covariate in a separate column. See the vignette of the mlogit package for an example.↩︎