In [9]:
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import matplotlib.pyplot as plt
import matplotlib.cm as cmap
cm = cmap.inferno
import numpy as np
import scipy as sp
import theano
import theano.tensor as tt
import theano.tensor.nlinalg
import sys
sys.path.insert(0, "../../..")
import pymc3 as pm
In [2]:
np.random.seed(20090425)
n = 20
X = np.sort(3 * np.random.rand(n))[:, None]
with pm.Model() as model:
# f(x)
l_true = 0.3
s2_f_true = 1.0
cov = s2_f_true * pm.gp.cov.ExpQuad(1, l_true)
# noise, epsilon
s2_n_true = 0.1
K_noise = s2_n_true ** 2 * tt.eye(n)
K = cov(X) + K_noise
# evaluate the covariance with the given hyperparameters
K = theano.function([], cov(X) + K_noise)()
# generate fake data from GP with white noise (with variance sigma2)
y = np.random.multivariate_normal(np.zeros(n), K)
In [10]:
fig = plt.figure(figsize=(14,5)); ax = fig.add_subplot(111)
ax.plot(X, y, 'ok', ms=10);
ax.set_xlabel("x");
ax.set_ylabel("f(x)");
In [30]:
Z = np.linspace(0,3,100)[:, None]
from pymc3.gp.mean import Mean
class MyMean(Mean):
def __call__(self, X):
# return tt.squeeze(tt.dot(tt.transpose(X), X))
return X[0] * X[0]
with pm.Model() as model:
# priors on the covariance function hyperparameters
l = pm.Uniform('l', 0, 10)
# uninformative prior on the function variance
log_s2_f = pm.Uniform('log_s2_f', lower=-10, upper=5)
s2_f = pm.Deterministic('s2_f', tt.exp(log_s2_f))
# uninformative prior on the noise variance
log_s2_n = pm.Uniform('log_s2_n', lower=-10, upper=5)
s2_n = pm.Deterministic('s2_n', tt.exp(log_s2_n))
# covariance functions for the function f and the noise
f_cov = s2_f * pm.gp.cov.ExpQuad(1, l)
y_obs = pm.gp.GP('y_obs', mean_func=MyMean(), cov_func=f_cov, sigma=s2_n, observed={'X': X, 'Y': y})
In [31]:
with model:
trace = pm.sample(2000, burn=1000)
In [32]:
pm.traceplot(trace, varnames=['l', 's2_f', 's2_n'],
lines={"l": l_true,
"s2_f": s2_f_true,
"s2_n": s2_n_true});
In [37]:
sample_locs = np.linspace(-5, 8, 100)[:, None]
with model:
gp_samples = pm.gp.sample_gp(trace, y_obs, sample_locs, samples=50, random_seed=42)
In [38]:
fig, ax = plt.subplots(figsize=(14,5))
[ax.plot(sample_locs, x, color=cm(0.3), alpha=0.3) for x in gp_samples]
# overlay the observed data
ax.plot(X, y, 'ok', ms=10);
ax.set_xlabel("x");
ax.set_ylabel("f(x)");
ax.set_title("Posterior predictive distribution");