Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e04fb58

Browse files
authored
FIX Ensure that GaussianProcessRegressor predict method does not modify input (#24405)
1 parent 85c2c3a commit e04fb58

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

doc/whats_new/v1.2.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,11 @@ Changelog
243243
`nu=0.5` for PyPy (and possibly other non CPython interpreters). :pr:`24245`
244244
by :user:`Loïc Estève <lesteve>`.
245245

246+
- |Fix| The `fit` method of :class:`gaussian_process.GaussianProcessRegressor`
247+
will not modify the input X in case a custom kernel is used, with a `diag`
248+
method that returns part of the input X. :pr:`24405`
249+
by :user:`Omar Salman <OmarManzoor>`.
250+
246251
:mod:`sklearn.kernel_approximation`
247252
...................................
248253

@@ -305,7 +310,7 @@ Changelog
305310
- |Fix| Allows `csr_matrix` as input for parameter: `y_true` of
306311
the :func:`metrics.label_ranking_average_precision_score` metric.
307312
:pr:`23442` by :user:`Sean Atukorala <ShehanAT>`
308-
313+
309314
- |Fix| :func:`metrics.ndcg_score` will now trigger a warning when the `y_true`
310315
value contains a negative value. Users may still use negative values, but the
311316
result may not be between 0 and 1. Starting in v1.4, passing in negative

sklearn/gaussian_process/_gpr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ def predict(self, X, return_std=False, return_cov=False):
435435
# Compute variance of predictive distribution
436436
# Use einsum to avoid explicitly forming the large matrix
437437
# V^T @ V just to extract its diagonal afterward.
438-
y_var = self.kernel_.diag(X)
438+
y_var = self.kernel_.diag(X).copy()
439439
y_var -= np.einsum("ij,ji->i", V.T, V)
440440

441441
# Check if any of the variances is negative because of

sklearn/gaussian_process/tests/test_gpr.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
import pytest
1515

1616
from sklearn.gaussian_process import GaussianProcessRegressor
17-
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C, WhiteKernel
17+
from sklearn.gaussian_process.kernels import (
18+
RBF,
19+
ConstantKernel as C,
20+
WhiteKernel,
21+
)
1822
from sklearn.gaussian_process.kernels import DotProduct, ExpSineSquared
1923
from sklearn.gaussian_process.tests._mini_sequence_kernel import MiniSeqKernel
2024
from sklearn.exceptions import ConvergenceWarning
@@ -767,3 +771,30 @@ def test_sample_y_shapes(normalize_y, n_targets):
767771

768772
y_samples = model.sample_y(X_test, n_samples=n_samples_y_test)
769773
assert y_samples.shape == y_test_shape
774+
775+
776+
class CustomKernel(C):
777+
"""
778+
A custom kernel that has a diag method that returns the first column of the
779+
input matrix X. This is a helper for the test to check that the input
780+
matrix X is not mutated.
781+
"""
782+
783+
def diag(self, X):
784+
return X[:, 0]
785+
786+
787+
def test_gpr_predict_input_not_modified():
788+
"""
789+
Check that the input X is not modified by the predict method of the
790+
GaussianProcessRegressor when setting return_std=True.
791+
792+
Non-regression test for:
793+
https://github.com/scikit-learn/scikit-learn/issues/24340
794+
"""
795+
gpr = GaussianProcessRegressor(kernel=CustomKernel()).fit(X, y)
796+
797+
X2_copy = np.copy(X2)
798+
_, _ = gpr.predict(X2, return_std=True)
799+
800+
assert_allclose(X2, X2_copy)

0 commit comments

Comments
 (0)