Skip to main content

Open In Colab test Downloads

PyTabKit: Tabular ML models and benchmarking (NeurIPS 2024)

Paper Documentation RealMLP-TD-S standalone implementation Grinsztajn et al. benchmark code Data archive

PyTabKit provides scikit-learn interfaces for modern tabular classification and regression methods benchmarked in our paper, see below. It also contains the code we used for benchmarking these methods on our benchmarks.

Meta-test benchmark results

When (not) to use pytabkit

  • To get the best possible results:
    • Generally we recommend AutoGluon for the best possible results, though it does not include all the models from pytabkit. AutoGluon 1.4 includes RealMLP (though not in a default configuration) and TabM (in the "extreme" preset for <= 30K samples).
    • To get the best possible results from pytabkit, we recommend using Ensemble_HPO_Classifier(n_cv=8, use_full_caruana_ensembling=True, use_tabarena_spaces=True, n_hpo_steps=50) with a val_metric_name corresponding to your target metric (e.g., class_error, cross_entropy, brier, 1-auc_ovr), or the corresponding Regressor. (This might take very long to fit.)
    • For only a single model, we recommend using RealMLP_HPO_Classifier(n_cv=8, hpo_space_name='tabarena-new', use_caruana_ensembling=True, n_hyperopt_steps=50), also with val_metric_name as above, or the corresponding Regressor.
  • Models: TabArena also includes some newer models like RealMLP and TabM with more general preprocessing (missing numericals, text, etc.), as well as very good boosted tree implementations. pytabkit is currently still easier to use and supports vectorized cross-validation for RealMLP, which can significantly speed up the training.
  • Benchmarking: While pytabkit can be good for quick benchmarking for development, for method evaluation we recommend TabArena.

Installation (new in 1.4.0: optional model dependencies)

pip install pytabkit[models]
  • RealMLP (and TabM) can be used without the [models] part.
  • For xRFM on GPU, faster kernels will be used if you install kermac[cu12] or kermac[cu11] (depending on your CUDA version).
  • The KumoTabular wrapper needs the structured-data-models package, which is only installed with [models] for Python >= 3.11 (it also requires torch>=2.7).
  • If you want to use TabR, you have to manually install faiss, which is only available on conda.
  • Please install torch separately if you want to control the version (CPU/GPU etc.)
  • On macOS, LightGBM and XGBoost need OpenMP (e.g., brew install libomp). Using PyTorch-based models (like RealMLP) and LightGBM/XGBoost in the same process (e.g., in the ensembles) can then crash with a segmentation fault, since the pip wheels load two different OpenMP runtimes. Installing pytorch, lightgbm, and xgboost from conda-forge avoids this.
  • Use pytabkit[models,autogluon,extra,hpo,bench,dev] to install additional dependencies for the other models, AutoGluon models, extra preprocessing, hyperparameter optimization methods beyond random search (hyperopt/SMAC), the benchmarking part, and testing/documentation. For the hpo part, you might need to install swig (e.g. via pip) if the build of pyrfr fails. See also the documentation. To run the data download for the meta-train benchmark, you need one of rar, unrar, or 7-zip to be installed on the system.

Using the ML models

Most of our machine learning models are directly available via scikit-learn interfaces. For example, you can use RealMLP-TD for classification as follows:

from pytabkit import RealMLP_TD_Classifier

model = RealMLP_TD_Classifier()  # or TabR_S_D_Classifier, CatBoost_TD_Classifier, etc.
model.fit(X_train, y_train)
model.predict(X_test)

The code above will automatically select a GPU if available, try to detect categorical columns in dataframes, preprocess numerical variables and regression targets (no standardization required), and use a training-validation split for early stopping. All of this (and much more) can be configured through the constructor and the parameters of the fit() method. For example, it is possible to do bagging (ensembling of models on 5-fold cross-validation) simply by passing n_cv=5 to the constructor. Here is an example for some of the parameters that can be set explicitly:

from pytabkit import RealMLP_TD_Classifier

model = RealMLP_TD_Classifier(device='cpu', random_state=0, n_cv=1, n_refit=0,
                              n_epochs=256, batch_size=256, hidden_sizes=[256] * 3,
                              val_metric_name='cross_entropy',
                              use_ls=False,  # for metrics like AUC / log-loss
                              lr=0.04, verbosity=2)
model.fit(X_train, y_train, X_val, y_val, cat_col_names=['Education'])
model.predict_proba(X_test)

See this notebook for more examples. Missing numerical values are currently not allowed and need to be imputed beforehand.

Available ML models

Our ML models are available in up to three variants, all with best-epoch selection:

  • library defaults (D)
  • our tuned defaults (TD)
  • random search hyperparameter optimization (HPO), sometimes also tree parzen estimator (HPO-TPE) or weighted ensembling (Ensemble)

We provide the following ML models:

Post-hoc calibration and refinement stopping

For using post-hoc temperature scaling and refinement stopping from our paper Rethinking Early Stopping: Refine, Then Calibrate, you can pass the following parameters to the scikit-learn interfaces:

from pytabkit import RealMLP_TD_Classifier
clf = RealMLP_TD_Classifier(
    val_metric_name='ref-ll-ts',  # short for 'refinement_logloss_ts-mix_all'
    calibration_method='ts-mix',  # temperature scaling with laplace smoothing
    use_ls=False  # recommended for cross-entropy loss
)

Other calibration methods and validation metrics from probmetrics can be used as well.

For reproducing the results from this paper, we refer to the documentation.

Benchmarking code

Our benchmarking code has functionality for

  • dataset download
  • running methods highly parallel on single-node/multi-node/multi-GPU hardware, with automatic scheduling and trying to respect RAM constraints
  • analyzing/plotting results

For more details, we refer to the documentation.

The benchmarking code also contains wrappers for further models, such as TabPFN, TabICL, and the KumoTabular foundation model (KumoTabularInterfaceWrapper).

Few-shot benchmark (new in 1.8.0). The code for the few-shot benchmark from the TabICLv2 paper (ICML) is included: datasets from the TALENT benchmark with 100–2000 samples (binary classification and regression), where methods only get 16 samples for training and validation. Import the datasets with import_talent_tiny=True in scripts/download_data.py, run the methods with scripts/run_fewshot_experiments.py, and create the result tables with scripts/create_fewshot_tables.py.

Preprocessing code

While many preprocessing methods are implemented in this repository, a standalone version of our robust scaling + smooth clipping can be found here.

Citation

If you use this repository for research purposes, please cite our paper:

@inproceedings{holzmuller2024better,
  title={Better by default: {S}trong pre-tuned {MLPs} and boosted trees on tabular data},
  author={Holzm{\"u}ller, David and Grinsztajn, Leo and Steinwart, Ingo},
  booktitle = {Neural {Information} {Processing} {Systems}},
  year={2024}
}

Contributors

  • David Holzmüller (main developer)
  • Léo Grinsztajn (deep learning baselines, plotting)
  • Ingo Steinwart (UCI dataset download)
  • Katharina Strecker (PyTorch-Lightning interface)
  • Daniel Beaglehole (part of the xRFM implementation)
  • Lennart Purucker (some features/fixes)
  • Jérôme Dockès (deployment, continuous integration)

Acknowledgements

Code from other repositories is acknowledged as well as possible in code comments. Especially, we used code from https://github.com/yandex-research/rtdl and sub-packages (Apache 2.0 license), code from https://github.com/catboost/benchmarks/ (Apache 2.0 license), and https://docs.ray.io/en/latest/cluster/vms/user-guides/community/slurm.html (Apache 2.0 license).

Releases (see git tags)

  • v1.8.0:
    • Added a standalone, simplified RealMLP implementation in pytabkit.models.realmlp (plain PyTorch, no Lightning or fitter framework), which additionally supports missing numerical values. It is experimental and half vibe-coded, but it has been confirmed experimentally to yield similarly good results as the original implementation. See its README for the differences to the original implementation.
    • Added the code for the few-shot benchmark from the TabICLv2 paper (ICML), see the benchmarking section.
    • Added a benchmark wrapper for the KumoTabular foundation model (KumoTabularInterfaceWrapper). It requires the structured-data-models package (Python >= 3.11), which is now an optional dependency in pytabkit[models].
    • Other benchmarking additions: dummy baselines, TabICL for regression, selectable TabPFN versions, refitting for RF, ExtraTrees, linear models, TabPFN, and TabICL, and limits on the number of training/validation and test samples (max_trainval_samples, max_test_samples in RunConfig).
    • Bugfixes found through the few-shot benchmark:
      • CatBoost no longer crashes if the training set contains only a single class or if the regression target is constant.
      • The CatBoost validation metric now also works when CatBoost passes (all-one) sample weights.
      • The expected calibration error no longer fails when only a single class is present.
    • Fixed batch_size='auto' in RealMLP: the batch size was chosen based on the number of vectorized splits instead of the number of training samples, so it was effectively always 64.
    • Pytorch-Lightning's info messages ("GPU available: ..." etc.) are no longer printed for every fit/predict of RealMLP and TabR (with verbosity=0), fixing #39.
    • TabR now raises a clear error if candidate_encoding_batch_size is set without memory_efficient=True (#44).
    • Fixed a FutureWarning on every fit() with scikit-learn 1.6 and 1.7 (#41, #42).
    • Documented that RealMLP applies the lr and wd factors of a parameter twice in the weight decay (#40). This is kept for backward compatibility; the new standalone implementation applies them once.
    • Dropped support for Python 3.9. The CI now installs OpenMP (libomp) on macOS (see #42).
    • Python 3.13 is now also tested in the CI (Ray provides Windows wheels for Python 3.13 now).
  • v1.7.3:
    • disabled RealMLP lightning log file creation that was accidentally introduced in predict() in >=v1.7.0.
    • removed pynvml dependency.
  • v1.7.2:
    • Added scikit-learn 1.8 compatibility.
    • Removed debug print in RealMLP.
    • fixed device memory estimation error in the scheduler when CUDA_VISIBLE_DEVICES was used.
  • v1.7.1:
    • LightGBM now processes the extra_trees, max_cat_to_onehot, and min_data_per_group parameters used in the 'tabarena' search space, which should improve results.
    • Scikit-learn interfaces for RealMLP (TD, HPO) now support moving the model to a different device (e.g., before saving). This can be achived using, e.g., model.to('cpu') (which is in-place).
    • Fixed an xRFM bug in handling binary categorical features.
  • v1.7.0:
    • added xRFM (D, HPO)
    • added new 'tabarena-new' search space for RealMLP-HPO, including per-fold ensembling (more expensive) and tuning two more categorical hyperparameters (with better results)
    • reduced RealMLP pickle size by not storing the dataset (#33)
    • fixed gradient clipping for TabM (it did nothing previously, see #34). To ensure backward compatibility, it is set to None in the HPO search spaces now (it was already None in the default parameters).
    • removed debug print in TabM training loop
  • v1.6.1:
    • For n_ens>1, changed the default behavior for classification to averaging probabilities instead of logits. This can be reverted by setting ens_av_before_softmax=True.
    • Implemented time limit for HPO/ensemble methods through time_limit_s parameter.
    • Support torch>=2.6 and Python 3.13.
  • v1.6.0:
    • Added support for other training losses in TabM through the train_metric_name parameter, for example, (multi)quantile regression via train_metric_name='multi_pinball(0.05,0.95)'.
    • RealMLP-TD now adds the n_ens hyperparameter, which can be set to values >1 to train ensembles per train-validation split (called PackedEnsemble in the TabM paper). This is especially useful when using holdout validation instead of cross-validation ensembles, and to get more reliable validation predictions and scores for tuning/ensembling.
    • fixed RealMLP TabArena search space (hpo_space_name='tabarena') for classification (allow no label smoothing through use_ls=False instead of use_ls="auto").
  • v1.5.2: fixed more device bugs for HPO and ensembling
  • v1.5.1: fixed a device bug in TabM for GPU
  • v1.5.0:
    • added n_repeats parameter to scikit-learn interfaces for repeated cross-validation
    • HPO sklearn interfaces (the ones using random search) can now do weighted ensembling instead by setting use_caruana_ensembling=True. Removed the RealMLP_Ensemble_Classifier and RealMLP_Ensemble_Regressor from v1.4.2 since they are now redundant through this feature.
    • renamed space parameter of GBDT HPO interface to hpo_space_name so now it also works with non-TPE versions.
    • Added new TabArena search spaces for boosted trees (not TPE), which should be almost equivalent to the ones from TabArena except for the early stopping logic.
    • TabM now supports val_metric_name for early stopping on different metrics.
    • fixed issues #20 and #21 regarding HPO
    • small updates for the "Rethinking Early Stopping" paper
  • v1.4.2:
    • fixed handling of custom val_metric_name HPO models and Ensemble_TD_Regressor.
    • if tmp_folder is specified in HPO models, save each model to disk immediately instead of holding all of them in memory. This can considerably reduce RAM/VRAM usage. In this case, pickled HPO models will still rely on the models stored in the tmp_folder.
    • We now provide RealMLP_Ensemble_Classifier and RealMLP_Ensemble_Regressor, which will use weighted ensembling and usually perform better than HPO (but have slower inference time). We recommend using the new hpo_space_name='tabarena' for best results.
  • v1.4.1:
    • moved dill to optional dependencies
    • updated TabM code to a newer version: added option share_training_batches=False (old version: True), exclude certain parameters from weight decay.
    • added documentation for using the scheduler with custom jobs.
    • fixed bug in RealMLP refitting.
    • updated process start method for scheduler to speed up benchmarking
  • v1.4.0:
    • moved some imports to the new models optional dependencies to have a more light-weight RealMLP installation
    • Added GPU support for CatBoost with help from Maximilian Schambach in #16 (not guaranteed to produce exactly the same results).
    • Ensembling now saves models after training if a path is supplied, to reduce memory usage
    • Added more search spaces
    • fixed error in multiquantile output when the passed y was one-dimensional instead of having shape (n_samples, 1)
    • Added some examples to the documentation
  • v1.3.0:
    • Added multiquantile regression for RealMLP: see the documentation
    • More hyperparameters for RealMLP
    • Added TabICL wrapper
    • Small fixes
  • v1.2.1: avoid error for older skorch versions
  • v1.2.0:
    • Included post-hoc calibration and more metrics through probmetrics.
    • Added benchmarking code for Rethinking Early Stopping: Refine, Then Calibrate.
    • Updated format for saving predictions, allow to stop on multiple metrics during the same training in the benchmark.
    • Better categorical handling, avoiding an error for string and object columns, not ignoring boolean columns by default but treating them as categorical.
    • Added Ensemble_HPO_Classifier and Ensemble_HPO_Regressor.
  • v1.1.3:
    • Fixed a bug where the categorical encoding was incorrect if categories were missing in the training or validation set. The bug affected XGBoost and potentially many other models except RealMLP.
    • Scikit-learn interfaces now accept and auto-detect categorical datatypes (category, string, object) in dataframes.
  • v1.1.2:
    • Some compatibility improvements for scikit-learn 1.6 (but disabled 1.6 since skorch is not compatible with it).
    • Improved documentation for Pytorch-Lightning interface.
    • Other small bugfixes and improvements.
  • v1.1.1:
    • Added parameters weight_decay, tfms, and gradient_clipping_norm to TabM. The updated default parameters now apply the RTDL quantile transform.
  • v1.1.0:
    • Included TabM
    • Replaced __ by _ in parameter names for MLP, MLP-PLR, ResNet, and FTT, to comply with scikit-learn interface requirements.
    • Fixed non-determinism in NN baselines by initializing the random state of quantile (and KDI) preprocessing transforms.
    • n_threads parameter is not ignored by NNs anymore.
    • Changes by Lennart Purucker: Add time limit for RealMLP, add support for lightning (but also still allowing pytorch-lightning), making skorch a lazy import, removed msgpack_numpy dependency.
  • v1.0.0: Release for the NeurIPS version and arXiv v2+v3.
    • More baselines (MLP-PLR, FT-Transformer, TabR-HPO, RF-HPO), also some un-polished internal interfaces for other methods, esp. the ones in AutoGluon.
    • Updated benchmarking code (configurations, plots) including the new version of the Grinsztajn et al. benchmark
    • Updated fit() parameters in scikit-learn interfaces, etc.
  • v0.0.1: First release for arXiv v1. Code and data are archived at DaRUS.

Metadata

Release files for pytabkit 1.8.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 pytabkit 1.8.0
File Size Uploaded Provenance Actions
pytabkit-1.8.0.tar.gz 341.7 kB Without provenance Details for pytabkit-1.8.0.tar.gz

Built distribution (wheel)

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

Total release size: 730.0 kB

Release files / pytabkit-1.8.0.tar.gz

Download URL pytabkit-1.8.0.tar.gz
Size 341.7 kB
Tags Source
SHA-256 checksum
How to use checksums
fb5d36bc7fe058774d68c151832329d21a4687f727ba9bbbc1155b926ad17e02
BLAKE2b-256 checksum
How to use checksums
27f90f604847b27c241747ed4589bdd62def6b9c62bbe65efa59076f8947fb52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.16.2 cpython/3.12.3 HTTPX/0.28.1

Release files / pytabkit-1.8.0-py3-none-any.whl

Download URL pytabkit-1.8.0-py3-none-any.whl
Size 388.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
11637959137946de1447e18192c81aae903262b25c3ed49524eaf61d1ef98e9e
BLAKE2b-256 checksum
How to use checksums
1a4854cc7825bfdee238ff0a9a76ca1315e4c29eb6705dbfb8c51d67ad3b7b58
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.16.2 cpython/3.12.3 HTTPX/0.28.1

Security for pytabkit 1.8.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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