nirs4all.operators.models.sklearn.aom_fast module

FastAOM public entry point for nirs4all.

Re-exports the canonical FastAOM implementation from nirs4all.operators.models._aom_nirs.fast (vendored copy of the aom-nirs package; once aom-nirs is on PyPI this file will switch to from aom_nirs.fast import ...).

FastAOM screens millions of preprocessing chains via adjoint-only covariance scoring + diversity-aware top-k + low-rank kernel evaluation, then fits one of four AOM-style models on the survivors. The paper-headline FastAOM variant is SparseMultiKernelRidge (FastAOMPLSRidge(model='sparse_mkr_compact')) — median rel-RMSEP 1.022 with 2.48 s median fit time on the 50-dataset cohort.

class nirs4all.operators.models.sklearn.aom_fast.ASLSBase(lam: float = 100000.0, p: float = 0.01, max_iter: int = 20, tol: float = 0.001)[source]

Bases: BaseTransform

ASLS baseline removal, applied independently to each spectrum.

Strictly speaking ASLS is non-linear because the weights depend on the spectrum. We keep the lambda/p as hyperparameters so that the transformation is deterministic given those parameters; the fit step is a no-op because there is no per-fold parameter to learn.

fit(X: ndarray, y: ndarray | None = None) → ASLSBase[source]
property name: str
property signature: str
transform(X: ndarray) → ndarray[source]
class nirs4all.operators.models.sklearn.aom_fast.AbsorbanceBase(eps: float = 1e-06)[source]

Bases: BaseTransform

Absorbance from reflectance: B(X) = -log10(clip(X, eps, 1)).

Reflectance is expected to lie in (0, 1]. If the data is already in absorbance space (e.g. negative values, magnitudes far outside [0, 1]) the transform falls back to identity to avoid producing NaN values that would break downstream models — the fallback is recorded in fallback_to_identity_.

fit(X: ndarray, y: ndarray | None = None) → AbsorbanceBase[source]
name: str = 'absorbance'
property signature: str
transform(X: ndarray) → ndarray[source]
class nirs4all.operators.models.sklearn.aom_fast.BaseTransform[source]

Bases: object

Protocol for fold-aware nonlinear base transforms.

fit(X: ndarray, y: ndarray | None = None) → BaseTransform[source]
fit_transform(X: ndarray, y: ndarray | None = None) → ndarray[source]
name: str
property signature: str
transform(X: ndarray) → ndarray[source]
class nirs4all.operators.models.sklearn.aom_fast.ChainGenerationConfig(max_depth: int = 4, include_identity_chain: bool = True, beam_width: int | None = None, simplify_each: bool = True)[source]

Bases: object

Parameters for chain enumeration.

Variables:
  • max_depth (int) – Maximum chain depth (overrides the grammar’s max_depth if smaller).

  • include_identity_chain (bool) – If True, the chain [IdentityOperator] is included (matches “no preprocessing”).

  • beam_width (int | None) – Optional cap on the number of chains kept at each depth level. None means no cap. Useful when the primitive bank is very large.

  • simplify_each (bool) – If True, every emitted chain is passed through OperatorChain.simplify() before deduplication. This is usually a good idea because the grammar can still emit redundant chains (e.g. smoother -> derivative -> detrend that collapses).

beam_width: int | None = None
include_identity_chain: bool = True
max_depth: int = 4
simplify_each: bool = True
class nirs4all.operators.models.sklearn.aom_fast.ChainGrammar(max_depth: int = 4, allowed_roles_per_position: Tuple[FrozenSet[str], ...] | None = None, allow_repeats_in_role: bool = False, forbidden_role_sequences: Tuple[Tuple[str, str], ...] = (('derivative', 'baseline_scatter'),), max_per_role: Dict[str, int] | None = None)[source]

Bases: object

Typed chain grammar with depth and role constraints.

Variables:
  • max_depth (int) – Maximum chain depth (number of operators).

  • allowed_roles_per_position (Tuple[FrozenSet[str], ...] | None) – Optional (role-set,) per chain position. If None (default), any role is allowed at any position, subject to the parent aompls.grammar_allows rules. If provided, the role at position i must be in allowed_roles_per_position[i].

  • allow_repeats_in_role (bool) – If True, repeats of the same role (e.g. two consecutive smoothings of different families) are allowed. If False (default), each role appears at most once.

  • forbidden_role_sequences (Tuple[Tuple[str, str], ...]) – Pairs of consecutive role tags that are forbidden. By default we forbid (derivative -> baseline) because a baseline-scatter step after a derivative is rarely helpful.

  • max_per_role (Dict[str, int] | None) – Optional per-role cap. None means no cap.

allow_repeats_in_role: bool = False
allowed_roles_per_position: Tuple[FrozenSet[str], ...] | None = None
chain_role_summary(chain: Sequence[LinearSpectralOperator]) → Tuple[str, ...][source]
forbidden_role_sequences: Tuple[Tuple[str, str], ...] = (('derivative', 'baseline_scatter'),)
is_extension_valid(chain: Sequence[LinearSpectralOperator], candidate: LinearSpectralOperator) → bool[source]

Return True if appending candidate to chain is legal.

max_depth: int = 4
max_per_role: Dict[str, int] | None = None
class nirs4all.operators.models.sklearn.aom_fast.EMSCBase(degree: int = 2)[source]

Bases: BaseTransform

Extended MSC with polynomial wavelength terms.

For each row x and a reference mean m (fit on the training fold), fit a + b * m + c1 * t + c2 * t^2 + ... + cD * t^D ≈ x and return (x - a - c1 t - ... - cD t^D) / b. Reduces to MSC when degree == 0.

fit(X: ndarray, y: ndarray | None = None) → EMSCBase[source]
name: str = 'emsc'
reference_: ndarray | None
property signature: str
transform(X: ndarray) → ndarray[source]
class nirs4all.operators.models.sklearn.aom_fast.FastAOMConfig(model: Literal['single_chain', 'hard_aom_chain', 'soft_aom_chain', 'sparse_mkr'] = 'hard_aom_chain', primitive_bank: str = 'compact', max_chain_depth: int = 3, chain_beam_width: int | None = None, rank: int = 200, top_global: int = 200, top_per_base: int | None = 60, top_per_family: int | None = 6, n_components: int = 15, lambdas: Tuple[float, ...] = (0.0, 0.0001, 0.001, 0.01, 0.1, 1.0, 10.0, 100.0), component_shrinkage_gamma: float | None = None, soft_rho: float = 0.05, soft_max_mixture_size: int | None = 4, sparse_mkr_max_chains: int = 8, use_raw: bool = True, use_absorbance: bool = False, use_snv: bool = True, use_msc: bool = False, use_emsc: bool = False, asls_grid: Tuple[Tuple[float, float], ...] | None = None, osc_components: Tuple[int, ...] | None = None, use_snv_osc: bool = False, whittaker_baseline_lam: Tuple[float, ...] | None = None, random_state: int = 0, cv_n_components: bool = False, cv_folds: int = 5)[source]

Bases: object

Configuration for FastAOMPLSRidge.

Variables:
  • model (Literal['single_chain', 'hard_aom_chain', 'soft_aom_chain', 'sparse_mkr']) – Final AOM model to fit on the surviving candidate pool.

  • primitive_bank (str) – Bank name to draw chain primitives from (e.g. "compact" or "default" from aompls.banks).

  • max_chain_depth (int) – Maximum chain depth.

  • chain_beam_width (int | None) – Optional beam-width cap for chain generation.

  • rank (int) – Truncated SVD rank for the low-rank evaluator.

  • top_global (int) – Global top-K for the diversity filter.

  • top_per_base (int | None) – Per-base top-K.

  • top_per_family (int | None) – Per-family-tag top-K (diversity).

  • n_components (int) – Maximum number of latent PLS components in the final AOM model.

  • lambdas (Tuple[float, ...]) – Ridge lambda_0 grid.

  • component_shrinkage_gamma (float | None) – Component-wise shrinkage exponent (lambda_h = lambda_0 * h ** gamma).

  • soft_rho (float) – L1 strength for the soft-AOM variant.

  • sparse_mkr_max_chains (int) – Maximum number of chains for sparse multi-kernel Ridge.

  • asls_grid (use_raw / use_absorbance / use_snv / use_msc / use_emsc /) – Toggles for the nonlinear base bank.

  • random_state (int) – Reproducibility seed (currently used for tie-breaking).

asls_grid: Tuple[Tuple[float, float], ...] | None = None
chain_beam_width: int | None = None
component_shrinkage_gamma: float | None = None
cv_folds: int = 5
cv_n_components: bool = False
lambdas: Tuple[float, ...] = (0.0, 0.0001, 0.001, 0.01, 0.1, 1.0, 10.0, 100.0)
max_chain_depth: int = 3
model: Literal['single_chain', 'hard_aom_chain', 'soft_aom_chain', 'sparse_mkr'] = 'hard_aom_chain'
n_components: int = 15
osc_components: Tuple[int, ...] | None = None
primitive_bank: str = 'compact'
random_state: int = 0
rank: int = 200
soft_max_mixture_size: int | None = 4
soft_rho: float = 0.05
sparse_mkr_max_chains: int = 8
top_global: int = 200
top_per_base: int | None = 60
top_per_family: int | None = 6
use_absorbance: bool = False
use_emsc: bool = False
use_msc: bool = False
use_raw: bool = True
use_snv: bool = True
use_snv_osc: bool = False
whittaker_baseline_lam: Tuple[float, ...] | None = None
class nirs4all.operators.models.sklearn.aom_fast.FastAOMPLSRidge(config: FastAOMConfig | None = None)[source]

Bases: BaseEstimator, RegressorMixin

End-to-end FastAOM PLS-Ridge regressor.

The estimator exposes the standard sklearn interface fit / predict and stores rich diagnostics in diagnostics_ (timings, candidate counts, selected chains, etc.) for the benchmark scripts to log.

fit(X: ndarray, y: ndarray) → FastAOMPLSRidge[source]
predict(X: ndarray) → ndarray[source]
set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') → FastAOMPLSRidge

Configure whether metadata should be requested to be passed to the score 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 score 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 score.

  • 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:

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

Returns:

self – The updated object.

Return type:

object

class nirs4all.operators.models.sklearn.aom_fast.HardAOMChainPLSRidge(bases: Sequence[BaseTransform], lowrank_bases: Sequence[LowRankBase], candidates: Sequence[Tuple[int, OperatorChain]], n_components: int = 15, lambdas: Sequence[float] | None = None, component_shrinkage_gamma: float | None = None, early_stop_patience: int | None = 3, eps: float = 1e-12)[source]

Bases: BaseEstimator, RegressorMixin

fit(X_train: ndarray | None = None, y_train: ndarray | None = None) → HardAOMChainPLSRidge[source]
predict(X: ndarray) → ndarray[source]
set_fit_request(*, X_train: bool | None | str = '$UNCHANGED$', y_train: bool | None | str = '$UNCHANGED$') → HardAOMChainPLSRidge

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:
  • X_train (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for X_train parameter in fit.

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

Returns:

self – The updated object.

Return type:

object

set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') → HardAOMChainPLSRidge

Configure whether metadata should be requested to be passed to the score 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 score 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 score.

  • 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:

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

Returns:

self – The updated object.

Return type:

object

class nirs4all.operators.models.sklearn.aom_fast.LowRankBase(base: BaseTransform, X_centred: ndarray, mean: ndarray, U: ndarray, S: ndarray, Vt: ndarray, rank: int, y_centred: ndarray, g0: ndarray)[source]

Bases: object

Truncated SVD of a nonlinear base applied to a training fold.

Variables:
F(chain: OperatorChain) → ndarray[source]

Compute F_s = A_s V diag(S) for a chain.

A_s is the chain matrix; using the parent convention transform(X) = X @ A.T, the apply on a column is apply_cov(V_col) = A @ V_col. We apply apply_cov to V * S[None, :] to get the desired A V diag(S).

S: ndarray
U: ndarray
property V: ndarray
Vt: ndarray
X_centred: ndarray
base: BaseTransform
chain_norm_F_sq(chain: OperatorChain) → float[source]

||B(X) A_s^T||_F^2 ≈ ||F_s||_F^2.

g0: ndarray
kernel_apply(chain: OperatorChain, v: ndarray) → ndarray[source]

K_s @ v ≈ U @ C_s @ (U^T @ v) for v of shape (n,) or (n, k).

kernel_matrix_lowrank(chain: OperatorChain) → ndarray[source]

K_s ≈ U F_s^T F_s U^T. Computes the dense n x n kernel.

mean: ndarray
rank: int
y_centred: ndarray
class nirs4all.operators.models.sklearn.aom_fast.MSCBase[source]

Bases: BaseTransform

Multiplicative Scatter Correction with training-fold mean as reference.

fit(X: ndarray, y: ndarray | None = None) → MSCBase[source]
name: str = 'msc'
transform(X: ndarray) → ndarray[source]
class nirs4all.operators.models.sklearn.aom_fast.OSCBase(n_components: int = 2)[source]

Bases: BaseTransform

Orthogonal Signal Correction (supervised linear).

Removes n_components directions of X orthogonal to y via the production-style OSC routine from aompls.preprocessing. Used as a base because it must see y at fit time and replays a stored projection at predict time — exactly the protocol required for fold-aware NIRS preprocessing.

fit(X: ndarray, y: ndarray | None = None) → OSCBase[source]
property name: str
property signature: str
transform(X: ndarray) → ndarray[source]
class nirs4all.operators.models.sklearn.aom_fast.OperatorChain(operators: Sequence[LinearSpectralOperator])[source]

Bases: object

An ordered chain of linear spectral operators with grammar utilities.

The composed action is A_s = A_K ... A_1 (apply leftmost first), matching the parent aompls.ComposedOperator convention. Methods behave linearly:

Empty chains are not allowed — pass a single IdentityOperator instead.

adjoint_vec(v: ndarray) → ndarray[source]
apply_cov(S: ndarray) → ndarray[source]
property composed: ComposedOperator

Return the lazily built ComposedOperator.

depth() → int[source]
families() → Tuple[str, ...][source]
fit(X: ndarray | None = None, y: ndarray | None = None) → OperatorChain[source]
classmethod from_operators(operators: Iterable[LinearSpectralOperator]) → OperatorChain[source]
matrix(p: int | None = None) → ndarray[source]
names() → Tuple[str, ...][source]
property operators: Tuple[LinearSpectralOperator, ...]
property signature: str
simplify() → OperatorChain[source]

Return a grammar-aware simplified chain.

Rules (combining the parent canonicalize with extra FastAOM simplifications):

  • Drop IdentityOperator stages.

  • Collapse consecutive DetrendProjectionOperator to the higher-degree one (idempotence of nested polynomial projection complements when degrees are nested).

  • Collapse consecutive smoothers of the same family by keeping the widest window (heuristic: wider smoother absorbs the narrower).

  • Drop a trailing detrend if the chain already ends with a derivative whose null space contains the polynomial basis (first/second derivatives kill polynomials of equal degree).

  • If the chain becomes empty after simplification, return an IdentityOperator-only chain.

property stages: Tuple[ChainStage, ...]
transform(X: ndarray) → ndarray[source]
class nirs4all.operators.models.sklearn.aom_fast.RawBase[source]

Bases: BaseTransform

Identity base: B(X) = X.

fit(X: ndarray, y: ndarray | None = None) → RawBase[source]
name: str = 'raw'
transform(X: ndarray) → ndarray[source]
class nirs4all.operators.models.sklearn.aom_fast.SNVBase[source]

Bases: BaseTransform

Standard Normal Variate, row-wise centring and scaling.

SNV is independent of the training fold (purely row-based), but we keep the fit/transform interface for API symmetry.

fit(X: ndarray, y: ndarray | None = None) → SNVBase[source]
name: str = 'snv'
transform(X: ndarray) → ndarray[source]
class nirs4all.operators.models.sklearn.aom_fast.SNVOSCBase(n_components: int = 2)[source]

Bases: BaseTransform

SNV row-normalisation followed by OSC (supervised).

fit(X: ndarray, y: ndarray | None = None) → SNVOSCBase[source]
property name: str
property signature: str
transform(X: ndarray) → ndarray[source]
class nirs4all.operators.models.sklearn.aom_fast.ScreeningCandidate(base_index: int, base_name: str, chain: OperatorChain, score: float, numerator: float, denominator: float, chain_norm_F_sq: float, family_tag: str = '')[source]

Bases: object

A scored (base, chain) candidate.

Variables:
  • base_index (int) – Index of the source base in the input bank.

  • base_name (str) – Convenience signature of the base.

  • chain (nirs4all.operators.models._aom_nirs.fast.operator_chain.OperatorChain) – The candidate chain.

  • score (float) – Screening score ([0, 1]).

  • numerator (float) – Raw numerator (||A^T g_0||^2); informative for debugging.

  • denominator (float) – Raw denominator (||F_s||_F^2 * ||y||^2).

  • chain_norm_F_sq (float) – Frobenius norm squared of the transformed matrix.

  • family_tag (str) – Coarse signature for the chain’s “dominant” family, used by diversity_topk() for stratified selection.

base_index: int
base_name: str
chain: OperatorChain
chain_norm_F_sq: float
denominator: float
family_tag: str = ''
numerator: float
score: float
class nirs4all.operators.models.sklearn.aom_fast.SingleChainPLSRidge(base: BaseTransform, chain: OperatorChain, n_components: int = 15, lambdas: Sequence[float] | None = None, component_shrinkage_gamma: float | None = None, center_y: bool = True, cv_n_components: bool = False, cv_folds: int = 5, cv_random_state: int = 0)[source]

Bases: BaseEstimator, RegressorMixin

PLS-Ridge on a single preprocessing chain over a single base.

Attributes (after fit()):

x_mean_: training-fold mean of B(X) y_mean_: training-fold mean of y T_: latent scores (n, H) W_: PLS weights (p, H) P_: PLS loadings (p, H) coef_latent_: Ridge coefficients on latent scores (H,) coef_: regression coefficients in original space (p,) lambda_: chosen lambda_0 n_components_: actual number of components extracted

Parameters:
  • base – Fold-aware nonlinear base transform.

  • chain – Operator chain to apply after the base.

  • n_components – Maximum number of latent components H.

  • lambdas – Candidate lambda_0 grid for Ridge.

  • component_shrinkage_gamma – If not None, late components are shrunk more aggressively: lambda_h = lambda_0 * h ** gamma.

  • center_y – Always center y (set to False only for tests).

fit(X: ndarray, y: ndarray) → SingleChainPLSRidge[source]
predict(X: ndarray) → ndarray[source]
set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') → SingleChainPLSRidge

Configure whether metadata should be requested to be passed to the score 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 score 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 score.

  • 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:

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

Returns:

self – The updated object.

Return type:

object

class nirs4all.operators.models.sklearn.aom_fast.SoftAOMChainPLSRidge(bases: Sequence[BaseTransform], lowrank_bases: Sequence[LowRankBase], candidates: Sequence[Tuple[int, OperatorChain]], n_components: int = 15, rho: float = 0.05, lambdas: Sequence[float] | None = None, component_shrinkage_gamma: float | None = None, max_mixture_size: int | None = 5, cd_iters: int = 200, eps: float = 1e-12)[source]

Bases: BaseEstimator, RegressorMixin

fit(X_train: ndarray | None = None, y_train: ndarray | None = None) → SoftAOMChainPLSRidge[source]
predict(X: ndarray) → ndarray[source]
set_fit_request(*, X_train: bool | None | str = '$UNCHANGED$', y_train: bool | None | str = '$UNCHANGED$') → SoftAOMChainPLSRidge

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:
  • X_train (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for X_train parameter in fit.

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

Returns:

self – The updated object.

Return type:

object

set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') → SoftAOMChainPLSRidge

Configure whether metadata should be requested to be passed to the score 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 score 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 score.

  • 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:

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

Returns:

self – The updated object.

Return type:

object

class nirs4all.operators.models.sklearn.aom_fast.SparseMultiKernelRidge(bases: Sequence[BaseTransform], lowrank_bases: Sequence[LowRankBase], candidates: Sequence[Tuple[int, OperatorChain]], max_chains: int = 8, lambdas: Sequence[float] | None = None, tol: float = 1e-06, nnls_iters: int = 200)[source]

Bases: BaseEstimator, RegressorMixin

fit(X_train: ndarray | None = None, y_train: ndarray | None = None) → SparseMultiKernelRidge[source]
predict(X: ndarray) → ndarray[source]
set_fit_request(*, X_train: bool | None | str = '$UNCHANGED$', y_train: bool | None | str = '$UNCHANGED$') → SparseMultiKernelRidge

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:
  • X_train (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for X_train parameter in fit.

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

Returns:

self – The updated object.

Return type:

object

set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') → SparseMultiKernelRidge

Configure whether metadata should be requested to be passed to the score 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 score 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 score.

  • 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:

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

Returns:

self – The updated object.

Return type:

object

class nirs4all.operators.models.sklearn.aom_fast.WhittakerBaseLine(lam: float = 100000.0)[source]

Bases: BaseTransform

Whittaker smoother used as a baseline estimator: B(X) = X - smooth(X).

The smoother is linear given lambda but is plugged in here as a base because the subtraction of the smoothed signal is what we want to feed the linear chains downstream. The smoother itself shares the parent aompls.WhittakerOperator.

fit(X: ndarray, y: ndarray | None = None) → WhittakerBaseLine[source]
property name: str
property signature: str
transform(X: ndarray) → ndarray[source]
nirs4all.operators.models.sklearn.aom_fast.build_base_bank(use_raw: bool = True, use_absorbance: bool = True, use_snv: bool = True, use_msc: bool = True, use_emsc: bool = False, asls_grid: Sequence[Tuple[float, float]] | None = None, osc_components: Sequence[int] | None = None, use_snv_osc: bool = False, use_whittaker_baseline: Sequence[float] | None = None) → List[BaseTransform][source]

Construct a default bank of nonlinear / supervised bases.

Parameters:
  • use_emsc (use_raw / use_absorbance / use_snv / use_msc /) – toggle simple normalisation bases.

  • asls_grid – optional sequence of (lam, p) pairs to add as ASLSBase baseline-corrected variants.

  • osc_components – optional sequence of OSC component counts (each added as an OSCBase). Supervised — uses y at fit time and replays at predict.

  • use_snv_osc – include an SNV+OSC compound base (typical NIRS production pipeline).

  • use_whittaker_baseline – optional sequence of lam for WhittakerBaseLine bases.

nirs4all.operators.models.sklearn.aom_fast.chain_from_operators(operators: Iterable[LinearSpectralOperator]) → OperatorChain[source]

Convenience constructor used by the chain generator and tests.

nirs4all.operators.models.sklearn.aom_fast.default_grammar(max_depth: int = 4) → ChainGrammar[source]

Return the default FastAOM grammar.

No fixed role-per-position; up to max_depth operators; each role appears at most once (so we do not get two derivatives, two smoothings, etc.); the derivative -> baseline pair is forbidden.

nirs4all.operators.models.sklearn.aom_fast.diversity_topk(candidates: Sequence[ScreeningCandidate], top_k_global: int, top_k_per_family: int | None = None, top_k_per_base: int | None = None) → List[ScreeningCandidate][source]

Return up to top_k_global candidates with diversity constraints.

Parameters:
  • candidates – Pre-scored candidates (typically sorted by score already; if not, this routine re-sorts a copy).

  • top_k_global – Maximum number of returned candidates.

  • top_k_per_family – Maximum number per family tag (e.g. cap how many sg_smooth+sg_d1 chains we keep). None disables.

  • top_k_per_base – Maximum number per base. None disables.

Returns:

Sorted list with at most top_k_global entries.

nirs4all.operators.models.sklearn.aom_fast.fast_covariance_screen(bases: Sequence[LowRankBase], chains: Sequence[OperatorChain], eps: float = 1e-12) → List[ScreeningCandidate][source]

Screen every (base, chain) pair and return all candidates with scores.

Parameters:
  • bases – Pre-fitted LowRankBase list (one per nonlinear base).

  • chains – Chains to screen.

  • eps – Numerical floor for the denominator.

Returns:

Flat list of ScreeningCandidate, sorted by descending score.

nirs4all.operators.models.sklearn.aom_fast.fit_lowrank_bases(bases: Sequence[BaseTransform], X: ndarray, y: ndarray, rank: int = 200, random_state: int = 0) → List[LowRankBase][source]

Fit each base on X (training fold) and compute its truncated SVD.

Parameters:
  • bases – Sequence of fold-aware base transforms.

  • X – Training spectra.

  • y – Training response (1D or 2D).

  • rank – Truncation rank r. Reduced to min(rank, n, p).

  • random_state – Currently unused (deterministic SVD); reserved for future randomised SVD variants.

Returns:

List of LowRankBase, one per input base, fitted on X.

nirs4all.operators.models.sklearn.aom_fast.generate_chains(bank: Sequence[LinearSpectralOperator], grammar: ChainGrammar | None = None, cfg: ChainGenerationConfig | None = None, feature_dim: int | None = None) → List[OperatorChain][source]

Enumerate OperatorChain instances under grammar.

Parameters:
  • bank – Primitive operator bank to draw from. Each operator should already be initialised for the spectral dimension (use aompls.fit_bank if needed).

  • grammar – Chain grammar (default: default_grammar()).

  • cfg – Generation parameters.

  • feature_dim – Optional override for the feature dimensionality (the grammar treats the bank as already shaped, but identity chains need a value of p to bind to).

Returns:

Deduplicated list of OperatorChain, sorted by depth then by signature for reproducibility.