Skip to main content

preorder4MLC: Pre-Order Based Multi-Label Classification

License: MIT Python

In multi-label classification (MLC) each instance can carry several labels at once (a song that is both happy and relaxed — as in the emotions dataset; an email tagged both business and legal — as in the enron dataset, both used in this paper). This repository introduces a method that predicts labels by first learning how labels compare rather than deciding each label in isolation — and that can abstain on labels it is unsure about instead of guessing.

📄 Code and full experimental results for: Robust Multi-Label Classification via Preference Learning — Vu-Linh Nguyen, Xuan-Truong Hoang, Sébastien Destercke, Cassio de Campos, Van-Nam Huynh (Nguyen and Hoang contributed equally). Machine Learning (Springer), 2026. <TODO: DOI once assigned>

Abstract. We explore how multi-label classification (MLC) tasks can be cast into order structure learning, exploiting the rich structure of orders to improve and robustify MLC. We formalise the transformation of MLC into an order structure learning and prediction task, study the prediction of Bayes-optimal order structures, and run experiments in settings where orders are especially beneficial: robust MLC under noisy and imbalanced labels, and MLC prediction with partial abstention.

What it does

The method is built around Bipartite Ordered Preference Orders (BOPOs). Instead of predicting each label independently, it works in three steps:

  1. Learn pairwise preferences. For every pair of labels, a calibrated classifier estimates the probability of their relative ordering.
  2. Search for the best order. Per instance, an integer linear program (ILP) combines those pairwise probabilities into a single coherent preference order — a pre-order or a partial-order — that minimises an expected loss (Hamming or Subset 0/1).
  3. Derive a prediction. The order is turned into one of three outputs: a plain binary vector, the preference order itself, or a partial-abstention vector that marks uncertain labels as "abstain".

An optional height constraint on the order yields eight inference algorithms in total (pre-/partial-order × Hamming/Subset × height 2/∅). We compare against four standard baselines: BR, CC, CLR, ECC.

              ┌──────────────────────┐
   training → │ K(K−1)/2 pairwise    │ → pairwise probabilities pᵢⱼ
              │ calibrated classif.  │
              └──────────────────────┘
                         │
                         ▼
              ┌──────────────────────┐
              │ per-instance ILP     │ → preference order
              │ search (cvxopt+GLPK) │   (pre- or partial-order)
              └──────────────────────┘
                         │
                         ▼
              ┌──────────────────────┐
              │ derive prediction    │ → BinaryVector
              │                      │   PreferenceOrder
              │                      │   PartialAbstention
              └──────────────────────┘

Quick start

# Install (editable, so scripts/ can import the package)
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
pip install -e .

# Run one dataset end-to-end
python scripts/train.py    --dataset emotions --results_dir results/run-dev
python scripts/evaluate.py --dataset emotions --results_dir results/run-dev

To reproduce every number and figure in the paper, see REPRODUCE.md — it covers the full pipeline, expected wall times, and the exact environment.

Datasets

Ten multi-label datasets are used: chd_49, emotions, scene, yeast, water_quality, humanpseaac, gpositivepseaac, plantpseaac, viruspseaac, and enron.

The first nine ARFFs are bundled under data/, so the pipeline runs end-to-end right after pip install. enron.arff (K=53) is downloaded separately — see REPRODUCE.md §2. CLI keys match preorder4mlc.config::ConfigManager.DATASET_CONFIGS.

Partial abstention

A partial-abstention prediction is a vector in {0, 1, −1} where −1 means "abstain" on that label. This lets the model stay silent where it is uncertain instead of forcing a 0/1 call. Two pairs of metrics capture the trade-off — recovery (did the abstentions cover the truth?) and abstention rate (how often did it abstain?):

ŷ = [1, 0, 1, −1, 0, −1]      y = [0, 0, 1, 1, 0, 0]

AREC = (0 + 1 + 1 + 1 + 1 + 1) / 6 = 4/6      # −1 counts as covering {0,1}
AABS = 2 / 6                                   # fraction abstained

Full definitions (AREC, AABS, REC, ABS) live in preorder4mlc.evaluation_metric.

Repository layout

preorder4mlc/            # Library package
├── config.py            # Run configuration + dataset registry
├── datasets4experiments.py   # ARFF loading, k-fold splits, label noise
├── base_classifiers.py  # Pairwise / calibrated classifier factory
├── estimator.py         # Uniform interface over RF / ETC / XGBoost / LightGBM
├── inference_models.py  # PredictBOPOs (BOPOs + BR / CC / CLR baselines)
├── searching_algorithms.py   # ILP search for pre- and partial-orders
├── training_orchestrator.py  # Training loop over learners × folds × algorithms
├── evaluation_metric.py # Example-, label-, ranking-, abstention-metrics
└── utils/               # Summaries, statistical tests, figures

scripts/                 # CLI entry points
├── train.py / evaluate.py          # BOPOs + CLR / BR / CC
├── train_ecc.py / evaluate_ecc.py  # ECC baseline
└── smoke_predict_bopos.py          # Behavior-preservation smoke test

data/                    # 9 bundled ARFFs (enron downloaded separately)
results/                 # Per-fold CSVs + aggregated tables
run.sh                   # End-to-end reproduction driver
REPRODUCE.md             # Step-by-step reproduction recipe

Citation

If you use this code, please cite the paper (see CITATION.cff):

@article{nguyen2026robust,
  title     = {Robust Multi-Label Classification via Preference Learning},
  author    = {Nguyen, Vu-Linh and Hoang, Xuan-Truong and Destercke, S{\'e}bastien and de Campos, Cassio and Huynh, Van-Nam},
  journal   = {Machine Learning},
  publisher = {Springer},
  year      = {2026},
}

License

Released under the MIT License.

Metadata

Release files for preorder4mlc 1.0.0

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

Source distribution (sdist)

Source distribution for preorder4mlc 1.0.0
File Size Uploaded
preorder4mlc-1.0.0.tar.gz 62.4 kB Details

Built distribution (wheel)

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

Total release size: 121.5 kB

Release files / preorder4mlc-1.0.0.tar.gz

Download URL preorder4mlc-1.0.0.tar.gz
Size 62.4 kB
Tags Source
SHA-256 checksum
How to use checksums
96c15390cf7636b7b1063b3b73f5fff6a99b6e1ebd70017a3ba5096acf94ae7e
BLAKE2b-256 checksum
How to use checksums
079c1f6cf56d389181ce978933f1c39a9307a1b208ed1eb50411fd065550f3bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Aug 26, 2026.

Transparency log

Release files / preorder4mlc-1.0.0-py3-none-any.whl

Download URL preorder4mlc-1.0.0-py3-none-any.whl
Size 59.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7b2142f24077225f78012caa18c4f484e79ffc500ca0101e3e74f18ed825ec80
BLAKE2b-256 checksum
How to use checksums
c8d22a2f22b4de71ae8ab522e4a68892829d8f3621775f48cbac8626d72b43de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Aug 26, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.2

2 release files

1.0.1

2 release files

This release

1.0.0 This release

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