File: plot_gaussian_processes_comparison.py

package info (click to toggle)
openturns 1.26-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 67,708 kB
  • sloc: cpp: 261,605; python: 67,030; ansic: 4,378; javascript: 406; sh: 185; xml: 164; makefile: 101
file content (209 lines) | stat: -rw-r--r-- 6,660 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
"""
Compare covariance models
=========================
"""

# %%
# The main goal of this example is to briefly review the most important covariance models and compare them in terms of regularity of the trajectories.
#
# We first show how to define a covariance model, a temporal grid and a Gaussian process.
# We first consider the squared exponential covariance model and show how the trajectories are sensitive to its parameters.
# We show how to define a trend. In the final section, we compare the trajectories from exponential and Matérn covariance models.

# %%
# References
# ----------
#
# * Carl Edward Rasmussen and Christopher K. I. Williams (2006) Gaussian Processes for Machine Learning. Chapter 4: "Covariance Functions", www.GaussianProcess.org/gpml

# %%
# The anisotropic squared exponential model
# -----------------------------------------
#
# The :class:`~openturns.SquaredExponential` class allows one to define covariance models:
#
# * :math:`\sigma\in\mathbb{R}` is the amplitude parameter,
# * :math:`\boldsymbol{\theta}\in\mathbb{R}^d` is the scale.

# %%
import openturns.viewer as otv
import openturns as ot
import matplotlib.pyplot as plt

# %%
# Amplitude values
amplitude = [3.5]
# Scale values
scale = [1.5]
# Covariance model
myModel = ot.SquaredExponential(scale, amplitude)

# %%
# Gaussian processes
# ------------------
#
# In order to create a :class:`~openturns.GaussianProcess`, we must have:
#
# * a covariance model,
# * a grid.
#
# Optionnally, we can define a trend (we will see that later in the example). By default, the trend is zero.
#
# We consider the domain :math:`\mathcal{D}=[0,10]`. We discretize this domain with 100 cells (which corresponds to 101 nodes), with steps equal to 0.1 starting from 0:
#
# .. math::
#    (x_0=x_{min}=0,\:x_1=0.1,\:\ldots,\:x_n=x_{max}=10).
#

# %%
xmin = 0.0
step = 0.1
n = 100
myTimeGrid = ot.RegularGrid(xmin, step, n + 1)
graph = myTimeGrid.draw()
graph.setTitle("Regular grid")
view = otv.View(graph)

# %%
# Then we create the Gaussian process (by default the trend is zero).

# %%
process = ot.GaussianProcess(myModel, myTimeGrid)

# %%
# Then we generate 10 trajectores with the `getSample` method. This trajectories are in a :class:`~openturns.ProcessSample`.

# %%
nbTrajectories = 10
sample = process.getSample(nbTrajectories)
type(sample)

# %%
# We can draw the trajectories with `drawMarginal`.

# %%
graph = sample.drawMarginal(0)
graph.setTitle("amplitude=%.3f, scale=%.3f" % (amplitude[0], scale[0]))
view = otv.View(graph)


# %%
# In order to make the next examples easier, we define a function which plots a given number of trajectories from a Gaussian process based on a covariance model.


# %%
def plotCovarianceModel(myCovarianceModel, myTimeGrid, nbTrajectories):
    """Plots the given number of trajectories with given covariance model."""
    process = ot.GaussianProcess(myCovarianceModel, myTimeGrid)
    sample = process.getSample(nbTrajectories)
    graph = sample.drawMarginal(0)
    graph.setTitle("")
    return graph


# %%
# The amplitude parameter sets the variance of the process. A greater amplitude increases the chances of getting larger absolute values of the process.

# %%
amplitude = [7.0]
scale = [1.5]
myModel = ot.SquaredExponential(scale, amplitude)
graph = plotCovarianceModel(myModel, myTimeGrid, 10)
graph.setTitle("amplitude=%.3f, scale=%.3f" % (amplitude[0], scale[0]))
view = otv.View(graph)

# %%
# Modifying the scale parameter is here equivalent to stretch or contract the "time" :math:`x`.

# %%
amplitude = [3.5]
scale = [0.5]
myModel = ot.SquaredExponential(scale, amplitude)
graph = plotCovarianceModel(myModel, myTimeGrid, 10)
graph.setTitle("amplitude=%.3f, scale=%.3f" % (amplitude[0], scale[0]))
view = otv.View(graph)

# %%
# Define the trend
# ----------------
#
# The trend is a deterministic function. With the :class:`~openturns.GaussianProcess` class, the associated process is the sum of a trend and a Gaussian process with zero mean.

# %%
f = ot.SymbolicFunction(["x"], ["2*x"])
fTrend = ot.TrendTransform(f, myTimeGrid)

# %%
amplitude = [3.5]
scale = [1.5]
myModel = ot.SquaredExponential(scale, amplitude)
process = ot.GaussianProcess(fTrend, myModel, myTimeGrid)

# %%
# sphinx_gallery_thumbnail_number = 5
nbTrajectories = 10
sample = process.getSample(nbTrajectories)
graph = sample.drawMarginal(0)
graph.setTitle("amplitude=%.3f, scale=%.3f" % (amplitude[0], scale[0]))
view = otv.View(graph)

# %%
# Other covariance models
# -----------------------
#
# There are other covariance models. The models which are used more often are the following:
#
# * :class:`~openturns.SquaredExponential`. The generated processes can be derivated in mean square at all orders.
# * :class:`~openturns.MaternModel`. When :math:`\nu\rightarrow+\infty`, it converges to the squared exponential model.
#   This model can be derivated :math:`k` times only if :math:`k<\nu`.
#   In other words, when :math:`\nu` increases, then the trajectories are more and more regular.
#   The particular case :math:`\nu=1/2` is the exponential model.
#   The most commonly used values are :math:`\nu=3/2` and :math:`\nu=5/2`, which produce trajectories that are, in terms of regularity,
#   in between the squared exponential and the exponential models.
# * :class:`~openturns.ExponentialModel`. The associated process is continuous, but not differentiable.
#

# %%
# The Matérn and exponential models
# ---------------------------------

# %%
amplitude = [1.0]
scale = [1.0]
nu1, nu2, nu3 = 2.5, 1.5, 0.5
myModel1 = ot.MaternModel(scale, amplitude, nu1)
myModel2 = ot.MaternModel(scale, amplitude, nu2)
myModel3 = ot.MaternModel(scale, amplitude, nu3)

# %%
nbTrajectories = 10
graph1 = plotCovarianceModel(myModel1, myTimeGrid, nbTrajectories)
graph2 = plotCovarianceModel(myModel2, myTimeGrid, nbTrajectories)
graph3 = plotCovarianceModel(myModel3, myTimeGrid, nbTrajectories)

# %%
fig = plt.figure(figsize=(20, 6))
ax1 = fig.add_subplot(1, 3, 1)
_ = otv.View(graph1, figure=fig, axes=[ax1])
_ = ax1.set_title("Matern 5/2")
ax2 = fig.add_subplot(1, 3, 2)
_ = otv.View(graph2, figure=fig, axes=[ax2])
_ = ax2.set_title("Matern 3/2")
ax3 = fig.add_subplot(1, 3, 3)
_ = otv.View(graph3, figure=fig, axes=[ax3])
_ = ax3.set_title("Matern 1/2")

# %%
# We see than, when :math:`\nu` increases, then the trajectories are smoother and smoother.

# %%
myExpModel = ot.ExponentialModel(scale, amplitude)

# %%
graph = plotCovarianceModel(myExpModel, myTimeGrid, nbTrajectories)
graph.setTitle("Exponential")
view = otv.View(graph)

# %%
# We see that the exponential model produces very irregular trajectories.
otv.View.ShowAll()