Benchmark models across datasets.
Benchmark takes a set of model specs and a set of dataset specs; run scores every model on every dataset with cross-validation or repeated holdout, optionally tuning each model inside the training folds. Results live on the instance: tidy per-fold scores, ranked tables, significance tests, paper-ready exports, and comparison plots.
Everything is declarative, in the same {"name": ..., "params": {...}} convention as train, so a whole benchmark can be stored as JSON and replayed.
Classes
A declarative model comparison: configure it, then run it.
run executes the comparison and stores the results on the instance: scores_, best_params_, and every table, test, export, and plot method.__init__( self, models: List[Dict[str, Any]], datasets: List[Dict[str, Any]], *, pipeline: Optional[Union[str, List[Dict]]] = None, evaluation: Optional[Dict[str, Any]] = None, random_seed: Optional[int] = None, task: Optional[str] = None, )
Parameters
models
Model specs, each {"name": ..., "params": {...}} plus optional keys:
- •
"tune": ``{"method": "grid" | "random", "space": {param:
[values]}, "iterations": 25}``. Tuning runs on the training side of every fold with an inner 3-fold split, so reported scores stay honest.
- •
"pipeline": per-model step list overriding the shared
pipeline (for example scaling for an SVM but not for trees).
- •
"label": display name; defaults to the model name.
datasets
Dataset specs, always in spec form:
- •
{"source": "iris"}: a builtin dataset (builtins define their
own target).
- •``{"source": "sales.csv", "target": "label", "features": [...],
"name": "sales"}: a data file; "features" restricts the columns, "name"`` sets the display name.
- •
{"name": "custom", "X": X_array, "y": y_array}: in-memory
pipeline
PRESETS.
evaluation
{"cv": 10} for k-fold (the default), or {"test_size": 0.2} for holdout. "repeats" repeats either scheme with fresh seeds, which also gives holdout a spread for statistics. "stratify" (default True) keeps class balance, and "metrics" lists metric function names from tuiml.evaluation.metrics. Forecasters (models tagged timeseries) never shuffle: "cv" becomes an expanding-window TimeSeriesSplit, "test_size" a single tail holdout, and "repeats", "stratify" and the shared pipeline do not apply. The series is the dataset's target column, or its first feature column when there is no target.
random_seed
task
Attributes
scores_
dataset, model, metric, fold, value. Set by run.
best_params_
run.
task
metrics
random_seed
Step 1, import and configure:
>>> from tuiml import Benchmark
>>> bench = Benchmark(
... models=[
... {"name": "NaiveBayesClassifier"},
... {"name": "RandomForestClassifier",
... "tune": {"method": "grid",
... "space": {"n_estimators": [50, 100]}}},
... ],
... datasets=[
... {"source": "iris"},
... {"source": "sales.csv", "target": "label"},
... ],
... evaluation={"cv": 10, "metrics": ["accuracy_score"]},
... random_seed=42,
... )
Step 2, execute:
>>> bench.run() # doctest: +SKIP
Step 3, read the results:
>>> print(bench.summary()) # doctest: +SKIP
>>> bench.table() # doctest: +SKIP
>>> bench.compare(baseline="NaiveBayesClassifier") # doctest: +SKIP
>>> bench.to_latex() # doctest: +SKIP
Methods
run
(self, verbose: int=0, progress_callback: Optional[Callable]=None) -> 'Benchmark'
run
(self, verbose: int=0, progress_callback: Optional[Callable]=None) -> 'Benchmark'
Execute the benchmark and store the results on this instance.
Parameters
verbose
progress_callback
Returns
self
scores_ and best_params_ populated.
table
(self, metric: Optional[str]=None, formatted: bool=True) -> pd.DataFrame
table
(self, metric: Optional[str]=None, formatted: bool=True) -> pd.DataFrame
Datasets by models table of scores for one metric.
Parameters
metric
formatted
"mean ± std" strings; False gives numeric means.
Returns
pd.DataFrame
best
(self, metric: Optional[str]=None) -> pd.DataFrame
best
(self, metric: Optional[str]=None) -> pd.DataFrame
The winning model per dataset, plus the overall mean rank.
Parameters
metric
Returns
pd.DataFrame
best_model and best_score indexed by dataset, with an overall row naming the best mean rank.
compare
(self, baseline: str, metric: Optional[str]=None, significance_level: float=0.05) -> pd.DataFrame
compare
(self, baseline: str, metric: Optional[str]=None, significance_level: float=0.05) -> pd.DataFrame
Paired significance tests of every model against a baseline.
Parameters
baseline
metric
significance_level
Returns
pd.DataFrame
"tie").
__repr__
(self) -> str