diff --git a/doc/templates/index.html b/doc/templates/index.html index b3f0736fa..7aff01909 100644 --- a/doc/templates/index.html +++ b/doc/templates/index.html @@ -109,6 +109,8 @@

News

  • On-going development: What's new (Changelog)
  • +
  • Sep 2020. scikit-optimize 0.8.1 (Changelog). +
  • Sep 2020. scikit-optimize 0.8 (Changelog).
  • Feb 2020. scikit-optimize 0.7.2 (Changelog).
  • Feb 2020. scikit-optimize 0.7.1 (Changelog).
  • Jan 2020. scikit-optimize 0.7 (Changelog). diff --git a/doc/whats_new.rst b/doc/whats_new.rst index b1e166f8e..15dd110f7 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -8,6 +8,7 @@ Release notes for all scikit-optimize releases are linked in this this page. .. toctree:: :maxdepth: 1 + Version 0.9 Version 0.8 Version 0.7 Version 0.6 diff --git a/doc/whats_new/v0.8.rst b/doc/whats_new/v0.8.rst index ea8bd641f..822ff1cbb 100644 --- a/doc/whats_new/v0.8.rst +++ b/doc/whats_new/v0.8.rst @@ -2,6 +2,15 @@ .. currentmodule:: skopt +.. _changes_0_8_1: + +Version 0.8.1 +============= +**September 2020** + +- |Fix| GaussianProcessRegressor on sklearn 0.23 normalizes the + variance to 1, which needs to reverted on predict. + .. _changes_0_8: Version 0.8.0 diff --git a/doc/whats_new/v0.9.rst b/doc/whats_new/v0.9.rst index e4c613f90..42bec8647 100644 --- a/doc/whats_new/v0.9.rst +++ b/doc/whats_new/v0.9.rst @@ -2,7 +2,7 @@ .. currentmodule:: skopt -.. _changes_0_8: +.. _changes_0_9: Version 0.9.0 ============= diff --git a/skopt/learning/gaussian_process/gpr.py b/skopt/learning/gaussian_process/gpr.py index 331d19ad7..6b13bb686 100644 --- a/skopt/learning/gaussian_process/gpr.py +++ b/skopt/learning/gaussian_process/gpr.py @@ -224,10 +224,15 @@ def fit(self, X, y): self.K_inv_ = L_inv.dot(L_inv.T) # Fix deprecation warning #462 - if int(sklearn.__version__[2:4]) >= 19: + if int(sklearn.__version__[2:4]) >= 23: + self.y_train_std_ = self._y_train_std self.y_train_mean_ = self._y_train_mean + elif int(sklearn.__version__[2:4]) >= 19: + self.y_train_mean_ = self._y_train_mean + self.y_train_std_ = 1 else: self.y_train_mean_ = self.y_train_mean + self.y_train_std_ = 1 return self @@ -309,11 +314,14 @@ def predict(self, X, return_std=False, return_cov=False, else: # Predict based on GP posterior K_trans = self.kernel_(X, self.X_train_) y_mean = K_trans.dot(self.alpha_) # Line 4 (y_mean = f_star) - y_mean = self.y_train_mean_ + y_mean # undo normal. + # undo normalisation + y_mean = self.y_train_std_ * y_mean + self.y_train_mean_ if return_cov: v = cho_solve((self.L_, True), K_trans.T) # Line 5 y_cov = self.kernel_(X) - K_trans.dot(v) # Line 6 + # undo normalisation + y_cov = y_cov * self.y_train_std_**2 return y_mean, y_cov elif return_std: @@ -330,17 +338,22 @@ def predict(self, X, return_std=False, return_cov=False, warnings.warn("Predicted variances smaller than 0. " "Setting those variances to 0.") y_var[y_var_negative] = 0.0 + # undo normalisation + y_var = y_var * self.y_train_std_**2 y_std = np.sqrt(y_var) if return_mean_grad: grad = self.kernel_.gradient_x(X[0], self.X_train_) grad_mean = np.dot(grad.T, self.alpha_) - + # undo normalisation + grad_mean = grad_mean * self.y_train_std_ if return_std_grad: grad_std = np.zeros(X.shape[1]) if not np.allclose(y_std, grad_std): grad_std = -np.dot(K_trans, np.dot(K_inv, grad))[0] / y_std + # undo normalisation + grad_std = grad_std * self.y_train_std_**2 return y_mean, y_std, grad_mean, grad_std if return_std: diff --git a/skopt/tests/test_acquisition.py b/skopt/tests/test_acquisition.py index 13117dcbe..a75d20550 100644 --- a/skopt/tests/test_acquisition.py +++ b/skopt/tests/test_acquisition.py @@ -119,6 +119,19 @@ def test_acquisition_gradient(): check_gradient_correctness(X_new, gpr, acq_func, np.max(y)) +@pytest.mark.fast_test +def test_acquisition_gradient_cookbook(): + rng = np.random.RandomState(0) + X = rng.randn(20, 5) + y = rng.randn(20) + X_new = rng.randn(5) + gpr = cook_estimator("GP", Space(((-5.0, 5.0),)), random_state=0) + gpr.fit(X, y) + + for acq_func in ["LCB", "PI", "EI"]: + check_gradient_correctness(X_new, gpr, acq_func, np.max(y)) + + @pytest.mark.fast_test @pytest.mark.parametrize("acq_func", ["EIps", "PIps"]) def test_acquisition_per_second(acq_func):