nirs4all.operators.transforms.concat module

FeatureConcat — a JSON-spec’d horizontal feature concatenation transformer.

This is the single-source, single-processing horizontal-concat lowering of nirs4all’s concat_transform (backlog #27) and feature_augmentation (backlog #31 / S6) steps onto the dag-ml engine. Both grow the dataset’s processing axis (parallel preprocessing layers on the same samples); for a 2D model nirs4all materializes that axis with the FLAT_2D layout, which reshape-flattens (samples, processings, features) → (samples, processings × features) — i.e. an np.hstack of the per-processing layers in processing order (layout_transformer.py). So a 2D model consuming the augmented/concatenated layers sees exactly the same matrix as a FeatureUnion over the layer transformers. Expressing it as ONE sklearn-compatible transformer lets the dag-ml engine run it as an ordinary X-chain transform node: the model node reconstructs make_pipeline(FeatureConcat(...), model) and fits it on fold-train only (leakage-safe), so the column-count change propagates through fold-val / test apply just like the supervised / column-changing X-transforms (OSC/EPO/CARS/MC-UVE, backlog #24).

The sub-transformer list is carried as a JSON-serializable operations spec (a list of {"class": "<FQN>", "params": {...}} entries, where an entry may itself be a chain — a list of such dicts applied sequentially, or None for a pass-through “raw” channel) so the whole node round-trips through the dag-ml compat DSL as a single {"class", "params"} node. The transformers are instantiated lazily at fit time, so an unfitted FeatureConcat stays JSON-cloneable.

Pass-through (raw) channel: a None entry keeps the un-transformed base layer alongside the new ones — this is the feature_augmentation raw layer ([raw, op1(raw), op2(raw), …]), lowered as FeatureConcat([None, op1, op2, …]). The raw channel maps to sklearn’s native "passthrough" FeatureUnion member (raw columns first, in spec order).

Scope (host-only, single-source 2D model): the multi-processing 3D signal_with_processings delivered as parallel channels to a 3D/CNN model, multi-source feature_augmentation, and the nested (concat-of-concat) shapes are NOT covered here — those need the 3D data-plane / a DL operator (backlog #29/#31).

class nirs4all.operators.transforms.concat.FeatureConcat(operations: list[Any] | None = None)[source]

Bases: BaseEstimator, TransformerMixin

Fit several sub-transformers and horizontally concatenate their transform outputs.

Mirrors nirs4all’s concat_transform (replace mode) and feature_augmentation (extend/add/ replace) on a single 2D feature matrix: every sub-transformer fits on the same training rows and the per-sample outputs are stacked column-wise. Equivalent to sklearn.pipeline.FeatureUnion over the supplied operations, but parameterised by a JSON-serializable operations spec so it serializes as one DSL node.

Parameters:

operations – A list whose entries are each either a single transformer spec ({"class": "<FQN>", "params": {...}}), a chain (a list of such specs applied sequentially), or None for a pass-through “raw” channel (the un-transformed base layer — the feature_augmentation extend/add raw layer). The raw channel emits its columns first, in spec order. A shared_fit_id on selector specs fits the first processing lane once and applies its selected columns to later lanes.

channel_widths(X: Any) → tuple[int, ...][source]

Report fitted output widths so a following operator can preserve processing lanes.

fit(X: Any, y: Any = None, wavelengths: Any = None) → FeatureConcat[source]
set_fit_request(*, wavelengths: bool | None | str = '$UNCHANGED$') → FeatureConcat

Configure whether metadata should be requested to be passed to the fit method.

Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with enable_metadata_routing=True (see sklearn.set_config()). Please check the User Guide on how the routing mechanism works.

The options for each parameter are:

  • True: metadata is requested, and passed to fit if provided. The request is ignored if metadata is not provided.

  • False: metadata is not requested and the meta-estimator will not pass it to fit.

  • None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.

  • str: metadata should be passed to the meta-estimator with this given alias instead of the original name.

The default (sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.

Added in version 1.3.

Parameters:

wavelengths (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for wavelengths parameter in fit.

Returns:

self – The updated object.

Return type:

object

transform(X: Any) → ndarray[source]