bipls_select — biPLS — Backward Interval PLS

Group: Variable selector · Registry tolerance: 0.7

Description

biPLS backward interval elimination (§18 Phase 5p)

Registry note — R mdatools::ipls(method='backward'). Mask RMSE-rel ~0=perfect, ~1=half disagree, ~1.41=disjoint; tolerance 0.7 enforces ~50% overlap. Backward elimination is order-sensitive.

Parameters

Name

Type

Default

Notes

n_components

int

2

current public binding signature

interval_width

int

10

current public binding signature

min_intervals

int

2

current public binding signature

n_folds

int

3

current public binding signature

Explanations

Bibliographic source

Leardi, R. & Nørgaard, L. (2004). Sequential application of backward interval partial least squares and genetic algorithms for the selection of relevant spectral regions. Journal of Chemometrics 18(11), 486–497. Verified primary link: https://doi.org/10.1002/cem.893.

Mathematical principle

Start with the spectrum partitioned into \(I\) equal intervals (typically 10–40). At each iteration, remove the interval whose removal least hurts CV-RMSE — i.e. the least informative interval. Iterate until removing any further interval materially worsens performance.

Returns a multi-band subset with each band aligned to the original equal-partition grid. The discrete structure makes biPLS robust to noise (no fine-grained fishing) and easy to interpret (each retained interval is a spectroscopic region of contiguous wavelengths).

Commonly chained with GA-PLS as a coarse-to-fine pipeline (Leardi & Nørgaard 2004): biPLS narrows the candidate intervals, GA-PLS does the within-interval feature selection.

Appropriate uses

Backward elimination of predefined spectral intervals using PLS validation error.

Limits and validation

Greedy deletion cannot recover removed intervals and repeated CV comparison can produce optimistic subset estimates.

Implementation

n4m_feature_selection_bipls_select. Reference: R plsVarSel.

Sources and provenance

Current implementation: cpp/src/core/bipls_selection.cpp.

API and bindings

C ABI (ABI 2): n4m_feature_selection_bipls_select. Use the linked public header for the exact signature, configuration, and result handles.

Python (verified public re-export):

from n4m.feature_selection.wrapper import BiPLS

Source signature: BiPLS(*, n_components: int = 2, interval_width: int = 10, min_intervals: int = 2, n_folds: int = 3) (n4m/_impl/selection.py).

R (source-verified): bipls_select(X, Y, n_components, interval_width = 10L, min_intervals = 1L).

The source signature has additional required inputs, so no example call is fabricated.

MATLAB / Octave (source-verified): bipls_select(X, Y, n_components, interval_width, min_intervals).

The source signature has additional required inputs, so no example call is fabricated.

Registry parity references 📐

  • 📐 ref.r_mdatools (R · r) — mdatools 0.15.0 · qualitative (rmse_rel ≤ 7e-01) — R mdatools::ipls(method='backward') — biPLS elimination. Returns variables from intervals that survive the backward sweep.

Benchmarks

Archived measurement identity. Backend labels in this table are the raw IDs recorded when the benchmark ran (including historical pls4all.* IDs). They preserve measurement provenance and do not describe a current public Python, R, or MATLAB binding; use the source-verified API and bindings section above for current entry points.

Adaptive wall-clock per cell measured against full_matrix.csv. Only backends that implement this method are listed; libraries without the method are omitted.

Verdict  ·  ✓ ref / ≈ ref / ~ shape mark a reference-gate pass at strict / relaxed / qualitative tolerance  ·  ✓ bind = archived binding-harness result agrees with the C++ baseline  ·  ⇄ cross-check = documented by-design selector/RNG/model, noncanonical API/facade convention, or secondary oracle  ·  ✗ divergent  ·  ⚠ error  ·  — not run. The fastest backend per column is marked 🏆.

Reference gate: qualitative — shape/smoke comparison only. The external library and archived benchmark harness do not produce numerically equivalent output for this method (see the MethodSpec notes); the rmse_rel_tol ≤ 7e-01 budget is set wide on purpose. Treat ~ shape as “we ran both, both finished”, not as numerical agreement.

Rows tagged with 📐 are the canonical parity references for this method (declared in parity_timing.registry). C++ and external rows show reference parity; archived language-harness rows show binding parity against the C++ backend. Hover the icon for role and tolerance band.

BackendParity200×40 (ms)
C++ native · libn4m
pls4all.cpp.blas+omp✓ J 1.003.83 ms
Python · archived pls4all benchmark
pls4all.python✓ J 1.003.60 ms🏆
pls4all.sklearn✓ J 1.003.69 ms
R · archived pls4all benchmark
pls4all.R✓ J 1.008.26 ms
pls4all.R.formula✓ J 1.0011.7 ms
pls4all.R.mdatools✓ J 1.009.90 ms
pls4all.R.pls✓ J 1.008.83 ms
R · external
📐ref.r_mdatoolssource365.6 ms
BackendParity200×40 (ms)
C++ native · libn4m
pls4all.cpp.blas+omp✓ J 1.003.49 ms🏆
Python · archived pls4all benchmark
pls4all.python✓ J 1.003.58 ms
pls4all.sklearn✓ J 1.003.74 ms
R · archived pls4all benchmark
pls4all.R✓ J 1.009.93 ms
pls4all.R.formula✓ J 1.0025.5 ms
pls4all.R.mdatools✓ J 1.0015.1 ms
pls4all.R.pls✓ J 1.0024.8 ms
R · external
📐ref.r_mdatoolssource1.0 s
BackendParity200×40 (ms)
C++ native · libn4m
pls4all.cpp.blas+omp✓ J 1.0014.3 ms
Python · archived pls4all benchmark
pls4all.python✓ J 1.0013.4 ms
pls4all.sklearn✓ J 1.005.97 ms🏆
R · archived pls4all benchmark
pls4all.R✓ J 1.0023.9 ms
pls4all.R.formula✓ J 1.0035.4 ms
pls4all.R.mdatools✓ J 1.0016.3 ms
pls4all.R.pls✓ J 1.0021.7 ms
R · external
📐ref.r_mdatoolssource333.9 ms

See also: benchmark overview · methods index · interactive dashboard