nirs4all.operators.models.sklearn.aom_ridge module

AOM-Ridge family public entry point for nirs4all.

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

The AOM-Ridge family is the Talanta paper’s strongest empirical contribution: AOMRidgeBlender reaches median RMSEP ratio 0.918 versus Ridge-default on the strict 32-dataset intersection (Wilcoxon Holm-corrected p = 2.6e-4, 27/32 wins).

class nirs4all.operators.models.sklearn.aom_ridge.AOMKernelizer(operator_bank: object = 'compact', *, center: bool = True, normalize: str = 'trace', eps: float = 1e-12, zero_trace_policy: str = 'raise', zero_trace_threshold: float = 1e-12)[source]

Bases: object

Build centred + trace-normalised AOM block kernels (sklearn-style).

Parameters:
  • operator_bank (str | sequence) – Bank name (e.g. "compact", "default") or explicit operator sequence. See aompls.banks.bank_by_name.

  • center (bool, default True) – Apply double-centring at the kernel level.

  • normalize (str, default "trace") – "trace" rescales each block so that tr(K_b)/n == 1; "none" skips normalisation.

  • eps (float, default 1e-12) – Floor for trace denominator.

  • fit) (Attributes (set by)

  • ---------------------------

  • operators (list of fitted operator clones (one per block).)

  • block_names (list[str])

  • n_train (int)

  • K_train_blocks (list[ndarray (n_train, n_train)]) – Centred + normalised training block kernels.

  • block_stats (list[BlockKernelStats]) – Statistics needed for cross-kernel centring at transform time.

  • x_mean (ndarray (p,)) – Training-mean row used to centre features before kernel computation.

fit(X: ndarray, y: ndarray | None = None) → AOMKernelizer[source]

Fit operators to X and store training kernel statistics.

y is unused (kept for sklearn API compatibility).

fit_transform(X: ndarray, y: ndarray | None = None) → list[ndarray][source]

Fit and return the list of training block kernels.

get_params(deep: bool = True) → dict[source]

Sklearn-compatible parameter dict (not used by AOMKernelizer directly; kept for cloning).

transform(X: ndarray) → list[ndarray][source]

Return list of cross block kernels for X.

Each output has shape (n_test, n_train). Centring uses only training-side moments stored at fit time.

class nirs4all.operators.models.sklearn.aom_ridge.AOMLocalRidge(operator_bank: str | Sequence[LinearSpectralOperator] = 'compact', distance_branches: Sequence[str] = ('none', 'snv', 'msc'), k_grid: Sequence[int] = (10, 20, 50, 100), alpha_grid_size: int = 15, cv: int | object = 3, local_weight_beta: float | str = 'auto', random_state: int | None = 0, block_scaling: str = 'none', center: bool = True)[source]

Bases: BaseEstimator, RegressorMixin

Local Ridge in AOM score space.

For each test sample, find the k nearest training samples (in the superblock-AOM kernel-induced metric, optionally after an SNV or MSC pre-transform), fit a local Ridge on those k neighbours, predict.

The ‘distance’ branch and k are chosen by fold-local CV:

branches in {“none”, “snv”, “msc”} k_grid = [10, 20, 50, 100] alpha_grid is logarithmic relative to median(diag(K)).

Optionally blend the local prediction with a global AOM-Ridge prediction:

y_hat = beta * y_local + (1-beta) * y_global, beta in [0, 1].

fit(X: ndarray, y: ndarray) → AOMLocalRidge[source]
get_diagnostics() → dict[source]
predict(X: ndarray) → ndarray[source]
score(X: ndarray, y: ndarray) → float[source]

Return coefficient of determination on test data.

The coefficient of determination, \(R^2\), is defined as \((1 - \frac{u}{v})\), where \(u\) is the residual sum of squares ((y_true - y_pred)** 2).sum() and \(v\) is the total sum of squares ((y_true - y_true.mean()) ** 2).sum(). The best possible score is 1.0 and it can be negative (because the model can be arbitrarily worse). A constant model that always predicts the expected value of y, disregarding the input features, would get a \(R^2\) score of 0.0.

Parameters:
  • X (array-like of shape (n_samples, n_features)) – Test samples. For some estimators this may be a precomputed kernel matrix or a list of generic objects instead with shape (n_samples, n_samples_fitted), where n_samples_fitted is the number of samples used in the fitting for the estimator.

  • y (array-like of shape (n_samples,) or (n_samples, n_outputs)) – True values for X.

  • sample_weight (array-like of shape (n_samples,), default=None) – Sample weights.

Returns:

score – \(R^2\) of self.predict(X) w.r.t. y.

Return type:

float

Notes

The \(R^2\) score used when calling score on a regressor uses multioutput='uniform_average' from version 0.23 to keep consistent with default value of r2_score(). This influences the score method of all the multioutput regressors (except for MultiOutputRegressor).

class nirs4all.operators.models.sklearn.aom_ridge.AOMMultiBranchMKL(branches: Sequence[str] = ('none', 'snv', 'msc', 'asls', 'emsc2'), operator_bank: str | Sequence[LinearSpectralOperator] = 'compact', block_scaling: str = 'none', shrinkage_to_identity: float = 0.3, alphas: str | Sequence[float] = 'auto', alpha_grid_size: int = 50, alpha_grid_low: float = -6.0, alpha_grid_high: float = 6.0, cv: int | object = 3, center: bool = True, random_state: int | None = 0)[source]

Bases: BaseEstimator, RegressorMixin

Soft Multi-Branch Kernel Ridge regressor (AOM-Ridge Phase H4).

For each branch b in branches and each operator a in operator_bank, the estimator forms the kernel

`text K_{b,a} = (Z_b A_a^T) (Z_b A_a^T)^T,   Z_b = T_b(X) `

and combines them as

`text K_total = sum_b w_b * sum_a (1/B) * K_{b,a} `

The branch weights w_b are learned fold-locally by KTA on the training fold (max-then-normalised) and shrunk towards identity-only weight w_none controlled by shrinkage_to_identity. The dual Ridge is solved on K_total + alpha I with the alpha selected by cross-validation on the training fold.

Parameters:
  • branches – Sequence of branch names (must include "none" for the identity reference point).

  • operator_bank – Bank preset name or sequence of operators.

  • block_scaling – Reserved for compatibility with the rest of AOM-Ridge; only "none" is implemented in the multi-branch path.

  • shrinkage_to_identity – Blend factor in [0, 1]: w_b = alpha * raw + (1-alpha) * identity_b. Larger values let the data drive the weights; smaller values protect small-n datasets by forcing reliance on the identity branch.

  • alphas – "auto" or an explicit grid.

  • cv – Integer KFold size or sklearn-compatible splitter.

  • center – Center each branch output at its training mean after raw-spectrum preprocessing; reuse that mean on validation and test rows.

  • random_state – Seed for the default KFold shuffle.

Variables:
  • alphas, (branch_weights, branch_kta_scores, dual_coef, alpha,)

  • n_train, (fitted_branch_transformers, x_mean, y_mean,)

  • diagnostics.

fit(X: ndarray, y: ndarray) → AOMMultiBranchMKL[source]
get_diagnostics() → dict[source]
predict(X: ndarray) → ndarray[source]
score(X: ndarray, y: ndarray) → float[source]

Return coefficient of determination on test data.

The coefficient of determination, \(R^2\), is defined as \((1 - \frac{u}{v})\), where \(u\) is the residual sum of squares ((y_true - y_pred)** 2).sum() and \(v\) is the total sum of squares ((y_true - y_true.mean()) ** 2).sum(). The best possible score is 1.0 and it can be negative (because the model can be arbitrarily worse). A constant model that always predicts the expected value of y, disregarding the input features, would get a \(R^2\) score of 0.0.

Parameters:
  • X (array-like of shape (n_samples, n_features)) – Test samples. For some estimators this may be a precomputed kernel matrix or a list of generic objects instead with shape (n_samples, n_samples_fitted), where n_samples_fitted is the number of samples used in the fitting for the estimator.

  • y (array-like of shape (n_samples,) or (n_samples, n_outputs)) – True values for X.

  • sample_weight (array-like of shape (n_samples,), default=None) – Sample weights.

Returns:

score – \(R^2\) of self.predict(X) w.r.t. y.

Return type:

float

Notes

The \(R^2\) score used when calling score on a regressor uses multioutput='uniform_average' from version 0.23 to keep consistent with default value of r2_score(). This influences the score method of all the multioutput regressors (except for MultiOutputRegressor).

class nirs4all.operators.models.sklearn.aom_ridge.AOMMultiKernelRidge(operator_bank: object = 'compact', *, weight_strategy: str = 'uniform', weight_init: Sequence[float] | None = None, weight_top_k: int | None = None, weight_n_restarts: int = 3, lambda_eta: float = 0.001, weight_max_iter: int = 50, alphas: object = 'auto', alpha_grid_size: int = 50, alpha_low: float = -6.0, alpha_high: float = 6.0, alpha_cv_n_splits: int = 5, kernel_center: bool = True, kernel_normalize: str = 'trace', kernel_eps: float = 1e-12, feature_scaling: str = 'center', one_se_rule: bool = False, random_state: int | None = 0, verbose: int = 0)[source]

Bases: BaseEstimator, RegressorMixin

Multi-kernel Ridge with explicit per-block weights (mkR).

Parameters:
  • operator_bank (str | sequence) – Name of bank or explicit operator list. See aompls.banks.

  • weight_strategy ({"uniform", "manual", "kta", "softmax_cv"}) – How to choose eta.

  • weight_init (sequence of B floats, optional) – For "manual", this is the (pre-projection) eta vector. For "softmax_cv", ignored (random Dirichlet starts).

  • weight_top_k (int, optional) – For "kta" and "softmax_cv" (via inner-CV alpha grid), keep only the top-k highest-aligned blocks. None means all.

  • weight_n_restarts (int) – Random restarts for "softmax_cv".

  • lambda_eta (float) – KL-to-uniform regulariser for "softmax_cv".

  • weight_max_iter (int) – L-BFGS-B max iterations per restart for "softmax_cv".

  • alphas ("auto" or sequence of positive floats) – Alpha grid. "auto" builds a trace-relative grid.

  • alpha_grid_size (grid params (when "auto").)

  • alpha_low (grid params (when "auto").)

  • alpha_high (grid params (when "auto").)

  • alpha_cv_n_splits (int) – K-fold splits for inner alpha CV (and softmax_cv inner CV).

  • kernel_center (passed to AOMKernelizer.)

  • kernel_normalize (passed to AOMKernelizer.)

  • kernel_eps (passed to AOMKernelizer.)

  • feature_scaling ({"center"} (only "center" in v1).)

  • one_se_rule (bool) – Pick largest alpha within one SE of minimum CV RMSE.

  • random_state (int | None)

  • verbose (int)

fit(X: ndarray, y: ndarray) → AOMMultiKernelRidge[source]
predict(X: ndarray) → ndarray[source]
predict_dual(X: ndarray) → ndarray[source]

Predict via the dual form (cross kernels). Used in tests for agreement with primal.

score(X: ndarray, y: ndarray) → float[source]

Return coefficient of determination on test data.

The coefficient of determination, \(R^2\), is defined as \((1 - \frac{u}{v})\), where \(u\) is the residual sum of squares ((y_true - y_pred)** 2).sum() and \(v\) is the total sum of squares ((y_true - y_true.mean()) ** 2).sum(). The best possible score is 1.0 and it can be negative (because the model can be arbitrarily worse). A constant model that always predicts the expected value of y, disregarding the input features, would get a \(R^2\) score of 0.0.

Parameters:
  • X (array-like of shape (n_samples, n_features)) – Test samples. For some estimators this may be a precomputed kernel matrix or a list of generic objects instead with shape (n_samples, n_samples_fitted), where n_samples_fitted is the number of samples used in the fitting for the estimator.

  • y (array-like of shape (n_samples,) or (n_samples, n_outputs)) – True values for X.

  • sample_weight (array-like of shape (n_samples,), default=None) – Sample weights.

Returns:

score – \(R^2\) of self.predict(X) w.r.t. y.

Return type:

float

Notes

The \(R^2\) score used when calling score on a regressor uses multioutput='uniform_average' from version 0.23 to keep consistent with default value of r2_score(). This influences the score method of all the multioutput regressors (except for MultiOutputRegressor).

class nirs4all.operators.models.sklearn.aom_ridge.AOMRidgeAutoSelector(candidates: Sequence[dict[str, Any] | Callable[[], BaseEstimator]] | None = None, outer_cv: int | object = 3, inner_cv: int | object = 3, outer_cv_kind: str = 'spxy', outer_cv_repeats: int = 1, scoring: str = 'rmse_mean', random_state: int = 0, n_jobs: int = 1)[source]

Bases: BaseEstimator, RegressorMixin

Outer-CV variant selector over a list of AOM-Ridge candidates.

For each candidate variant in candidates, run K-fold outer CV (default SPXYFold(3)) and compute the mean RMSE across folds. The candidate with the lowest mean RMSE is selected and refit on the full training set. predict() delegates to the refit estimator.

Parameters:
  • candidates (sequence of variant specs (dicts) or callables, or None) –

    Each spec is a dict with at minimum label and either:

    • factory: a callable returning a fresh sklearn-compatible estimator (the rest of the spec is ignored), or

    • selection / operator_bank / block_scaling / branch_preproc / extra: dispatched to AOMRidgeRegressor, AOMRidgePLS, AOMRidgePLSCV, or AOMPLSRegressor.

    When None (default), uses the 8 HEADLINE variants.

  • outer_cv (int or splitter) – K-fold outer CV. Integer is interpreted by outer_cv_kind.

  • outer_cv_kind ({"spxy", "kfold", "spxy_repeated"}) – Splitter style when outer_cv is integer.

  • outer_cv_repeats (int) – Repeats for outer_cv_kind="spxy_repeated" (ignored otherwise).

  • scoring ({"rmse_mean", "mse_pooled"}) – Aggregation across outer folds.

  • random_state (int) – Seed forwarded to splitters and inner CVs.

  • n_jobs (int) – joblib parallelism over candidates. 1 runs serially, -1 uses all cores.

Variables:
  • selected_variant_label (str) – Label of the chosen candidate.

  • selected_variant_index (int) – Index of the chosen candidate inside self.candidates_.

  • cv_scores (list of float) – Mean RMSE per candidate across outer folds.

  • cv_per_fold_scores (list of list of float) – Per-fold RMSE matrix [n_candidates][n_folds].

  • candidates (list of dict) – Resolved candidate specs (with at least label).

  • refit_estimator (sklearn-compatible estimator) – The chosen candidate refit on the full training set. predict and score delegate to it.

  • refit_branch_preproc (transformer or None) – Branch preprocessor fitted on the full training set, applied to new rows before delegating to refit_estimator_.

fit(X: ndarray, y: ndarray) → AOMRidgeAutoSelector[source]
get_diagnostics() → dict[source]

Return a JSON-serialisable summary of the selection.

predict(X: ndarray) → ndarray[source]
score(X: ndarray, y: ndarray) → float[source]

Return coefficient of determination on test data.

The coefficient of determination, \(R^2\), is defined as \((1 - \frac{u}{v})\), where \(u\) is the residual sum of squares ((y_true - y_pred)** 2).sum() and \(v\) is the total sum of squares ((y_true - y_true.mean()) ** 2).sum(). The best possible score is 1.0 and it can be negative (because the model can be arbitrarily worse). A constant model that always predicts the expected value of y, disregarding the input features, would get a \(R^2\) score of 0.0.

Parameters:
  • X (array-like of shape (n_samples, n_features)) – Test samples. For some estimators this may be a precomputed kernel matrix or a list of generic objects instead with shape (n_samples, n_samples_fitted), where n_samples_fitted is the number of samples used in the fitting for the estimator.

  • y (array-like of shape (n_samples,) or (n_samples, n_outputs)) – True values for X.

  • sample_weight (array-like of shape (n_samples,), default=None) – Sample weights.

Returns:

score – \(R^2\) of self.predict(X) w.r.t. y.

Return type:

float

Notes

The \(R^2\) score used when calling score on a regressor uses multioutput='uniform_average' from version 0.23 to keep consistent with default value of r2_score(). This influences the score method of all the multioutput regressors (except for MultiOutputRegressor).

class nirs4all.operators.models.sklearn.aom_ridge.AOMRidgeBlender(candidates: Sequence[dict[str, Any] | Callable[[], BaseEstimator]] | None = None, outer_cv: int | object = 3, inner_cv: int | object = 3, outer_cv_kind: str = 'spxy', outer_cv_repeats: int = 1, regularizer: float = 0.01, scoring: str = 'mse', random_state: int = 0, n_jobs: int = 1)[source]

Bases: BaseEstimator, RegressorMixin

Convex non-negative blender of AOM-Ridge variant OOF predictions.

For each candidate variant: compute outer-CV out-of-fold predictions, stack them into Z of shape (n_samples, n_candidates), then solve

\[\min_w \| y - Z w \|^2 + \lambda \| w - 1/K \|^2 \;\text{s.t.}\; w \ge 0,\; \sum_k w_k = 1.\]

via SLSQP. Each candidate is then refit on the full training set; new predictions are blended as Z_test @ weights_.

Parameters:
  • candidates (sequence of variant specs (dicts) or callables, or None) – Same convention as AOMRidgeAutoSelector. When None (default), uses the 8 HEADLINE variants minus any auto_select and blender entries (recursion guard).

  • outer_cv (int or splitter) – K-fold outer CV. Integer is interpreted by outer_cv_kind.

  • outer_cv_kind ({"spxy", "kfold", "spxy_repeated"}) – Splitter style when outer_cv is integer.

  • outer_cv_repeats (int) – Repeats for outer_cv_kind="spxy_repeated" (ignored otherwise).

  • regularizer (float) – lambda for the bias-toward-uniform penalty in the QP. Larger values shrink weights toward 1/K (uniform averaging).

  • scoring ({"mse", "rmse"}) – Reported in get_diagnostics() for completeness; the QP objective is always squared error so the blender weights are invariant under this choice.

  • random_state (int) – Seed forwarded to splitters and inner CVs.

  • n_jobs (int) – joblib parallelism over candidates’ outer-CV passes. 1 runs serially, -1 uses all cores.

Variables:
  • weights (ndarray of shape (n_candidates,)) – Convex blending weights on the simplex.

  • oof_predictions (ndarray of shape (n_samples, n_candidates) for 1D y,) – or (n_samples, n_targets, n_candidates) for 2D y. OOF predictions used to solve the QP.

  • selected_variant_label (str) – Label of the candidate carrying the largest weight (for diagnostics).

  • refit_estimators (list) – One refit estimator per candidate, fitted on the full training set.

  • refit_branch_preprocs (list) – Per-candidate branch preprocessor fitted on the full training set (or None when the candidate has no branch).

  • candidates (list of dict) – Resolved candidate specs.

  • cv_scores (list of float) – OOF RMSE per candidate (diagnostic).

fit(X: ndarray, y: ndarray) → AOMRidgeBlender[source]
get_diagnostics() → dict[source]

Return a JSON-serialisable summary of the blending solution.

predict(X: ndarray) → ndarray[source]
score(X: ndarray, y: ndarray) → float[source]

Return coefficient of determination on test data.

The coefficient of determination, \(R^2\), is defined as \((1 - \frac{u}{v})\), where \(u\) is the residual sum of squares ((y_true - y_pred)** 2).sum() and \(v\) is the total sum of squares ((y_true - y_true.mean()) ** 2).sum(). The best possible score is 1.0 and it can be negative (because the model can be arbitrarily worse). A constant model that always predicts the expected value of y, disregarding the input features, would get a \(R^2\) score of 0.0.

Parameters:
  • X (array-like of shape (n_samples, n_features)) – Test samples. For some estimators this may be a precomputed kernel matrix or a list of generic objects instead with shape (n_samples, n_samples_fitted), where n_samples_fitted is the number of samples used in the fitting for the estimator.

  • y (array-like of shape (n_samples,) or (n_samples, n_outputs)) – True values for X.

  • sample_weight (array-like of shape (n_samples,), default=None) – Sample weights.

Returns:

score – \(R^2\) of self.predict(X) w.r.t. y.

Return type:

float

Notes

The \(R^2\) score used when calling score on a regressor uses multioutput='uniform_average' from version 0.23 to keep consistent with default value of r2_score(). This influences the score method of all the multioutput regressors (except for MultiOutputRegressor).

class nirs4all.operators.models.sklearn.aom_ridge.AOMRidgeClassifier(selection: str = 'superblock', operator_bank: str | Sequence[LinearSpectralOperator] = 'compact', alphas: str | Sequence[float] = 'auto', alpha_grid_size: int = 50, alpha_grid_low: float = -6.0, alpha_grid_high: float = 6.0, alpha: float | None = None, cv: int | object = 5, scoring: str = 'rmse', block_scaling: str = 'rms', center: bool = True, scale: bool = False, active_top_m: int = 20, active_diversity_threshold: float = 0.98, random_state: int | None = 0, solver: str = 'auto', scale_power: float = 1.0, adaptive_alpha_grid: bool = True, max_grid_expansions: int = 2, x_scale: str = 'center', active_score_method: str = 'norm', active_max_per_family: int | None = None, global_per_operator_grid: bool = True, selection_rule: str = 'min', mkl_top_k: int = 6, mkl_mode: str = 'alignment', branches: Sequence[str] = ('none', 'snv', 'msc'), calibrator: str = 'logistic', calibration_max_iter: int = 2000)[source]

Bases: BaseEstimator, ClassifierMixin

AOM-Ridge classifier (PLS-DA-style).

Wraps AOMRidgeRegressor on a class-balanced one-hot encoding of y and calibrates predict_proba via a logistic regression fitted on the latent regression scores. All AOM-Ridge selection modes (superblock, global, active_superblock, mkl, branch_global) are available through the selection parameter.

Parameters:
  • selection

  • operator_bank

  • alphas

  • alpha_grid_size

  • alpha_grid_low

:param : :param alpha_grid_high: :param alpha: :param cv: :param scoring: :param block_scaling: :param center: :param scale: :param : :param active_top_m: :param active_diversity_threshold: :param random_state: :param solver: :param : :param scale_power: :param adaptive_alpha_grid: :param max_grid_expansions: :param x_scale: :param : :param active_score_method: :param active_max_per_family: :param global_per_operator_grid: :param : :param selection_rule: Forwarded to the underlying AOMRidgeRegressor. See its

docstring for the full contract.

Parameters:
  • mkl_top_k – Forwarded to the underlying AOMRidgeRegressor. See its docstring for the full contract.

  • mkl_mode – Forwarded to the underlying AOMRidgeRegressor. See its docstring for the full contract.

  • branches – Forwarded to the underlying AOMRidgeRegressor. See its docstring for the full contract.

  • calibrator (str) – "logistic" (default) fits LogisticRegression on training latent scores and uses it for predict_proba. "temperature" skips logistic calibration and uses the temperature-scaled softmax of the latent scores. The logistic path automatically falls back to temperature scaling when logistic fitting fails.

  • calibration_max_iter (int) – max_iter for the logistic calibrator (default 2000).

Variables:
  • classes (np.ndarray) – Sorted unique class labels seen during fit.

  • regressor (AOMRidgeRegressor) – The fitted underlying regressor (after fit).

  • calibrator (LogisticRegression or None) – Fitted calibrator, None when the temperature fallback is active.

  • calibrator_kind (str) – "logistic" or "temperature" depending on which path was used.

  • temperature (float or None) – Fitted temperature (only when calibrator_kind_ == "temperature").

  • diagnostics (dict) – Selection / calibration diagnostics.

decision_function(X: ndarray) → ndarray[source]

Return raw latent scores (regressor output on encoded Y).

fit(X: ndarray, y: ndarray) → AOMRidgeClassifier[source]
get_diagnostics() → dict[source]
get_selected_operators() → list[str][source]
predict(X: ndarray) → ndarray[source]
predict_proba(X: ndarray) → ndarray[source]
score(X: ndarray, y: ndarray) → float[source]

Return balanced accuracy on (X, y).

class nirs4all.operators.models.sklearn.aom_ridge.AOMRidgePLS(operator_bank: str | Sequence[LinearSpectralOperator] = 'compact', n_components: int = 10, ridge_alpha: float = 1.0, ridge_alpha_mode: str = 'absolute', block_scaling: str = 'frobenius', column_scaling: bool = False, center_y: bool = True, scale_y: bool = False, per_component_penalty: str = 'uniform', cv: int | object = 5, random_state: int = 0, max_iter: int = 500, tol: float = 1e-06)[source]

Bases: BaseEstimator, RegressorMixin

Adaptive Operator-Mixture Ridge-PLS regressor.

The model is a PLS decomposition on a multi-block AOM superblock followed by a closed-form ridge regression on the resulting scores. The two hyperparameters are n_components (the latent dimensionality H) and ridge_alpha (the L2 penalty on the score-space coefficients).

Parameters:
  • operator_bank (str or sequence of LinearSpectralOperator) – Operator bank preset name (resolved via aompls.banks.bank_by_name) or an explicit sequence.

  • n_components (int) – Number of PLS components (H).

  • ridge_alpha (float) – Absolute ridge penalty on the score-space coefficients. Must be non-negative; values of 0 reduce to vanilla PLS-on-superblock.

  • ridge_alpha_mode (str) – Either "absolute" (use ridge_alpha directly) or "relative_to_score_variance" (multiply ridge_alpha by the median of diag(T^T T) measured on the train fold). Default is "absolute".

  • block_scaling (str) – Either "frobenius" (s_b = sqrt(n) / ||Z_b||_F) or "none" (raw blocks, s_b = 1). Default "frobenius".

  • column_scaling (bool) – If True, divide the superblock columns by their per-column std.

  • center_y (bool) – If True, center the target (default).

  • scale_y (bool) – If True, divide the centered target by its std.

  • per_component_penalty (str) – How the per-component penalty lambda_h is built from ridge_alpha. "uniform" (default) uses a constant lambda_h = alpha_eff; "exponent_0.5" and "exponent_1.0" use lambda_h = alpha_eff * h**rho with rho 0.5 and 1.0 respectively (Variant 3 from the spec).

  • cv (int or splitter) – Reserved for the AOMRidgePLSCV wrapper. Ignored by AOMRidgePLS itself but kept on the constructor so user-supplied dictionaries can be passed through unchanged.

  • random_state (int) – Random state for the optional CV splitter.

  • max_iter (forwarded to sklearn.cross_decomposition.PLSRegression.)

  • tol (forwarded to sklearn.cross_decomposition.PLSRegression.)

Variables:
  • coef_z (ndarray of shape (B*p, q)) – Coefficient in the standardised superblock space.

  • coef_in_original_space (ndarray of shape (p, q) or None) – Linear-only back-projection of coef_z_ into the original feature space. None when the bank contains a non-fixed-linear operator.

  • coef_by_block (list of ndarray) – One (p, q) slice of coef_z_ per operator block.

  • pls (sklearn.cross_decomposition.PLSRegression) – The fitted PLS object (used only for its rotations / scores).

  • rotations (ndarray of shape (B*p, H)) – The PLS rotation matrix R used to compute scores.

  • score_diag (ndarray of shape (H,)) – Diagonal of T^T T (one value per latent component).

  • shrinkage_factors (ndarray of shape (H,)) – Per-component shrinkage d_h / (d_h + lambda_h).

  • effective_components (float) – Sum of the shrinkage factors (continuous analogue of H).

  • block_importance (ndarray of shape (B,)) – Aggregated rotation L2 norm per block, weighted by per-component shrinkage. Higher = more contribution to predictions.

  • block_component_importance (ndarray of shape (B, H)) – Per-component normalised rotation importance ||R_{b,h}||^2 / sum_j ||R_{j,h}||^2.

  • block_component_importance_ridge (ndarray of shape (B, H)) – Per-component normalised rotation importance weighted by the component shrinkage factor.

  • block_scales (ndarray of shape (B,)) – Per-block scaling s_b learned on the training fold.

  • block_slices (list of slice) – Column slice in the standardised superblock for each operator.

  • n_features_in (int) – Number of input features seen at fit time (X.shape[1]).

fit(X: ndarray, y: ndarray) → AOMRidgePLS[source]
get_diagnostics() → dict[source]

Return a JSON-serialisable summary of the fitted model.

predict(X: ndarray) → ndarray[source]
score(X: ndarray, y: ndarray) → float[source]

Return coefficient of determination on test data.

The coefficient of determination, \(R^2\), is defined as \((1 - \frac{u}{v})\), where \(u\) is the residual sum of squares ((y_true - y_pred)** 2).sum() and \(v\) is the total sum of squares ((y_true - y_true.mean()) ** 2).sum(). The best possible score is 1.0 and it can be negative (because the model can be arbitrarily worse). A constant model that always predicts the expected value of y, disregarding the input features, would get a \(R^2\) score of 0.0.

Parameters:
  • X (array-like of shape (n_samples, n_features)) – Test samples. For some estimators this may be a precomputed kernel matrix or a list of generic objects instead with shape (n_samples, n_samples_fitted), where n_samples_fitted is the number of samples used in the fitting for the estimator.

  • y (array-like of shape (n_samples,) or (n_samples, n_outputs)) – True values for X.

  • sample_weight (array-like of shape (n_samples,), default=None) – Sample weights.

Returns:

score – \(R^2\) of self.predict(X) w.r.t. y.

Return type:

float

Notes

The \(R^2\) score used when calling score on a regressor uses multioutput='uniform_average' from version 0.23 to keep consistent with default value of r2_score(). This influences the score method of all the multioutput regressors (except for MultiOutputRegressor).

class nirs4all.operators.models.sklearn.aom_ridge.AOMRidgePLSCV(operator_bank: str | Sequence[LinearSpectralOperator] = 'compact', n_components_grid: Sequence[int] = (2, 3, 4, 5, 7, 10, 15, 20, 30), ridge_alpha_grid: Sequence[float] | None = None, ridge_alpha_mode: str = 'absolute', block_scaling: str = 'frobenius', column_scaling: bool = False, center_y: bool = True, scale_y: bool = False, per_component_penalty: str = 'uniform', cv: int | object = 5, selection_rule: str = 'min', scoring: str = 'rmse_mean', random_state: int = 0, max_iter: int = 500, tol: float = 1e-06)[source]

Bases: BaseEstimator, RegressorMixin

K-fold CV wrapper that selects (n_components, ridge_alpha) for AOMRidgePLS.

The wrapper performs a fold-local grid search over the cartesian product of n_components_grid and ridge_alpha_grid. Each fold refits the full chain (operator bank -> superblock scaling -> PLS -> ridge) once per H, then solves the closed-form ridge for every alpha in the grid - so no leakage can flow between folds while the alpha sweep adds negligible cost. The best (H, alpha) pair is then refit on the full training set.

Selection follows selection_rule ("min" for argmin of the summary, "1se" for the most-regularised alpha within one SE of the minimum).

Parameters:
  • operator_bank (str or sequence)

  • n_components_grid (sequence of int) – Candidate values for n_components. Default (2, 3, 4, 5, 7, 10, 15, 20, 30).

  • ridge_alpha_grid (sequence of float) – Candidate values for ridge_alpha. Default np.logspace(-4, 4, 9).

  • ridge_alpha_mode (str) – Forwarded to the inner estimator: "absolute" or "relative_to_score_variance".

  • block_scaling

  • column_scaling

  • center_y

  • scale_y

  • per_component_penalty

:param : :param max_iter: :type max_iter: forwarded to the inner estimator. :param tol: :type tol: forwarded to the inner estimator. :param cv: K-fold CV strategy. Integer k -> shuffled KFold(k). Any object

exposing split(X, y) is accepted (e.g. RepeatedSPXYFold).

Parameters:
  • selection_rule (str) – "min" (default) or "1se".

  • scoring (str) – "rmse_mean" (mean of fold RMSEs, default) or "mse_pooled" (pooled RMSE across folds).

  • random_state (int)

Variables:
  • best_n_components (int)

  • best_ridge_alpha (float)

  • best_score (float)

  • cv_results (dict) – Contains "n_components", "ridge_alpha", "mean_rmse" (summary 2D table), "per_fold_rmse" (3D (n_folds, n_h, n_a)), and "actual_n_components" (1D, per H value).

  • estimator (AOMRidgePLS) – The refit estimator on the full training data.

fit(X: ndarray, y: ndarray) → AOMRidgePLSCV[source]
get_diagnostics() → dict[source]
predict(X: ndarray) → ndarray[source]
score(X: ndarray, y: ndarray) → float[source]

Return coefficient of determination on test data.

The coefficient of determination, \(R^2\), is defined as \((1 - \frac{u}{v})\), where \(u\) is the residual sum of squares ((y_true - y_pred)** 2).sum() and \(v\) is the total sum of squares ((y_true - y_true.mean()) ** 2).sum(). The best possible score is 1.0 and it can be negative (because the model can be arbitrarily worse). A constant model that always predicts the expected value of y, disregarding the input features, would get a \(R^2\) score of 0.0.

Parameters:
  • X (array-like of shape (n_samples, n_features)) – Test samples. For some estimators this may be a precomputed kernel matrix or a list of generic objects instead with shape (n_samples, n_samples_fitted), where n_samples_fitted is the number of samples used in the fitting for the estimator.

  • y (array-like of shape (n_samples,) or (n_samples, n_outputs)) – True values for X.

  • sample_weight (array-like of shape (n_samples,), default=None) – Sample weights.

Returns:

score – \(R^2\) of self.predict(X) w.r.t. y.

Return type:

float

Notes

The \(R^2\) score used when calling score on a regressor uses multioutput='uniform_average' from version 0.23 to keep consistent with default value of r2_score(). This influences the score method of all the multioutput regressors (except for MultiOutputRegressor).

class nirs4all.operators.models.sklearn.aom_ridge.AOMRidgeRegressor(selection: str = 'superblock', operator_bank: str | Sequence[LinearSpectralOperator] = 'compact', alphas: str | Sequence[float] = 'auto', alpha_grid_size: int = 50, alpha_grid_low: float = -6.0, alpha_grid_high: float = 6.0, alpha: float | None = None, cv: int | object = 5, scoring: str = 'rmse_mean', block_scaling: str = 'rms', center: bool = True, scale: bool = False, active_top_m: int = 20, active_diversity_threshold: float = 0.98, random_state: int | None = 0, solver: str = 'auto', scale_power: float = 1.0, adaptive_alpha_grid: bool = True, max_grid_expansions: int = 2, x_scale: str = 'center', active_score_method: str = 'norm', active_max_per_family: int | None = None, global_per_operator_grid: bool = True, selection_rule: str = 'min', branches: Sequence[str] = ('none', 'snv', 'msc'), mkl_top_k: int = 6, mkl_mode: str = 'alignment')[source]

Bases: BaseEstimator, RegressorMixin

Adaptive Operator-Mixture Ridge regressor (dual / kernel).

The Ridge solution is computed via a dual / kernel formulation that never materialises the wide superblock feature matrix. The fitted coef_ has shape (p, q) and lives in the original feature space, so the estimator is a drop-in replacement for sklearn.linear_model.Ridge.

Parameters:
  • selection (str) – One of "superblock", "global", "active_superblock", "branch_global", or "mkl".

  • operator_bank (str or sequence) – Bank preset name (resolved by aompls.banks.bank_by_name) or an explicit sequence of LinearSpectralOperator instances. Identity is always present (added if missing).

  • alphas (str or sequence) – "auto" (trace-relative log grid) or an explicit sequence of positive scalars.

  • alpha_grid_size – Parameters for the auto grid (only used when alphas == "auto").

  • alpha_grid_low – Parameters for the auto grid (only used when alphas == "auto").

  • alpha_grid_high – Parameters for the auto grid (only used when alphas == "auto").

  • alpha (float, optional) – If provided, skip alpha CV and use this fixed alpha.

  • cv (int or splitter) – Integer KFold size or any sklearn-compatible splitter (e.g. SPXYFold).

  • block_scaling (str) – "rms" (default) or "none".

  • center (bool) – If True, center X and Y before computing kernels.

  • scale (bool) – Reserved; True is not implemented and raises.

  • active_top_m (int) – Maximum active operators in active-superblock mode.

  • active_diversity_threshold (float) – Cosine threshold for response-based pruning.

  • branches (sequence of str) – Branches probed by selection="branch_global". Each entry must be in aomridge.branches.VALID_BRANCHES.

  • mkl_top_k (int) – Number of blocks kept by the MKL-light alignment weights.

  • mkl_mode (str) – Weight-learning mode (currently only "alignment").

  • selection_rule (str) – "min" (default) or "1se" (one standard error rule).

  • scoring (str) – "rmse_mean", "mse_pooled", or "rmse_pooled_trimmed". These average per-fold RMSE, pool squared errors, or pool residuals and discard the largest 5% by magnitude before computing RMSE.

  • random_state (int, optional) – Seed for the default KFold shuffle when cv is an integer.

  • solver (str) – "auto", "cholesky", or "eigh".

Variables:
  • y_mean, (coef, intercept, alpha, alphas, dual_coef, x_mean,)

  • selected_operator_indices, (block_scales, selected_operators,)

  • only). (diagnostics, mkl_weights (mkl mode)

fit(X: ndarray, y: ndarray) → AOMRidgeRegressor[source]
get_diagnostics() → dict[source]
get_selected_operators() → list[str][source]
predict(X: ndarray) → ndarray[source]
score(X: ndarray, y: ndarray) → float[source]

Return coefficient of determination on test data.

The coefficient of determination, \(R^2\), is defined as \((1 - \frac{u}{v})\), where \(u\) is the residual sum of squares ((y_true - y_pred)** 2).sum() and \(v\) is the total sum of squares ((y_true - y_true.mean()) ** 2).sum(). The best possible score is 1.0 and it can be negative (because the model can be arbitrarily worse). A constant model that always predicts the expected value of y, disregarding the input features, would get a \(R^2\) score of 0.0.

Parameters:
  • X (array-like of shape (n_samples, n_features)) – Test samples. For some estimators this may be a precomputed kernel matrix or a list of generic objects instead with shape (n_samples, n_samples_fitted), where n_samples_fitted is the number of samples used in the fitting for the estimator.

  • y (array-like of shape (n_samples,) or (n_samples, n_outputs)) – True values for X.

  • sample_weight (array-like of shape (n_samples,), default=None) – Sample weights.

Returns:

score – \(R^2\) of self.predict(X) w.r.t. y.

Return type:

float

Notes

The \(R^2\) score used when calling score on a regressor uses multioutput='uniform_average' from version 0.23 to keep consistent with default value of r2_score(). This influences the score method of all the multioutput regressors (except for MultiOutputRegressor).