kernel_pls_rbf — Kernel PLS (Rosipal & Trejo 2001)

Group: Nonlinear / local · Registry tolerance: 2.0

Description

Non-linear kernel PLS (RBF kernel)

From the pls4all.sklearn.KernelPLSRegression docstring:

Non-linear kernel PLS (Rosipal & Trejo 2001).

Registry note — R kernlab::kernelMatrix (RBF/poly/sigmoid) + pls::plsr on the centered kernel matrix is the Rosipal-Trejo (2001) reference. pls4all’s deflation ordering differs from the kernel-PLS-2 of Rosipal & Trejo so parity is qualitative.

Parameters

Name

Type

Default

Notes

n_components

int

2

Number of latent components extracted (k).

kernel_type

int

1

Kernel family: 0=linear, 1=RBF, 2=polynomial, 3=sigmoid.

gamma

float

0.0

RBF kernel bandwidth γ (with K(x, x’) = exp(-γ‖x − x’‖²)).

coef0

float

1.0

Independent term in polynomial / sigmoid kernels.

degree

int

3

Degree of the polynomial kernel (ignored otherwise).

Explanations

Bibliographic source

Rosipal, R. & Trejo, L. J. (2001). Kernel partial least squares regression in reproducing kernel Hilbert space. Journal of Machine Learning Research 2, 97–123.

Mathematical principle

Kernel PLS runs the NIPALS PLS procedure entirely in the feature space of a Mercer kernel \(k(\mathbf{x}, \mathbf{x}') = \langle \phi(\mathbf{x}), \phi(\mathbf{x}') \rangle\) without ever forming \(\phi\) explicitly. The kernel matrix \(\mathbf{K}_{ij} = k(\mathbf{x}_i, \mathbf{x}_j) \in \mathbb{R}^{n \times n}\) replaces \(\mathbf{X}\mathbf{X}^{\top}\) in the NIPALS recursion and the score matrix is built directly from \(\mathbf{K}\).

The RBF kernel \(k(\mathbf{x}, \mathbf{x}') = \exp(-\gamma \|\mathbf{x} - \mathbf{x}'\|^2)\) is the standard choice for non-linear PLS: it captures smooth non-linear relationships between \(\mathbf{X}\) and \(y\) at the cost of a single bandwidth hyperparameter \(\gamma\). Other kernels (polynomial, sigmoid) are available via the kernel_type enum.

Memory scales as \(O(n^2)\) which is the binding constraint for kernel PLS on spectroscopy datasets; subsampling (Nyström) or random Fourier features are the standard scale-up strategies but are not currently exposed.

Implementation

n4m_kernel_pls_fit. Predict-on-new-X is currently marked in-sample-only in the Python sklearn wrapper because the C ABI does not yet export the kernel-centring constants required to handle a fresh test point. The tier-1 entry point will refit on (X_train ∪ X_test) on demand.

MATLAB header (bindings/matlab/+pls4all/KernelPlsRegression.m):

pls4all.KernelPlsRegression  Non-linear kernel PLS (Rosipal & Trejo 2001).

 **In-sample only**: the C ABI exports `alpha` and `y_mean` but NOT the
 kernel-centering state needed to compute K(X_new, X_train) at predict
 time. predict(X) returns the stored predictions when X matches the
 training matrix (content equality), otherwise raises an error.

Usage

Every pls4all binding tab dispatches into the same C kernel; the external libraries listed at the bottom of the page are the parity references registered in benchmarks.parity_timing.registry. Switch tabs to read the same fit in your language. The R package now ships drop-in-compatible facades for the CRAN pls package (plsr, pcr, mvr) and for the mdatools::pls(x, y, ...) matrix idiom — those tabs appear only on the methods that have a meaningful equivalence.

pls4all bindings

/* C ABI — libn4m */
n4m_context_t* ctx = n4m_context_create();
n4m_config_t*  cfg = n4m_config_create();
n4m_method_result_t* res = NULL;
n4m_kernel_pls_rbf_fit(ctx, cfg, &x_view, &y_view, /* hyperparams */, &res);
/* … read coefficients / mask / scores via */
/* n4m_method_result_get_double_matrix / vector / scalar … */
n4m_method_result_destroy(res);
n4m_config_destroy(cfg);
n4m_context_destroy(ctx);
import pls4all
from pls4all._methods import kernel_pls_rbf_fit
with pls4all.Context() as ctx, pls4all.Config() as cfg:
    res = kernel_pls_rbf_fit(ctx, cfg, X, y, n_components=4)
# then: res.matrix("predictions"), res.matrix("coefficients"),
# res.vector("mask"), res.scalar("intercept"), …
from pls4all.sklearn import KernelPLSRegression
mdl = KernelPLSRegression(n_components=2, kernel_type=1, gamma=0.0, coef0=1.0, degree=3)
mdl.fit(X, y)
y_hat = mdl.predict(X_test)
library(pls4all)
# Unified low-level dispatcher (May 2026 R cleanup):
res <- pls4all_method("kernel_pls_rbf", X, y,
                      n_components = 4L, params = list(kernel_type = 1L, gamma = 0.02, coef0 = 1.0, degree = 3L))
# res is a named list with MethodResult arrays/scalars.
# selected_indices / top_k_intervals are 1-based.
res = pls4all.kernel_pls(X, y, 4);
% see header of bindings/matlab/+pls4all/kernel_pls.m for full
% parameter surface:
%   res = kernel_pls(X, Y, n_components, kernel_type, gamma, coef0, degree)
yhat = predict(res, Xtest);
mdl  = pls4all.fit("kernel_pls_rbf", X, y, "NumComponents", 4);
yhat = predict(mdl, Xtest);

Registry parity references 📐

  • 📐 ref.r_kernlab_pls (R · r) — kernlab+pls 0.9.33+2.8.5 · qualitative (rmse_rel ≤ 2e+00) — R kernlab::kernelMatrix (RBF/poly/sigmoid) + pls::plsr on the centered kernel matrix is a Rosipal-Trejo-style kernel PLS reference. pls4all uses a different deflation order so the parity is qualitative.

Benchmarks

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 = pls4all binding 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: strict — numeric equivalence (rmse_rel_tol 1e-08).

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

BackendParity200×50 (ms)
C++ native · libn4m
pls4all.cpp.blas+omp✓ ref 5e-153.07 ms🏆
Python · pls4all
pls4all.python✓ bind3.23 ms
pls4all.sklearn✓ bind3.23 ms
R · pls4all
pls4all.R✓ 1e-146.34 ms
pls4all.R.formula✓ 1e-147.05 ms
pls4all.R.mdatools✓ 1e-146.83 ms
pls4all.R.pls✓ 1e-147.21 ms
R · external
📐ref.r_kernlab_plssource28.6 ms
BackendParity200×50 (ms)
C++ native · libn4m
pls4all.cpp.blas+omp✓ ref 5e-153.12 ms🏆
Python · pls4all
pls4all.python✓ bind3.17 ms
pls4all.sklearn✓ bind3.29 ms
R · pls4all
pls4all.R✓ 1e-145.98 ms
pls4all.R.formula✓ 1e-147.13 ms
pls4all.R.mdatools✓ 1e-147.16 ms
pls4all.R.pls✓ 1e-147.20 ms
R · external
📐ref.r_kernlab_plssource27.3 ms
BackendParity200×50 (ms)
C++ native · libn4m
pls4all.cpp.blas+omp✓ ref 5e-153.18 ms
Python · pls4all
pls4all.python✓ bind3.14 ms🏆
pls4all.sklearn✓ bind3.22 ms
R · pls4all
pls4all.R✓ 1e-146.09 ms
pls4all.R.formula✓ 1e-147.28 ms
pls4all.R.mdatools✓ 1e-147.22 ms
pls4all.R.pls✓ 1e-147.41 ms
R · external
📐ref.r_kernlab_plssource40.0 ms

See also: benchmark overview · methods index · interactive dashboard