nirs4all.pipeline.execution.refit.model_selector module

Per-model variant selection for the refit phase.

After Pass 1 (cross-validation), for each model node in the pipeline, identifies the variant where that model achieved the best validation score – independently of other models.

In stacking pipelines with generators, different base models may have their best variant differ from the meta-model’s best variant. This module selects the optimal variant per model so that the refit phase can replay each model’s best configuration.

Example

>>> from nirs4all.pipeline.execution.refit.model_selector import (
...     select_best_per_model,
... )
>>> selections = select_best_per_model(predictions, topology, variant_configs)
>>> for model_name, sel in selections.items():
...     print(f"{model_name}: best variant {sel.variant_index}")
class nirs4all.pipeline.execution.refit.model_selector.PerModelSelection(variant_index: int = 0, best_score: float = 0.0, best_params: dict[str, ~typing.Any]=<factory>, expanded_steps: list[Any] = <factory>, branch_path: list[int] = <factory>)[source]

Bases: object

Selection result for a single model node.

Variables:
  • variant_index (int) – Index of the variant (in PipelineConfigs.steps) where this model achieved its best validation score.

  • best_score (float) – Best validation score achieved by this model.

  • best_params (dict[str, Any]) – Best hyperparameters for this model (from finetuning or the variant’s expanded config).

  • expanded_steps (list[Any]) – The fully expanded step list for the winning variant of this model.

  • branch_path (list[int]) – Branch path leading to this model (empty for top-level models).

best_params: dict[str, Any]
best_score: float = 0.0
branch_path: list[int]
expanded_steps: list[Any]
variant_index: int = 0
nirs4all.pipeline.execution.refit.model_selector.select_best_per_model(predictions: list[dict[str, Any]], topology: PipelineTopology, variant_configs: list[dict[str, Any]], metric: str = '', ascending: bool | None = None, evaluation_scope: str | None = None) → dict[str, PerModelSelection][source]

Select the best variant for each model node independently.

Enumerates all model nodes from the topology, filters prediction entries by model name/branch path, and for each model finds the variant with the best validation score.

Parameters:
  • predictions – List of prediction dicts from all variants. Each dict must contain at least model_name, val_score, and branch_name (or branch_id) fields.

  • topology – Pipeline topology descriptor with model_nodes.

  • variant_configs – List of variant configuration dicts, one per variant. Each dict should contain variant_index, expanded_steps, and optionally best_params.

  • metric – Metric name for ranking. If empty, uses val_score directly.

  • ascending – Sort direction. True means lower is better (e.g. RMSE). None infers from the metric name.

  • evaluation_scope – Optional unit at which prediction-backed candidates are ranked. "sample" recomputes scores from arrays after grouping by metadata["physical_sample_id"] when present. None keeps legacy val_score selection.

Returns:

Mapping from model class name to its PerModelSelection. For single-variant pipelines, all models share the same variant index.

Edge cases:
  • Single variant: all models map to variant 0.

  • Branches without merge: models in different branches are alternatives, not cooperating. Each gets independent selection.

  • Branches with merge (stacking): all branch models are cooperating; the meta-model’s winning variant determines the stacking context. Branch base models are still independently selected within that context.