Skip to main content

Multe: Multichoice Logit Estimation

Python Version License: MIT Tests PyPI version

A Python library for estimating discrete choice models where agents can select either single alternatives or unordered pairs of alternatives.

This implements the model as described in Ophem, H.V., Stam, P. and Praag, B.V., 1999. Multichoice Logit: Modeling Incomplete Preference Rankings of Classical Concerts. Journal of Business & Economic Statistics, 17(1), pp.117-128.

Installation

Install from PyPI:

pip install multe

Or install from source for development:

git clone https://github.com/tmonk/multe.git
cd multe
pip install -e .

Quick Start

from multe import MultichoiceLogit, simulate_data

# Generate synthetic data
X, y_single, y_dual, true_beta = simulate_data(N=1000, J=4, K=3, seed=42)

# Fit model
model = MultichoiceLogit(num_alternatives=4, num_covariates=3)
model.fit(X, y_single, y_dual)

# Access fitted coefficients
print(model.coef_)  # Shape: (J-1, K) = (3, 3)

See examples/simple_fit_example.py for a complete example, or examples/basic_example.py for advanced usage.

Model

Agents choose from J alternatives. The utility for agent i and alternative j is:

U_ij = V_ij + epsilon_ij
V_ij = X_i * beta_j
epsilon_ij ~ Gumbel(0, 1)

Each agent makes either:

  • Single choice: Select the alternative with maximum utility
  • Dual choice: Select the top two alternatives as an unordered pair

The mixing probability between single and dual choices is determined by the parameter mix_ratio in simulation.

Probabilities

Single choice (multinomial logit):

P(choose j) = exp(V_ij) / sum_k exp(V_ik)

Dual choice (inclusion-exclusion principle):

P(choose {s,t}) = P(U_s > max_k≠s U_k ∪ U_t > max_k≠t U_k)

Identification

The model fixes beta_0 = 0 for identification, so it estimates (J-1) × K parameters.

Data Format

  • X: Covariates (N, K)
  • y_single: Binary matrix (N, J) where y_single[i,j]=1 if agent i chose alternative j
  • y_dual: Binary tensor (N, J, J) where y_dual[i,s,t]=1 if agent i chose pair {s,t} with s<t

Each agent must have exactly one choice (one entry in either y_single or y_dual).

Performance

Fully vectorized implementation for fast estimation and simulation:

Estimation:

  • ~10ms per 1000 observations (optimization)
  • Example: N=10,000, J=5, K=4 completes in ~0.1s

Recommended optimizer: L-BFGS-B

Run benchmarks: python examples/benchmark.py

API Reference

MultichoiceLogit(num_alternatives, num_covariates)

Model class with methods:

  • fit(X, y_single, y_dual, method='L-BFGS-B') - Fit model using MLE (recommended)
    • Returns self with fitted coef_ attribute
    • Stores optimization details in optimization_result_
  • neg_log_likelihood(flat_beta, X, y_single, y_dual) - Negative log-likelihood
  • gradient(flat_beta, X, y_single, y_dual) - Analytical gradient
  • compute_standard_errors(flat_beta, X, y_single, y_dual) - Standard errors

simulate_data(N, J, K, true_beta=None, mix_ratio=0.5, seed=42)

Generate synthetic data following the RUM framework.

Returns: X, y_single, y_dual, true_beta

Acknowledgements

Many thanks to Alan Manning for his guidance and support with this project.

Metadata

Release files for multe 3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for multe 3
File Size Uploaded
multe-3.tar.gz 24.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for multe 3
File Interpreter ABI Platform
multe-3-py3-none-any.whl Python 3 none any Details

Total release size: 35.3 kB

Release files / multe-3.tar.gz

Download URL multe-3.tar.gz
Size 24.4 kB
Tags Source
SHA-256 checksum
How to use checksums
81c15b1e9ed2a846a100dcd3f4ade76ea9388fcdbf8b215deeee76158ef4fd32
BLAKE2b-256 checksum
How to use checksums
3749de84b9a945a5570e9127c94f657181a9a2904d6069abd24cc1dd18bc2a41
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 24, 2025.

Transparency log

Release files / multe-3-py3-none-any.whl

Download URL multe-3-py3-none-any.whl
Size 10.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c32dbaf6e30bd992cfb11c81b8eec06920b39e84a4f5b3ade9a19346f11684ec
BLAKE2b-256 checksum
How to use checksums
ed727b7ca7c70bb71a0553b2cc309bb9388e777744631455423be79031df44e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 24, 2025.

Transparency log

Release history Release notifications | RSS feed

4

2 release files

This release

3 This release

2 release files

2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page