# Ordered Probit Estimation with Constrained Maximum Likelihood

### Example introduction

Suppose we have a dependent variable that is observed in several ordered categories. We might estimate coefficients of a regression on this variable using the ordered probit model

$$y^* = x\beta + \epsilon$$

where

$$y = \begin{cases} 1 \text{ if } -\infty \lt y^* \lt \tau_2\\ 2 \text{ if } \tau_2 \le y^* \lt \tau_3\\ \ \ \ \ \vdots\\ K \text{ if } \tau_K \le y^* \lt +\infty\\ \end{cases}$$ and $$-\infty \lt \tau_2 \lt \tau_3 \lt \cdots \lt \tau_K \lt +\infty$$

Assuming

$$\epsilon \sim N(0,1)$$

we have

$$P(y = k) = \Phi(\tau_k - x\beta) - \Phi(\tau_{k-1} - x\beta)$$

where $\Phi$ represents the normal cumulative distribution function. The log-likelihood for this model is

$$lnL(\beta,\tau) = \sum_{k=1}^{K} \sum_{y_1=k} ln[\Phi(\tau_k - x_i\beta) - \Phi(\tau_{k-1} - x_i\beta)]$$

## Step 1: Load the CMLMT library

// Make cmlmt library functions available
library cmlmt;

Our data source is a CSV file, containing four variables. The first column is the dependent variable and the remaining three will be the independent variables.

// Load all four variables into one matrix
data = loadd(getGAUSSHome() $+ "pkgs/cmlmt/examples/cmlmt_ordered_probit.csv"); // Create separate matrices for dependent // and independent variables y = data[., 1]; X = data[., 2:4]; ## Step 3: Starting parameters Our model has two characteristics which make it less convenient to store our parameters as a single vector. 1. Our log-likelihood function has two vectors which we will want to reference separately. 2. We do not want to estimate the first and last elements of$\tau\$.

In order to handle this, we will place our parameters inside of a PV structure. The PV structure allows us to 'pack' our vectors into the structure and retrieve them by name. It also allows us to apply a mask so that some of the parameters will not be estimated.

// Declare 'p' to be a PV structure
// and initialize it
struct PV p;
p = pvCreate();

// Pack the starting vectors for 'beta'
// into 'p' so that we can reference it by name
beta_strt = { 0.5, 0.5, 0.5 };
p = pvPack(p, beta_strt, "beta");

// Pack the starting values for 'tau'
// with a mask, telling CMLMT not to
// estimate the first and last elements of 'tau'
// Note the use of 'pvPackM' instead of 'pvPack'
mask = { 0, 1, 1, 1, 0 };
tau_strt = { -30, -1, 0, 1, 30 };
p = pvPackM(p, tau_strt, "tau", mask);

## Step 4: The log-likelihood procedure

Now that we have set up our parameters, it is time to look at how we will use them in the log-likelihood procedure. The log-likelihood procedure has three sets of inputs

1. The first input is the parameter vector or PV structure containing the model parameters.
2. Next comes any data your function needs other than the parameters.
3. The final input is an indicator vector which CMLMT uses to tell your function whether to compute the gradient or Hessian. For this example, we will ignore the indicator vector.
// The log-likelihood procedure
proc (1) = orderedProbit(p, y, X, ind);
local mu, tau_, beta_, emu, eml;

// Declare 'mm' to be a modelResults
// structure to hold the function value
struct modelResults mm;

// Extract the current 'tau'
// and 'beta' vectors
tau_ = pvUnpack(p, "tau");
beta_ = pvUnpack(p, "beta");

mu = X * beta_;
eml = tau_[y] - mu;
emu = tau_[y+1] - mu;

// Assign the log-likelihood value to the
// 'function' member of the modelResults structure
mm.function = ln(cdfn(emu) - cdfn(eml));

// Return the model results structure
retp(mm);
endp;

## Step 5: Apply the inequality constraints

In order to enforce the inequality

$$-\infty \lt \tau_2 \lt \tau_3 \lt \cdots \lt \tau_K \lt +\infty$$

we will set this inequality constraint equation

$$-1\tau_2 + 1\tau_3 + 0\tau_4 \ge 0\\ 0\tau_2 + -1\tau_3 + 1\tau_4 \ge 0$$

// Declare 'ctl' to be a cmlmtControl structure
// and fill with default values
struct cmlmtControl ctl;
ctl = cmlmtControlCreate();

/*
** The dot product of each row of ctl.C
** with the parameter vector must be
** greater than or equal to the corresponding
** row of ctl.D
**
** Note that the first 3 elements of our parameter
** vector are 'beta' and the final 3 are the middle
** 3 elements of 'tau', because the mask keeps
** the first and last elements of 'tau' from
** the estimation.
*/
ctl.C = { 0 0 0 -1  1 0,
0 0 0  0 -1 1 };
ctl.D = { 0,
0 };

## Step 6: Run the estimation and print results

The cmlmt procedure will take five inputs

1. A pointer to the log-likelihood procedure.
2. The PV structure containing the model parameters. 3-4. The y vector and X matrix.
3. The cmlmtControl structure, containing the inequality constraints.
// Declare 'out' to be a cmlmtResults structure
// to hold the results of the estimation
struct cmlmtResults out;

// Perform estimation and print results
out = cmlmt(&orderedProbit, p, y, X, ctl);
call cmlmtPrt(out);

## Results

After running all of the above code, the following report will be printed

===============================================================================
CMLMT Version 3.0.0
===============================================================================

return code =    0
normal convergence

Log-likelihood      -14.1623
Number of cases     200

Covariance of the parameters computed by the following method:
ML covariance matrix
Parameters    Estimates     Std. err.  Est./s.e.  Prob.    Gradient
---------------------------------------------------------------------
beta[1,1]    4.2996        0.2816      15.268   0.0000      0.0000
beta[2,1]    5.1704        0.3275      15.787   0.0000      0.0000
beta[3,1]    6.1077        0.2931      20.838   0.0000      0.0000
tau[2,1]   -10.3687        0.6380     -16.251   0.0000      0.0000
tau[3,1]     0.2012        0.2833       0.710   0.4776      0.0000
tau[4,1]    10.2323        0.6439      15.890   0.0000      0.0000

Correlation matrix of the parameters
1        0.5337       0.37587      -0.56933       0.12117       0.55204
0.53365             1       0.56732      -0.71255     -0.029152       0.66281
0.37587       0.56732             1      -0.62297     -0.010140       0.61754
-0.56933      -0.71255      -0.62297             1     -0.013120      -0.59049
0.12117     -0.029152     -0.010140     -0.013120             1      0.016093
0.55204       0.66281       0.61754      -0.59049      0.016093             1

Wald Confidence Limits

0.95 confidence limits
Parameters  Estimates     Lower Limit   Upper Limit   Gradient
----------------------------------------------------------------------
beta[1,1]    4.2996        3.7442        4.8551        0.0000
beta[2,1]    5.1704        4.5245        5.8164        0.0000
beta[3,1]    6.1077        5.5296        6.6858        0.0000
tau[2,1]   -10.3687      -11.6271       -9.1104        0.0000
tau[3,1]     0.2012       -0.3575        0.7599        0.0000
tau[4,1]    10.2323        8.9623       11.5023        0.0000

### Have a Specific Question?

Get a real answer from a real person

### Need Support?

Get help from our friendly experts.