Skip to main content

TorchDCM

TorchDCM logo

PyTorch-first discrete choice model estimation and econometric inference.

Installation | Quick Start | Examples | Model Zoo | Development

PyPI Python PyTorch Models Benchmarks Status

TorchDCM is the importable Python package for discrete choice model estimation. This repository is intentionally package-first: it keeps the reusable torchdcm implementation, unit tests, examples, and packaging metadata in one small repo that users can install and import directly.

The paper's reproducibility repository is separate and contains benchmark runners, aligned datasets, validation utilities, and committed outputs:

torchdcm-paper: reproduce the validation and benchmark results

Why TorchDCM

Goal What TorchDCM Provides
PyTorch-native estimation Vectorized likelihoods written around tensors and automatic differentiation.
Econometric outputs Classic, robust, and cluster covariance; WTP and elasticity helpers.
Model coverage MNL, NL, CNL, mixed logit, WTP-space, latent class, scaled, ordered, and hybrid choice.
Reusable package Clean import surface, executed model notebooks, and package-level tests.
Benchmark companion Full comparisons live in torchdcm-paper and import this package.

Installation

python -m pip install torchdcm

For local development:

python -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
python -m pip install -e ".[dev]"
pytest

Quick Start

import torch

from torchdcm import Beta, ChoiceDataset, MultinomialLogit, UtilitySpec
from torchdcm.datasets import make_swissmetro_like

df = make_swissmetro_like(n_obs=300, seed=7)
data = ChoiceDataset.from_wide(
    df,
    alternatives=["TRAIN", "SM", "CAR"],
    choice="choice",
    variables={
        "time": {"TRAIN": "time_train", "SM": "time_sm", "CAR": "time_car"},
        "cost": {"TRAIN": "cost_train", "SM": "cost_sm", "CAR": "cost_car"},
    },
    availability={
        "TRAIN": "avail_train",
        "SM": "avail_sm",
        "CAR": "avail_car",
    },
    individual_id="person_id",
)

spec = UtilitySpec()
spec.utility(
    "TRAIN",
    Beta("ASC_TRAIN")
    + Beta("B_TIME", init=-0.01) * "time"
    + Beta("B_COST", init=-0.1) * "cost",
)
spec.utility(
    "SM",
    Beta("B_TIME", init=-0.01) * "time"
    + Beta("B_COST", init=-0.1) * "cost",
)
spec.utility(
    "CAR",
    Beta("ASC_CAR")
    + Beta("B_TIME", init=-0.01) * "time"
    + Beta("B_COST", init=-0.1) * "cost",
)

device = "cuda" if torch.cuda.is_available() else "cpu"
result = MultinomialLogit(spec, device=device).fit(data, cov_type="cluster", groups="person_id")
print(result.summary())

summary() renders an organized console report covering the model and data, convergence diagnostics, fit statistics, inference, alternative shares, and parameter estimates. The same structured report can be inspected as tables or saved as a reproducible artifact directory:

report = result.report(cov_type="cluster", confidence_level=0.95)
parameter_table = report.parameters

result.save_report(
    "outputs/swissmetro_mnl",
    formats=["html", "json", "csv", "latex", "text"],
)

The output directory contains a readable HTML report, a machine-readable JSON record, parameter/covariance/correlation CSV files, a LaTeX fragment, and a plain-text summary. The convergence section records the exact L-BFGS stopping condition, the internal-parameter gradient infinity norm, and that norm divided by the number of observations. Function- or step-tolerance stops are reported as converged when the normalized gradient does not exceed 1e-5; iteration limits, non-finite values, and larger normalized gradients remain warnings.

All estimators accept a standard PyTorch-style device argument. Passing device="cuda" moves estimation, prediction, simulated likelihoods, and covariance calculations for that model to CUDA when your PyTorch installation has GPU support.

Executed Examples

The examples/ directory contains self-contained Jupyter notebooks for every public model family. Each notebook presents the model's mathematical formulation, builds a nontrivial specification, runs full estimation, and retains its rendered HTML report. They were executed on an AMD Ryzen 9 9950X3D CPU (16 cores), 64 GB RAM, and an NVIDIA GeForce RTX 5090 GPU (32 GB VRAM), running Ubuntu 24.04.4 with PyTorch 2.12.1 and CUDA 13.0. The examples automatically select CUDA when it is available and can be changed to CPU by setting device = "cpu".

Model Executed notebook
Multinomial logit 01_multinomial_logit.ipynb
Nested logit 02_nested_logit.ipynb
Cross-nested logit 03_cross_nested_logit.ipynb
Mixed logit 04_mixed_logit.ipynb
WTP-space mixed logit 05_wtp_space_mixed_logit.ipynb
Alternative-scaled MNL 06_scaled_multinomial_logit.ipynb
Covariate-scaled MNL 07_covariate_scaled_multinomial_logit.ipynb
Ordered logit 08_ordered_logit.ipynb
Ordered probit 09_ordered_probit.ipynb
Latent-class logit 10_latent_class_logit.ipynb
Error-components logit 11_error_components_logit.ipynb
Hybrid choice 12_hybrid_choice.ipynb
Panel mixed logit 13_panel_mixed_logit.ipynb

Model Zoo

The current package includes:

  • multinomial logit / conditional logit;
  • nested logit and cross-nested logit;
  • mixed logit, WTP-space mixed logit, and error-components logit;
  • latent-class logit;
  • scaled and covariate-scaled multinomial logit;
  • ordered logit and ordered probit;
  • hybrid choice with latent variables and Gaussian measurement indicators;
  • classic, robust, and cluster covariance estimates;
  • WTP and elasticity helpers.

Repository Layout

Path Purpose
torchdcm/ Importable package implementation.
tests/ Package-level unit tests.
examples/ Executed Jupyter notebooks covering every public model family.
docs/assets/ GitHub README logo and cover assets.
pyproject.toml Packaging metadata and dependencies.

Development

python -m pip install -e ".[dev]"
pytest

Benchmark and validation work should happen in the companion repository:

git clone https://github.com/mbc96325/torchdcm-paper.git

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

torchdcm-0.1.1.tar.gz (70.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

torchdcm-0.1.1-py3-none-any.whl (84.8 kB view details)

Uploaded Python 3

File details

Details for the file torchdcm-0.1.1.tar.gz.

File metadata

  • Download URL: torchdcm-0.1.1.tar.gz
  • Upload date:
  • Size: 70.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for torchdcm-0.1.1.tar.gz
Algorithm Hash digest
SHA256 2358f716e54f4fb40e3a7cba2f0697b25ec8bc6a367e883e336592388d038d68
MD5 46017375e517c6f49f2a768034709dde
BLAKE2b-256 89aca6a4aaba700a4aef7369d1c9d267aec720d25159bfc2673d9ee06caa4ecb

See more details on using hashes here.

Provenance

The following attestation bundles were made for torchdcm-0.1.1.tar.gz:

Publisher: publish.yml on mbc96325/torchdcm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file torchdcm-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: torchdcm-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 84.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for torchdcm-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f77d1c90f2de6bf0c9cb5c966eeed130e6e060609c63d18df7f48760b63c2d2a
MD5 a695862ac038b6827491e000dd2d3f26
BLAKE2b-256 ec4cbf3de50b3e90354b35e4d017060a060ffc4631ae6d75e7bc7e8fe7b1aac1

See more details on using hashes here.

Provenance

The following attestation bundles were made for torchdcm-0.1.1-py3-none-any.whl:

Publisher: publish.yml on mbc96325/torchdcm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page