Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b165442

Browse filesBrowse files
ogriselglemaitre
andcommitted
DOC Improve the plot_gpy_noisy.py example (#29788)
Co-authored-by: Guillaume Lemaitre <guillaume@probabl.ai>
1 parent 7b7f1e6 commit b165442
Copy full SHA for b165442

File tree

Expand file treeCollapse file tree

1 file changed

+59
-23
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+59
-23
lines changed

‎examples/gaussian_process/plot_gpr_noisy.py

Copy file name to clipboardExpand all lines: examples/gaussian_process/plot_gpr_noisy.py
+59-23Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def target_generator(X, add_noise=False):
3434
# %%
3535
# Let's have a look to the target generator where we will not add any noise to
3636
# observe the signal that we would like to predict.
37-
X = np.linspace(0, 5, num=30).reshape(-1, 1)
37+
X = np.linspace(0, 5, num=80).reshape(-1, 1)
3838
y = target_generator(X, add_noise=False)
3939

4040
# %%
@@ -89,7 +89,7 @@ def target_generator(X, add_noise=False):
8989
from sklearn.gaussian_process.kernels import RBF, WhiteKernel
9090

9191
kernel = 1.0 * RBF(length_scale=1e1, length_scale_bounds=(1e-2, 1e3)) + WhiteKernel(
92-
noise_level=1, noise_level_bounds=(1e-5, 1e1)
92+
noise_level=1, noise_level_bounds=(1e-10, 1e1)
9393
)
9494
gpr = GaussianProcessRegressor(kernel=kernel, alpha=0.0)
9595
gpr.fit(X_train, y_train)
@@ -98,7 +98,7 @@ def target_generator(X, add_noise=False):
9898
# %%
9999
plt.plot(X, y, label="Expected signal")
100100
plt.scatter(x=X_train[:, 0], y=y_train, color="black", alpha=0.4, label="Observations")
101-
plt.errorbar(X, y_mean, y_std)
101+
plt.errorbar(X, y_mean, y_std, label="Posterior mean ± std")
102102
plt.legend()
103103
plt.xlabel("X")
104104
plt.ylabel("y")
@@ -110,15 +110,18 @@ def target_generator(X, add_noise=False):
110110
fontsize=8,
111111
)
112112
# %%
113-
# We see that the optimum kernel found still have a high noise level and
114-
# an even larger length scale. Furthermore, we observe that the
115-
# model does not provide faithful predictions.
113+
# We see that the optimum kernel found still has a high noise level and an even
114+
# larger length scale. The length scale reaches the maximum bound that we
115+
# allowed for this parameter and we got a warning as a result.
116116
#
117-
# Now, we will initialize the
118-
# :class:`~sklearn.gaussian_process.kernels.RBF` with a
119-
# larger `length_scale` and the
120-
# :class:`~sklearn.gaussian_process.kernels.WhiteKernel`
121-
# with a smaller noise level lower bound.
117+
# More importantly, we observe that the model does not provide useful
118+
# predictions: the mean prediction seems to be constant: it does not follow the
119+
# expected noise-free signal.
120+
#
121+
# Now, we will initialize the :class:`~sklearn.gaussian_process.kernels.RBF`
122+
# with a larger `length_scale` initial value and the
123+
# :class:`~sklearn.gaussian_process.kernels.WhiteKernel` with a smaller initial
124+
# noise level lower while keeping the parameter bounds unchanged.
122125
kernel = 1.0 * RBF(length_scale=1e-1, length_scale_bounds=(1e-2, 1e3)) + WhiteKernel(
123126
noise_level=1e-2, noise_level_bounds=(1e-10, 1e1)
124127
)
@@ -129,7 +132,7 @@ def target_generator(X, add_noise=False):
129132
# %%
130133
plt.plot(X, y, label="Expected signal")
131134
plt.scatter(x=X_train[:, 0], y=y_train, color="black", alpha=0.4, label="Observations")
132-
plt.errorbar(X, y_mean, y_std)
135+
plt.errorbar(X, y_mean, y_std, label="Posterior mean ± std")
133136
plt.legend()
134137
plt.xlabel("X")
135138
plt.ylabel("y")
@@ -154,21 +157,19 @@ def target_generator(X, add_noise=False):
154157
# for different hyperparameters to get a sense of the local minima.
155158
from matplotlib.colors import LogNorm
156159

157-
length_scale = np.logspace(-2, 4, num=50)
158-
noise_level = np.logspace(-2, 1, num=50)
160+
length_scale = np.logspace(-2, 4, num=80)
161+
noise_level = np.logspace(-2, 1, num=80)
159162
length_scale_grid, noise_level_grid = np.meshgrid(length_scale, noise_level)
160163

161164
log_marginal_likelihood = [
162165
gpr.log_marginal_likelihood(theta=np.log([0.36, scale, noise]))
163166
for scale, noise in zip(length_scale_grid.ravel(), noise_level_grid.ravel())
164167
]
165-
log_marginal_likelihood = np.reshape(
166-
log_marginal_likelihood, newshape=noise_level_grid.shape
167-
)
168+
log_marginal_likelihood = np.reshape(log_marginal_likelihood, noise_level_grid.shape)
168169

169170
# %%
170171
vmin, vmax = (-log_marginal_likelihood).min(), 50
171-
level = np.around(np.logspace(np.log10(vmin), np.log10(vmax), num=50), decimals=1)
172+
level = np.around(np.logspace(np.log10(vmin), np.log10(vmax), num=20), decimals=1)
172173
plt.contour(
173174
length_scale_grid,
174175
noise_level_grid,
@@ -185,8 +186,43 @@ def target_generator(X, add_noise=False):
185186
plt.show()
186187

187188
# %%
188-
# We see that there are two local minima that correspond to the combination
189-
# of hyperparameters previously found. Depending on the initial values for the
190-
# hyperparameters, the gradient-based optimization might converge whether or
191-
# not to the best model. It is thus important to repeat the optimization
192-
# several times for different initializations.
189+
#
190+
# We see that there are two local minima that correspond to the combination of
191+
# hyperparameters previously found. Depending on the initial values for the
192+
# hyperparameters, the gradient-based optimization might or might not
193+
# converge to the best model. It is thus important to repeat the optimization
194+
# several times for different initializations. This can be done by setting the
195+
# `n_restarts_optimizer` parameter of the
196+
# :class:`~sklearn.gaussian_process.GaussianProcessRegressor` class.
197+
#
198+
# Let's try again to fit our model with the bad initial values but this time
199+
# with 10 random restarts.
200+
201+
kernel = 1.0 * RBF(length_scale=1e1, length_scale_bounds=(1e-2, 1e3)) + WhiteKernel(
202+
noise_level=1, noise_level_bounds=(1e-10, 1e1)
203+
)
204+
gpr = GaussianProcessRegressor(
205+
kernel=kernel, alpha=0.0, n_restarts_optimizer=10, random_state=0
206+
)
207+
gpr.fit(X_train, y_train)
208+
y_mean, y_std = gpr.predict(X, return_std=True)
209+
210+
# %%
211+
plt.plot(X, y, label="Expected signal")
212+
plt.scatter(x=X_train[:, 0], y=y_train, color="black", alpha=0.4, label="Observations")
213+
plt.errorbar(X, y_mean, y_std, label="Posterior mean ± std")
214+
plt.legend()
215+
plt.xlabel("X")
216+
plt.ylabel("y")
217+
_ = plt.title(
218+
(
219+
f"Initial: {kernel}\nOptimum: {gpr.kernel_}\nLog-Marginal-Likelihood: "
220+
f"{gpr.log_marginal_likelihood(gpr.kernel_.theta)}"
221+
),
222+
fontsize=8,
223+
)
224+
225+
# %%
226+
#
227+
# As we hoped, random restarts allow the optimization to find the best set
228+
# of hyperparameters despite the bad initial values.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.