biogeme.expressions.ordered module

class biogeme.expressions.ordered.OrderedBase(eta, cutpoints, y, categories=None, neutral_labels=None, enforce_order=True, eps=1e-12)[source]

Bases: Expression

Base class for ordered-response models (logit and probit).

This class implements the common logic for ordered discrete-choice models. Given a latent variable \(\eta_n\) and ordered cutpoints \(\tau_1 < \tau_2 < \dots < \tau_{K-1}\), the probability of observing category \(y_k\) is

\[P(y = y_k \mid \eta, \tau) = \mathrm{CDF}(\tau_k - \eta) - \mathrm{CDF}(\tau_{k-1} - \eta),\]

where \(\tau_0 = -\infty\) and \(\tau_K = +\infty\).

Subclasses must implement the appropriate cumulative distribution function (CDF), either logistic (logit) or Gaussian (probit).

This class returns per-observation probabilities. To obtain per-observation log-likelihoods, use the corresponding log-variants (e.g., OrderedLogLogit).

Parameters:
  • eta (Expression) – Expression defining the latent variable \(\eta_n\).

  • cutpoints (list[Expression]) – List of expressions defining the cutpoints (length K-1).

  • y (Expression) – Expression defining the observed categorical response.

  • categories (list[float] | tuple[float, ...] | None) – Ordered list of category labels (e.g. [1, 2, 3, 4, 5]). If None, defaults to [0, 1, ..., K-1].

  • enforce_order (bool) – If True, ensures that cutpoints are monotonically increasing, using a softplus transform (JAX) or sorting (PyTensor).

  • eps (float) – Lower bound for probabilities to avoid numerical issues.

  • neutral_labels (list[float] | tuple[float, ...] | None) – Labels that may appear in the data and must be treated as “always valid”; their contribution is probability 1. Useful to avoid crashes on placeholder/missing/special codes.

Examples

Ordered Logit with 5 Likert levels (valid labels 1..5) and two neutral codes 98/99:

income = Variable('Income')
age = Variable('Age')
beta_income = Beta('beta_income', 0, None, None, 0)
beta_age = Beta('beta_age', 0, None, None, 0)

eta = beta_income * income + beta_age * age

# Four thresholds for five ordered responses
tau1 = Beta('tau1', -1, None, None, 0)
tau2 = Beta('tau2',  0, None, None, 0)
tau3 = Beta('tau3',  1, None, None, 0)
tau4 = Beta('tau4',  2, None, None, 0)

y = Variable('Satisfaction')  # coded as 1, 2, 3, 4, 5, 98, 99

model = OrderedLogit(
    eta=eta,
    cutpoints=[tau1, tau2, tau3, tau4],
    y=y,
    categories=[1, 2, 3, 4, 5],
    neutral_labels=[98, 99],
)

prob_vec = model.recursive_construct_pymc_model_builder()

Ordered Probit with the same structure:

model = OrderedProbit(
    eta=eta,
    cutpoints=[tau1, tau2, tau3, tau4],
    y=y,
    categories=[1, 2, 3, 4, 5],
    neutral_labels=[98, 99],
)
recursive_construct_jax_function(numerically_safe)[source]

Build a JAX-compatible function returning per-observation probabilities.

Parameters:

numerically_safe (bool) – Whether to use numerically stable operators.

Return type:

Callable[[Array, Array, Array, Array], array]

Returns:

A callable taking model parameters and one observation, and returning the probability of the observed category.

recursive_construct_pymc_model_builder()[source]

Build a PyTensor-compatible function returning per-observation probabilities.

Return type:

PymcModelBuilderType

Returns:

Callable taking a pandas DataFrame and returning a PyTensor variable of probabilities of the observed categories.

class biogeme.expressions.ordered.OrderedLogLogit(eta, cutpoints, y, categories=None, neutral_labels=None, enforce_order=True, eps=1e-12)[source]

Bases: OrderedLogit

Ordered response model using logistic CDF, returning per-observation log-likelihoods.

Parameters:
  • eta (Expression)

  • cutpoints (list[Expression])

  • y (Expression)

  • categories (list[float] | tuple[float, ...] | None)

  • neutral_labels (list[float] | tuple[float, ...] | None)

  • enforce_order (bool)

  • eps (float)

recursive_construct_jax_function(numerically_safe)[source]

Build a JAX-compatible function returning per-observation probabilities.

Parameters:

numerically_safe (bool) – Whether to use numerically stable operators.

Return type:

Callable[[Array, Array, Array, Array], array]

Returns:

A callable taking model parameters and one observation, and returning the probability of the observed category.

recursive_construct_pymc_model_builder()[source]

Build a PyTensor-compatible function returning per-observation probabilities.

Return type:

PymcModelBuilderType

Returns:

Callable taking a pandas DataFrame and returning a PyTensor variable of probabilities of the observed categories.

class biogeme.expressions.ordered.OrderedLogProbit(eta, cutpoints, y, categories=None, neutral_labels=None, enforce_order=True, eps=1e-12)[source]

Bases: OrderedProbit

Ordered response model using probit CDF, returning per-observation log-likelihoods.

Parameters:
  • eta (Expression)

  • cutpoints (list[Expression])

  • y (Expression)

  • categories (list[float] | tuple[float, ...] | None)

  • neutral_labels (list[float] | tuple[float, ...] | None)

  • enforce_order (bool)

  • eps (float)

recursive_construct_jax_function(numerically_safe)[source]

Build a JAX-compatible function returning per-observation probabilities.

Parameters:

numerically_safe (bool) – Whether to use numerically stable operators.

Return type:

Callable[[Array, Array, Array, Array], array]

Returns:

A callable taking model parameters and one observation, and returning the probability of the observed category.

recursive_construct_pymc_model_builder()[source]

Build a PyTensor-compatible function returning per-observation probabilities.

Return type:

PymcModelBuilderType

Returns:

Callable taking a pandas DataFrame and returning a PyTensor variable of probabilities of the observed categories.

class biogeme.expressions.ordered.OrderedLogit(eta, cutpoints, y, categories=None, neutral_labels=None, enforce_order=True, eps=1e-12)[source]

Bases: OrderedBase

Ordered response model using the logistic cumulative distribution function.

Returns per-observation probabilities.

Parameters:
  • eta (Expression)

  • cutpoints (list[Expression])

  • y (Expression)

  • categories (list[float] | tuple[float, ...] | None)

  • neutral_labels (list[float] | tuple[float, ...] | None)

  • enforce_order (bool)

  • eps (float)

class biogeme.expressions.ordered.OrderedProbit(eta, cutpoints, y, categories=None, neutral_labels=None, enforce_order=True, eps=1e-12)[source]

Bases: OrderedBase

Ordered response model using the standard normal cumulative distribution function.

Returns per-observation probabilities.

Parameters:
  • eta (Expression)

  • cutpoints (list[Expression])

  • y (Expression)

  • categories (list[float] | tuple[float, ...] | None)

  • neutral_labels (list[float] | tuple[float, ...] | None)

  • enforce_order (bool)

  • eps (float)