PLSRegression#
- class chemotools.regression.PLSRegression(n_components: int = 2, *, scale: bool = True, algorithm: int = 1, copy: bool = True, dtype: type = <class 'numpy.float64'>)[source]
Bases:
DocLinkMixin,PLSPLS regression via Improved Kernel PLS with automatic explained variance.
This estimator wraps the fast, exact Improved Kernel PLS algorithms [1] from the ikpls package [2] in a scikit-learn-conformant regressor + transformer, and automatically calculates explained variance ratios for both X-space and Y-space after fitting, making it easy to use with diagnostic plots and following the same API as PCA.
Compared to
sklearn.cross_decomposition.PLSRegression(NIPALS) [3] and [4], the Improved Kernel PLS algorithms are faster [5] while still being numerically stable [6]. Predictions and regression coefficients agree with NIPALS; individual weight/score/loading vectors are identical up to a per-component sign, which is arbitrary in PLS.Additional capabilities inherited from ikpls:
predict_all_components()returns predictions for every number of components1..n_componentsin a single call (shape(n_components, n_samples, n_targets)), making component selection via (cross-)validation cheap.Fine-grained preprocessing on the backend: the ikpls model supports independent
center_X/center_Y/scale_X/scale_Yand a configurableddof. This wrapper exposes only a singlescaleflag (XandYare always mean-centered) and fixesddof = 1, to mirror the previous scikit-learn-backedPLSRegression. A maintainer can enable the independent flags or a differentddofon the inner model, but they change the fitted model and the explained-variance computation.Sample weights: the backend’s
fitacceptssample_weight(when given, the innerX/Ymeans and standard deviations become their weighted variants). This wrapper does not exposesample_weight; whether to enable it is left to the maintainer.
- Parameters:
n_components (int, default=2) – Number of components to keep. Should be in [1, min(n_samples, n_features)].
scale (bool, default=True) – Whether to scale
XandYto unit standard deviation before fitting.XandYare always mean-centered, matching the previous scikit-learn-backedPLSRegression. Internally this maps onto the ikpls backend ascenter_X = center_Y = Trueandscale_X = scale_Y = scale.algorithm (int, default=1) – Improved Kernel PLS algorithm to use, either 1 or 2. Algorithm 1 uses
Xdirectly, while algorithm 2 buildsX.T @ Xand is typically faster for tall matrices (many more samples than features). Both algorithms give the same results.copy (bool, default=True) – Whether to copy
XandYin fit before applying centering and potentially scaling.dtype (type, default=numpy.float64) – Floating point dtype used for the computations.
- Variables:
explained_x_variance_ratio (ndarray of shape (n_components,)) – Fraction of the total preprocessed training X sum of squares explained by each component (not cumulative). See Notes for the calculation and numerical caveats.
explained_y_variance_ratio (ndarray of shape (n_components,)) – Fraction of the total preprocessed training Y sum of squares explained by each component (not cumulative). For multiple targets, sums of squares are aggregated across all targets. These ratios describe training-data variance, not predictive performance on unseen data. See Notes for the calculation and numerical caveats.
x_scores (ndarray of shape (n_samples, n_components)) – The training X-scores
T(the projection of the preprocessed trainingXontox_rotations_), equal totransform(X)on the training data. (There is noy_scores_attribute; the Y-scores are available on demand viatransform(X, y)– seetransform()for the caveat on how they relate to scikit-learn.)y_weights_, (All other fitted attributes (x_weights_,)
y_rotations_, (x_loadings_, y_loadings_, x_rotations_,)
are (coef_, intercept_, n_features_in_, feature_names_in_))
the (inherited unchanged from the ikpls backend (ikpls.sklearn.PLS); see)
(https (ikpls documentation)
definitions.
References
Examples
Basic usage with automatic variance calculation
>>> from chemotools.regression import PLSRegression >>> import numpy as np >>> >>> # Generate sample data >>> X = np.random.randn(100, 50) >>> y = X[:, 0] + 2*X[:, 1] + np.random.randn(100)*0.1 >>> >>> # Fit model >>> pls = PLSRegression(n_components=5) >>> pls.fit(X, y) >>> >>> # Variance ratios are automatically available! >>> print( ... f"LV1 explains {pls.explained_y_variance_ratio_[0]*100:.1f}%" ... ) >>> print(f"Total Y variance: {pls.explained_y_variance_ratio_.sum()*100:.1f}%") >>> >>> # Predictions for ALL component counts 1..5 in a single call >>> all_predictions = pls.predict_all_components(X) >>> >>> # Use with plotting >>> from chemotools.plotting import ExplainedVariancePlot >>> plot = ExplainedVariancePlot(pls.explained_y_variance_ratio_) >>> plot.show()
Notes
Variance Calculation:
Component sums of squares are computed directly from squared X-score and loading norms [7]. Both X and Y contributions use X-scores, consistent with regression-mode PLS.
Let
t_a,p_a, andq_abe columnaofx_scores_,x_loadings_, andy_loadings_, respectively. LetX_candY_cdenote the training blocks after applying the fitted means and, whenscale=True, the fitted standard deviations (ddof=1). Then:explained_x_variance_ratio_[a] = sum(t_a**2) * sum(p_a**2) / sum(X_c**2) explained_y_variance_ratio_[a] = sum(t_a**2) * sum(q_a**2) / sum(Y_c**2)
Each sum is over all elements of its vector or matrix. Thus the denominators are the total sums of squares of the preprocessed blocks, not the residual sums of squares after earlier components.
For orthogonal fitted X-scores, these contributions equal the reduction in residual sum of squares from sequential PLS deflation, up to numerical precision [4] [7]. No explicit deflation is performed here.
X ratios sum to approximately 1 when the fitted components reconstruct the preprocessed X block. Y ratios do not need to sum to 1: variation in Y that the X-scores cannot explain remains in the residual.
The same calculation is used for both algorithms. Ratios are non-negative for finite fitted scores and loadings and positive total variance. There is no explicit rank thresholding, clipping, or renormalization; components near or beyond numerical rank depend on the backend’s numerical behavior.
A block with zero total variance has undefined ratios (
NaN).
Differences from the previous scikit-learn (NIPALS) backend:
The NIPALS-specific
max_iterandtolparameters do not exist: Improved Kernel PLS is an exact, non-iterative solver.The single
scaleparameter is retained with the same meaning (XandYare always mean-centered, andscaletoggles unit-variance scaling of both). The ikpls backend’s independentcenter_X/center_Y/scale_X/scale_Yare not exposed here.Score/weight/loading vectors may differ from NIPALS by a per-component sign; predictions, coefficients, and explained variances are unaffected.
See also
sklearn.cross_decomposition.PLSRegressionscikit-learn’s NIPALS-based PLS.
chemotools.plotting.ExplainedVariancePlotVisualization for explained variance.
Attributes
center_Xcenter_Yddofscale_Xscale_Yy_rotations_The rotations mapping
Ydirectly to its scores.- property center_X: bool
- property center_Y: bool
- property scale_X: bool
- property scale_Y: bool
- property ddof: int
- fit(X: ndarray, y: ndarray) PLSRegression[source]
Fit model to data and compute explained variance ratios.
This method extends
ikpls.sklearn.PLS.fitby storing the training X-scores and calculating explained variance ratios. See the Notes section ofPLSRegressionfor calculation details.- Parameters:
X (array-like of shape (n_samples, n_features)) – Training vectors. Accepts numpy arrays, pandas DataFrames.
y (array-like of shape (n_samples,) or (n_samples, n_targets)) – Target vectors. Accepts 1D (univariate) or 2D (multivariate) targets.
- Returns:
self – Fitted estimator with populated variance attributes:
explained_x_variance_ratio_andexplained_y_variance_ratio_.- Return type:
PLSRegression
- fit_transform(X: ndarray, y: ndarray) Tuple[ndarray, ndarray][source]
Learn and apply the dimension reduction on the training data.
Fits and returns the
(x_scores, y_scores)tuple, matchingsklearn.cross_decomposition.PLSRegression.fit_transform. Unlike the ikpls backend’sfit_transform, this wrapper does not acceptsample_weight(it is intentionally not exposed; see the class docstring).- Parameters:
X (array-like of shape (n_samples, n_features)) – Training vectors.
y (array-like of shape (n_samples,) or (n_samples, n_targets)) – Target vectors.
- Returns:
(x_scores, y_scores) – The training X-scores and Y-scores.
- Return type:
tuple of ndarray
- transform(X, y=None)[source]
Project
X(and optionallyY) onto the latent components.Returns the X-scores; when
yis given, also returns the Y-scores as an(x_scores, y_scores)tuple, matchingsklearn.cross_decomposition.PLSRegression.transform.Note on the Y-scores: the returned Y-scores are the projection of the preprocessed
Yontoy_rotations_– the same quantity scikit-learn’stransform(X, y)returns, but not the classic NIPALSuvectors (which scikit-learn stores in itsy_scores_attribute). In regression-mode PLS,Yis deflated by the X-scores, soudepends onXand is not recoverable as any linear projection ofY; the rotation projection anducoincide only under canonical deflation (PLSCanonical). This class therefore does not expose ay_scores_attribute.- Parameters:
X (array-like of shape (n_samples, n_features)) – Predictor variables to project.
y (array-like of shape (n_samples,) or (n_samples, n_targets), optional) – Response variables to project. If given, Y-scores are also returned.
- Returns:
x_scores (ndarray of shape (n_samples, n_components)) – Returned when
yis None.(x_scores, y_scores) (tuple of ndarray) – Returned when
yis given.
- set_fit_request() PLSRegression
No-op.
Calling this method has no effect.
- Returns:
self – The updated object.
- Return type:
- set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') PLSRegression
Configure whether metadata should be requested to be passed to the
scoremethod.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(seesklearn.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 toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.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.