Multe: Multichoice Logit Estimation
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]=1if agent i chose alternative j - y_dual: Binary tensor (N, J, J) where
y_dual[i,s,t]=1if 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
selfwith fittedcoef_attribute - Stores optimization details in
optimization_result_
- Returns
neg_log_likelihood(flat_beta, X, y_single, y_dual)- Negative log-likelihoodgradient(flat_beta, X, y_single, y_dual)- Analytical gradientcompute_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)
| File | Size | Uploaded | |
|---|---|---|---|
| multe-3.tar.gz | 24.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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