Optimal Model Trees using OR-Tools
Project description
OptimalModelTree (OMT)
A mixed-integer optimization-based decision tree framework for classification and regression.
OMT implements Optimal Model Trees, where both the tree structure and the prediction models at the leaves are learned jointly by solving a Mixed-Integer Linear Programming (MILP) problem.
⸻
🚀 Features
- Globally optimized decision tree construction via MILP
- Supports:
- Binary classification
- Multiclass classification
- Regression
- Parallel and oblique decision boundaries
- Sparse and regularized leaf models
- Warm-start support for faster optimization
- Scikit-learn-style API (fit, predict, score)
⸻
📦 Installation
Install the latest release from PyPI:
pip install optimal-omt
⸻
⚙️ Solver Backend
OMT is built on top of Google OR-Tools, which provides interfaces to several Mixed-Integer Linear Programming (MILP) solvers.
By default, OMT uses SCIP, an open-source solver that is distributed with OR-Tools and requires no additional installation.
Commercial solvers such as Gurobi are also supported and can substantially improve performance on larger optimization problems. However, Gurobi is not included with OMT and must be installed and licensed separately.
To use Gurobi:
- Obtain a valid Gurobi license.
- Install the Python interface:
pip install gurobipy
- Configure OMT to use Gurobi as the optimization backend.
If Gurobi is not installed, OMT automatically falls back to SCIP.
Note: OMT solves optimization problems exactly and is therefore intended primarily for small-to-medium datasets.
⸻
🧪 Minimal Working Example
The following example trains an Optimal Model Tree on the Iris dataset from scikit-learn.
from sklearn.datasets import load_iris as df
from sklearn.model_selection import train_test_split
from omt import OptimalModelTreeClassifier
X, y = df(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.4,
random_state=42,
stratify=y
)
clf = OptimalModelTreeClassifier(splits=3,solver='SCIP',timeout=0.3)
clf.fit(X_train, y_train)
print("Test accuracy:", clf.score(X_test, y_test))
clf.PlotTree()
Example output:
Test accuracy: 0.967
[Node 0] 2 < 5.0000
├── [Node 1] 3 < 1.6000
│ ├── [Node 3] Class 0: -2*1.8182 + 4.4545 | Class 1: 2*1.8182 - 4.4545 | Class 2: -1.0000
│ └── [Node 4] Class 0: -22.6000 | Class 1: -1.0000 | Class 2: 1.0000
└── [Node 2] 1 < 2.3000
├── [Node 5] Class 0: -1.0000 | Class 1: -1.0000 | Class 2: 22.6000
└── [Node 6] Class 0: -22.6000 | Class 1: -1.0000 | Class 2: 1.0000
⸻
📚 Citation
If you use OMT in your research, please cite:
@article{roselli2026experiments,
title={Experiments with optimal model trees: SF Roselli et al.},
author={Roselli, Sabino Francesco and Frank, Eibe},
journal={Scientific Reports},
volume={16},
number={1},
pages={19545},
year={2026},
publisher={Nature Publishing Group UK London}
url = {https://github.com/sabinoroselli/OptimalModelTree}
}
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file optimal_omt-0.1.6.tar.gz.
File metadata
- Download URL: optimal_omt-0.1.6.tar.gz
- Upload date:
- Size: 9.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
068ed5903444887992fc1b85017387af09bd07f528b77159d47373dd82289460
|
|
| MD5 |
5bf91f9c485723b7e6e58ed146bf9ffb
|
|
| BLAKE2b-256 |
5508691cc067ed4d57033a17b6f391485896f4ba95a2cc6dec308975d9b9e5eb
|
Provenance
The following attestation bundles were made for optimal_omt-0.1.6.tar.gz:
Publisher:
release.yml on sabinoroselli/OptimalModelTree
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
optimal_omt-0.1.6.tar.gz -
Subject digest:
068ed5903444887992fc1b85017387af09bd07f528b77159d47373dd82289460 - Sigstore transparency entry: 2061841388
- Sigstore integration time:
-
Permalink:
sabinoroselli/OptimalModelTree@6f8c38b6163292f49e6aa647b16624e4098d0dd9 -
Branch / Tag:
refs/tags/v0.1.6 - Owner: https://github.com/sabinoroselli
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6f8c38b6163292f49e6aa647b16624e4098d0dd9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file optimal_omt-0.1.6-py3-none-any.whl.
File metadata
- Download URL: optimal_omt-0.1.6-py3-none-any.whl
- Upload date:
- Size: 40.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1176b98513ceb40f3f4866d70288f34133eb8a0a932005fce8c9659dd15caf64
|
|
| MD5 |
cc34d9c9a5e30168927a6508c62026e8
|
|
| BLAKE2b-256 |
269f02c6a4d11cb32b4a492d5cc4634420ac8863699847ea5997dd55903f7efb
|
Provenance
The following attestation bundles were made for optimal_omt-0.1.6-py3-none-any.whl:
Publisher:
release.yml on sabinoroselli/OptimalModelTree
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
optimal_omt-0.1.6-py3-none-any.whl -
Subject digest:
1176b98513ceb40f3f4866d70288f34133eb8a0a932005fce8c9659dd15caf64 - Sigstore transparency entry: 2061842129
- Sigstore integration time:
-
Permalink:
sabinoroselli/OptimalModelTree@6f8c38b6163292f49e6aa647b16624e4098d0dd9 -
Branch / Tag:
refs/tags/v0.1.6 - Owner: https://github.com/sabinoroselli
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6f8c38b6163292f49e6aa647b16624e4098d0dd9 -
Trigger Event:
push
-
Statement type: