Skip to content

Commit 3615e7e

Browse files
fonnesbeckChris Fonnesbeck
and
Chris Fonnesbeck
committed
Update T Process notebook (pymc-devs#705)
* Draft update of BNN notebook * Pre-commit fixes * Address reviewer comments * Updated to v5 * Updated authorship --------- Co-authored-by: Chris Fonnesbeck <[email protected]>
1 parent dfd3e77 commit 3615e7e

File tree

2 files changed

+362
-127
lines changed

2 files changed

+362
-127
lines changed

Diff for: examples/gaussian_processes/GP-TProcess.ipynb

+304-92
Large diffs are not rendered by default.

Diff for: examples/gaussian_processes/GP-TProcess.myst.md

+58-35
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,16 @@ kernelspec:
1010
name: python3
1111
---
1212

13+
(GP-TProcess)=
1314
# Student-t Process
1415

15-
PyMC3 also includes T-process priors. They are a generalization of a Gaussian process prior to the multivariate Student's T distribution. The usage is identical to that of `gp.Latent`, except they require a degrees of freedom parameter when they are specified in the model. For more information, see chapter 9 of [Rasmussen+Williams](http://www.gaussianprocess.org/gpml/), and [Shah et al.](https://arxiv.org/abs/1402.4306).
16+
:::{post} August 2017
17+
:tags: t-process, gaussian process, bayesian non-parametrics
18+
:category: intermediate
19+
:author: Bill Engels
20+
:::
21+
22+
PyMC also includes T-process priors. They are a generalization of a Gaussian process prior to the multivariate Student's T distribution. The usage is identical to that of `gp.Latent`, except they require a degrees of freedom parameter when they are specified in the model. For more information, see chapter 9 of [Rasmussen+Williams](http://www.gaussianprocess.org/gpml/), and [Shah et al.](https://arxiv.org/abs/1402.4306).
1623

1724
Note that T processes aren't additive in the same way as GPs, so addition of `TP` objects are not supported.
1825

@@ -23,10 +30,13 @@ Note that T processes aren't additive in the same way as GPs, so addition of `TP
2330
The following code draws samples from a T process prior with 3 degrees of freedom and a Gaussian process, both with the same covariance matrix.
2431

2532
```{code-cell} ipython3
33+
import arviz as az
2634
import matplotlib.pyplot as plt
2735
import numpy as np
28-
import pymc3 as pm
29-
import theano.tensor as tt
36+
import pymc as pm
37+
import pytensor.tensor as pt
38+
39+
from pymc.gp.util import plot_gp_dist
3040
3141
%matplotlib inline
3242
```
@@ -39,33 +49,34 @@ n = 100 # The number of data points
3949
X = np.linspace(0, 10, n)[:, None] # The inputs to the GP, they must be arranged as a column vector
4050
4151
# Define the true covariance function and its parameters
42-
ℓ_true = 1.0
43-
η_true = 3.0
44-
cov_func = η_true**2 * pm.gp.cov.Matern52(1, ℓ_true)
52+
ell_true = 1.0
53+
eta_true = 3.0
54+
cov_func = eta_true**2 * pm.gp.cov.Matern52(1, ell_true)
4555
4656
# A mean function that is zero everywhere
4757
mean_func = pm.gp.mean.Zero()
4858
4959
# The latent function values are one sample from a multivariate normal
5060
# Note that we have to call `eval()` because PyMC3 built on top of Theano
51-
tp_samples = pm.MvStudentT.dist(mu=mean_func(X).eval(), cov=cov_func(X).eval(), nu=3).random(size=8)
61+
tp_samples = pm.draw(pm.MvStudentT.dist(mu=mean_func(X).eval(), scale=cov_func(X).eval(), nu=3), 8)
5262
5363
## Plot samples from TP prior
5464
fig = plt.figure(figsize=(12, 5))
55-
ax = fig.gca()
56-
ax.plot(X.flatten(), tp_samples.T, lw=3, alpha=0.6)
57-
ax.set_xlabel("X")
58-
ax.set_ylabel("y")
59-
ax.set_title("Samples from TP with DoF=3")
65+
ax0 = fig.gca()
66+
ax0.plot(X.flatten(), tp_samples.T, lw=3, alpha=0.6)
67+
ax0.set_xlabel("X")
68+
ax0.set_ylabel("y")
69+
ax0.set_title("Samples from TP with DoF=3")
6070
6171
62-
gp_samples = pm.MvNormal.dist(mu=mean_func(X).eval(), cov=cov_func(X).eval()).random(size=8)
72+
gp_samples = pm.draw(pm.MvNormal.dist(mu=mean_func(X).eval(), cov=cov_func(X).eval()), 8)
6373
fig = plt.figure(figsize=(12, 5))
64-
ax = fig.gca()
65-
ax.plot(X.flatten(), gp_samples.T, lw=3, alpha=0.6)
66-
ax.set_xlabel("X")
67-
ax.set_ylabel("y")
68-
ax.set_title("Samples from GP");
74+
ax1 = fig.gca()
75+
ax1.plot(X.flatten(), gp_samples.T, lw=3, alpha=0.6)
76+
ax1.set_xlabel("X")
77+
ax1.set_ylabel("y")
78+
ax1.set_ylim(ax0.get_ylim())
79+
ax1.set_title("Samples from GP");
6980
```
7081

7182
## Poisson data generated by a T process
@@ -79,16 +90,16 @@ n = 150 # The number of data points
7990
X = np.linspace(0, 10, n)[:, None] # The inputs to the GP, they must be arranged as a column vector
8091
8192
# Define the true covariance function and its parameters
82-
ℓ_true = 1.0
83-
η_true = 3.0
84-
cov_func = η_true**2 * pm.gp.cov.ExpQuad(1, ℓ_true)
93+
ell_true = 1.0
94+
eta_true = 3.0
95+
cov_func = eta_true**2 * pm.gp.cov.ExpQuad(1, ell_true)
8596
8697
# A mean function that is zero everywhere
8798
mean_func = pm.gp.mean.Zero()
8899
89100
# The latent function values are one sample from a multivariate normal
90101
# Note that we have to call `eval()` because PyMC3 built on top of Theano
91-
f_true = pm.MvStudentT.dist(mu=mean_func(X).eval(), cov=cov_func(X).eval(), nu=3).random(size=1)
102+
f_true = pm.draw(pm.MvStudentT.dist(mu=mean_func(X).eval(), scale=cov_func(X).eval(), nu=3), 1)
92103
y = np.random.poisson(f_true**2)
93104
94105
fig = plt.figure(figsize=(12, 5))
@@ -102,23 +113,22 @@ plt.legend();
102113

103114
```{code-cell} ipython3
104115
with pm.Model() as model:
105-
= pm.Gamma("", alpha=2, beta=2)
106-
η = pm.HalfCauchy("η", beta=3)
107-
cov = η**2 * pm.gp.cov.ExpQuad(1, )
116+
ell = pm.Gamma("ell", alpha=2, beta=2)
117+
eta = pm.HalfCauchy("eta", beta=3)
118+
cov = eta**2 * pm.gp.cov.ExpQuad(1, ell)
108119
109120
# informative prior on degrees of freedom < 5
110-
ν = pm.Gamma("ν", alpha=2, beta=1)
111-
tp = pm.gp.TP(cov_func=cov, nu=ν)
121+
nu = pm.Gamma("nu", alpha=2, beta=1)
122+
tp = pm.gp.TP(scale_func=cov, nu=nu)
112123
f = tp.prior("f", X=X)
113124
114-
# adding a small constant seems to help with numerical stability here
115-
y_ = pm.Poisson("y", mu=tt.square(f) + 1e-6, observed=y)
125+
pm.Poisson("y", mu=pt.square(f), observed=y)
116126
117-
tr = pm.sample(1000)
127+
tr = pm.sample(target_accept=0.9, nuts_sampler="nutpie", chains=2)
118128
```
119129

120130
```{code-cell} ipython3
121-
pm.traceplot(tr, var_names=["", "ν", "η"]);
131+
az.plot_trace(tr, var_names=["ell", "nu", "eta"]);
122132
```
123133

124134
```{code-cell} ipython3
@@ -131,24 +141,37 @@ with model:
131141
132142
# Sample from the GP conditional distribution
133143
with model:
134-
pred_samples = pm.sample_posterior_predictive(tr, vars=[f_pred], samples=1000)
144+
pm.sample_posterior_predictive(tr, var_names=["f_pred"], extend_inferencedata=True)
135145
```
136146

137147
```{code-cell} ipython3
138148
fig = plt.figure(figsize=(12, 5))
139149
ax = fig.gca()
140-
from pymc3.gp.util import plot_gp_dist
141150
142-
plot_gp_dist(ax, np.square(pred_samples["f_pred"]), X_new)
151+
f_pred_samples = np.square(
152+
az.extract(tr.posterior_predictive).astype(np.float32)["f_pred"].values
153+
).T
154+
plot_gp_dist(ax, f_pred_samples, X_new)
143155
plt.plot(X, np.square(f_true), "dodgerblue", lw=3, label="True f")
144156
plt.plot(X, y, "ok", ms=3, alpha=0.5, label="Observed data")
145157
plt.xlabel("X")
146158
plt.ylabel("True f(x)")
147-
plt.ylim([-2, 20])
148159
plt.title("Conditional distribution of f_*, given f")
149160
plt.legend();
150161
```
151162

163+
## Authors
164+
165+
* Authored by Bill Engels
166+
* Updated by Chris Fonnesbeck to use PyMC v5
167+
168+
+++
169+
170+
## References
171+
:::{bibliography}
172+
:filter: docname in docnames
173+
:::
174+
152175
```{code-cell} ipython3
153176
%load_ext watermark
154177
%watermark -n -u -v -iv -w

0 commit comments

Comments
 (0)