File tree Expand file tree Collapse file tree 3 files changed +38
-1
lines changed
Filter options
Expand file tree Collapse file tree 3 files changed +38
-1
lines changed
Original file line number Diff line number Diff line change @@ -32,6 +32,17 @@ Changelog
32
32
- |Fix | Fixed a bug in :class: `decomposition.KernelPCA `'s
33
33
``inverse_transform ``. :pr: `19732 ` by :user: `Kei Ishikawa <kstoneriv3> `.
34
34
35
+ :mod: `sklearn.gaussian_process `
36
+ ...............................
37
+
38
+ - |Fix | Avoid division by zero when scaling constant target in
39
+ :class: `gaussian_process.GaussianProcessRegressor `. It was due to a std. dev.
40
+ equal to 0. Now, such case is detected and the std. dev. is affected to 1
41
+ avoiding a division by zero and thus the presence of NaN values in the
42
+ normalized target.
43
+ :pr: `19703 ` by :user: `sobkevich `, :user: `Boris Villazón-Terrazas <boricles> `
44
+ and :user: `Alexandr Fonari <afonari> `.
45
+
35
46
:mod: `sklearn.linear_model `
36
47
...........................
37
48
Original file line number Diff line number Diff line change 14
14
from ..base import BaseEstimator , RegressorMixin , clone
15
15
from ..base import MultiOutputMixin
16
16
from .kernels import RBF , ConstantKernel as C
17
+ from ..preprocessing ._data import _handle_zeros_in_scale
17
18
from ..utils import check_random_state
18
19
from ..utils .optimize import _check_optimize_result
19
20
from ..utils .validation import _deprecate_positional_args
@@ -197,7 +198,9 @@ def fit(self, X, y):
197
198
# Normalize target value
198
199
if self .normalize_y :
199
200
self ._y_train_mean = np .mean (y , axis = 0 )
200
- self ._y_train_std = np .std (y , axis = 0 )
201
+ self ._y_train_std = _handle_zeros_in_scale (
202
+ np .std (y , axis = 0 ), copy = False
203
+ )
201
204
202
205
# Remove mean and make unit variance
203
206
y = (y - self ._y_train_mean ) / self ._y_train_std
Original file line number Diff line number Diff line change @@ -546,3 +546,26 @@ def test_bound_check_fixed_hyperparameter():
546
546
periodicity_bounds = "fixed" ) # seasonal component
547
547
kernel = k1 + k2
548
548
GaussianProcessRegressor (kernel = kernel ).fit (X , y )
549
+
550
+
551
+ # FIXME: we should test for multitargets as well. However, GPR is broken:
552
+ # see: https://github.com/scikit-learn/scikit-learn/pull/19706
553
+ @pytest .mark .parametrize ('kernel' , kernels )
554
+ def test_constant_target (kernel ):
555
+ """Check that the std. dev. is affected to 1 when normalizing a constant
556
+ feature.
557
+ Non-regression test for:
558
+ https://github.com/scikit-learn/scikit-learn/issues/18318
559
+ NaN where affected to the target when scaling due to null std. dev. with
560
+ constant target.
561
+ """
562
+ y_constant = np .ones (X .shape [0 ], dtype = np .float64 )
563
+
564
+ gpr = GaussianProcessRegressor (kernel = kernel , normalize_y = True )
565
+ gpr .fit (X , y_constant )
566
+ assert gpr ._y_train_std == pytest .approx (1.0 )
567
+
568
+ y_pred , y_cov = gpr .predict (X , return_cov = True )
569
+ assert_allclose (y_pred , y_constant )
570
+ # set atol because we compare to zero
571
+ assert_allclose (np .diag (y_cov ), 0. , atol = 1e-9 )
You can’t perform that action at this time.
0 commit comments