missing_aware_nipals — Missing-aware NIPALS¶
Group: Missing data · Registry tolerance: 10.0
Description¶
Missing-aware NIPALS PLS (§13)
From the pls4all.sklearn.MissingAwareNipalsRegression docstring:
Nelson 1996 missing-aware NIPALS PLS.
Registry note — R
softImpute+pls::plsrreference: matrix completion + SIMPLS. Different imputation algorithm than Nelson 1996 NIPALS-missing; same goal. Cell has no missing values so softImpute reduces to mean-fill; widened tolerance flags ref presence.
Parameters¶
Name |
Type |
Default |
Notes |
|---|---|---|---|
|
|
|
Number of latent components extracted (k). |
Explanations¶
Bibliographic source¶
Walczak, B. & Massart, D. L. (2001). Dealing with missing data: part I & II. Chemometrics and Intelligent Laboratory Systems 58(1), 15–27 & 29–42. — applied to the NIPALS PLS algorithm.
Mathematical principle¶
Standard PLS cannot ingest NaN values: the matrix operations propagate NaN. Missing-aware NIPALS treats missing entries as excluded from the inner products in the iterative loading-weight calculation. Concretely, the score \(t_i = \sum_{j \in \mathcal{O}_i} x_{ij} w_j\) and the loading \(p_j = \sum_{i \in \mathcal{O}_j} x_{ij} t_i / \sum_{i \in \mathcal{O}_j} t_i^2\) are computed only over the observed indices \(\mathcal{O}_{i}, \mathcal{O}_{j}\).
Convergence is slower than vanilla NIPALS and the result is sensitive to the missingness pattern, but the alternative (delete rows with any NaN or impute by column means) usually performs much worse on spectroscopic data. Acceptable up to ~10 % missing entries; beyond that low-rank matrix completion (softImpute) is a better front-end.
Note that missing-aware NIPALS produces a regression model that can still predict on complete new \(\mathbf{x}\); only the training step tolerates missing data.
Implementation¶
n4m_missing_aware_nipals_fit. Reference: R softImpute 1.4.3 for the imputation step; the PLS fitting itself is in-tree.
MATLAB header (bindings/matlab/+pls4all/MissingAwareNipalsRegression.m):
pls4all.MissingAwareNipalsRegression Nelson 1996 missing-aware NIPALS PLS.
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_missing_aware_nipals_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 missing_aware_nipals_fit
with pls4all.Context() as ctx, pls4all.Config() as cfg:
res = missing_aware_nipals_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 MissingAwareNipalsRegression
mdl = MissingAwareNipalsRegression(n_components=2)
mdl.fit(X, y)
y_hat = mdl.predict(X_test)
library(pls4all)
# Unified low-level dispatcher (May 2026 R cleanup):
res <- pls4all_method("missing_aware_nipals", X, y,
n_components = 4L)
# res is a named list with MethodResult arrays/scalars.
# selected_indices / top_k_intervals are 1-based.
res = pls4all.missing_aware_nipals(X, y, 4);
% see header of bindings/matlab/+pls4all/missing_aware_nipals.m for full
% parameter surface:
% res = missing_aware_nipals(X, Y, n_components)
yhat = predict(res, Xtest);
mdl = pls4all.fit("missing_aware_nipals", X, y, "NumComponents", 4);
yhat = predict(mdl, Xtest);
Registry parity references 📐
📐
ref.r_softimpute(R · r) —softImpute1.4-1 · qualitative (rmse_rel ≤ 1e+01) — RsoftImpute::softImputefollowed bypls::plsron the completed (X, Y). Different imputation algorithm than Nelson 1996 NIPALS-missing; same goal.
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.
| Backend | Parity | 200×30 (ms) |
|---|---|---|
| C++ native · libn4m | ||
pls4all.cpp.blas+omp | ✓ ref 8e-15 | 1.27 ms |
| Python · pls4all | ||
pls4all.python | ✓ bind | 1.25 ms🏆 |
pls4all.sklearn | ✓ bind | 1.39 ms |
| R · pls4all | ||
pls4all.R | ✓ bind | 4.25 ms |
pls4all.R.formula | ✓ bind | 4.88 ms |
pls4all.R.mdatools | ✓ bind | 5.41 ms |
pls4all.R.pls | ✓ bind | 4.85 ms |
| R · external | ||
📐ref.r_softimpute | source | 13.6 ms |
| Backend | Parity | 200×30 (ms) |
|---|---|---|
| C++ native · libn4m | ||
pls4all.cpp.blas+omp | ✓ ref 8e-15 | 1.22 ms🏆 |
| Python · pls4all | ||
pls4all.python | ✓ bind | 1.36 ms |
pls4all.sklearn | ✓ bind | 1.37 ms |
| R · pls4all | ||
pls4all.R | ✓ bind | 4.02 ms |
pls4all.R.formula | ✓ bind | 4.84 ms |
pls4all.R.mdatools | ✓ bind | 4.88 ms |
pls4all.R.pls | ✓ bind | 4.63 ms |
| R · external | ||
📐ref.r_softimpute | source | 14.9 ms |
| Backend | Parity | 200×30 (ms) |
|---|---|---|
| C++ native · libn4m | ||
pls4all.cpp.blas+omp | ✓ ref 8e-15 | 1.34 ms🏆 |
| Python · pls4all | ||
pls4all.python | ✓ bind | 1.79 ms |
pls4all.sklearn | ✓ bind | 3.36 ms |
| R · pls4all | ||
pls4all.R | ✓ bind | 12.2 ms |
pls4all.R.formula | ✓ bind | 16.6 ms |
pls4all.R.mdatools | ✓ bind | 12.2 ms |
pls4all.R.pls | ✓ bind | 18.2 ms |
| R · external | ||
📐ref.r_softimpute | source | 29.9 ms |
See also: benchmark overview · methods index · interactive dashboard