示例#1
0
def test_obs(x):
    prior = Measure()
    f = GP(EQ(), measure=prior)
    noise = 0.1

    # Generate some data.
    w = B.rand(B.shape(x)[0]) + 1e-2
    y = f(x, 0.1).sample()

    # Set some observations to be missing.
    y_missing = y.copy()
    y_missing[::2] = np.nan

    # Check dense case.
    gpar = GPAR()
    obs = gpar._obs(x, None, y_missing, w, f, noise)
    assert isinstance(obs, Obs)
    approx(
        prior.logpdf(obs),
        f(x[1::2], noise / w[1::2]).logpdf(y[1::2]),
        atol=1e-6,
    )

    # Check sparse case.
    gpar = GPAR(x_ind=x)
    obs = gpar._obs(x, x, y_missing, w, f, noise)
    assert isinstance(obs, SparseObs)
    approx(
        prior.logpdf(obs),
        f(x[1::2], noise / w[1::2]).logpdf(y[1::2]),
        atol=1e-6,
    )
def test_combine():
    x1 = B.linspace(0, 2, 10)
    x2 = B.linspace(2, 4, 10)

    m = Measure()
    p1 = GP(EQ(), measure=m)
    p2 = GP(Matern12(), measure=m)
    y1 = p1(x1).sample()
    y2 = p2(x2).sample()

    # Check the one-argument case.
    assert_equal_normals(combine(p1(x1, 1)), p1(x1, 1))
    fdd_combined, y_combined = combine((p1(x1, 1), B.squeeze(y1)))
    assert_equal_normals(fdd_combined, p1(x1, 1))
    approx(y_combined, y1)

    # Check the two-argument case.
    fdd_combined = combine(p1(x1, 1), p2(x2, 2))
    assert_equal_normals(
        fdd_combined,
        Normal(B.block_diag(p1(x1, 1).var,
                            p2(x2, 2).var)),
    )
    fdd_combined, y_combined = combine((p1(x1, 1), B.squeeze(y1)),
                                       (p2(x2, 2), y2))
    assert_equal_normals(
        fdd_combined,
        Normal(B.block_diag(p1(x1, 1).var,
                            p2(x2, 2).var)),
    )
    approx(y_combined, B.concat(y1, y2, axis=0))
示例#3
0
def test_logpdf(x, w):
    prior = Measure()
    f1, noise1 = GP(EQ(), measure=prior), 2e-1
    f2, noise2 = GP(Linear(), measure=prior), 1e-1
    gpar = GPAR().add_layer(lambda: (f1, noise1)).add_layer(lambda: (f2, noise2))

    # Generate some data.
    y = gpar.sample(x, w, latent=True)

    # Compute logpdf.
    x1 = x
    x2 = B.concat(x, y[:, 0:1], axis=1)
    logpdf1 = f1(x1, noise1 / w[:, 0]).logpdf(y[:, 0])
    logpdf2 = f2(x2, noise2 / w[:, 1]).logpdf(y[:, 1])

    # Test computation of GPAR.
    assert gpar.logpdf(x, y, w) == logpdf1 + logpdf2
    assert gpar.logpdf(x, y, w, only_last_layer=True) == logpdf2

    # Test resuming computation.
    x_partial, x_ind_partial = gpar.logpdf(x, y, w, return_inputs=True, outputs=[0])
    assert gpar.logpdf(x_partial, y, w, x_ind=x_ind_partial, outputs=[1]) == logpdf2

    # Test that sampling missing gives a stochastic estimate.
    y[1, 0] = np.nan
    all_different(
        gpar.logpdf(x, y, w, sample_missing=True),
        gpar.logpdf(x, y, w, sample_missing=True),
    )
示例#4
0
def test_dimensionality():
    m = Measure()
    p1 = GP(EQ(), measure=m)
    p2 = GP(2 * EQ().stretch(2), measure=m)

    k1 = MultiOutputKernel(m, p1, p2)
    k2 = MultiOutputKernel(m, p1, p1)

    assert dimensionality(EQ()) == 1
    assert dimensionality(k1) == 2

    # Test the unpacking of `Wrapped`s and `Join`s.
    assert dimensionality(k1 + k2) == 2
    assert dimensionality(k1 * k2) == 2
    assert dimensionality(k1.periodic(1)) == 2
    assert dimensionality(k1.stretch(2)) == 2

    # Check that dimensionalities must line up.
    with pytest.raises(RuntimeError):
        dimensionality(k1 + EQ())

    # Check `PosteriorKernel`.
    assert dimensionality(PosteriorKernel(EQ(), EQ(), EQ(), None, 0)) == 1
    assert dimensionality(PosteriorKernel(k1, k2, k2, None, 0)) == 2
    assert dimensionality(PosteriorKernel(k1, k2, ADK(EQ()), None, 0)) == 2
    with pytest.raises(RuntimeError):
        assert dimensionality(PosteriorKernel(k1, k2, EQ(), None, 0)) == 2

    # Check `SubspaceKernel`.
    assert dimensionality(SubspaceKernel(EQ(), EQ(), None, 0)) == 1
    assert dimensionality(SubspaceKernel(k1, k2, None, 0)) == 2
    assert dimensionality(SubspaceKernel(k1, ADK(EQ()), None, 0)) == 2
    with pytest.raises(RuntimeError):
        assert dimensionality(SubspaceKernel(k1, EQ(), None, 0)) == 2
示例#5
0
def test_conditioning(x, w):
    prior = Measure()
    f1, e1 = GP(EQ(), measure=prior), GP(1e-10 * Delta(), measure=prior)
    f2, e2 = GP(EQ(), measure=prior), GP(2e-10 * Delta(), measure=prior)
    gpar = GPAR().add_layer(lambda: (f1, e1)).add_layer(lambda: (f2, e2))

    # Generate some data.
    y = B.concat((f1 + e1)(x).sample(), (f2 + e2)(x).sample(), axis=1)

    # Extract posterior processes.
    gpar = gpar | (x, y, w)
    f1_post, e1_post = gpar.layers[0]()
    f2_post, e2_post = gpar.layers[1]()

    # Test independence of noises.
    assert f1_post.measure.kernels[f1_post, e1_post] == ZeroKernel()
    assert f2_post.measure.kernels[f2_post, e2_post] == ZeroKernel()

    # Test form of noises.
    assert e1.mean == e1_post.mean
    assert e1.kernel == e1_post.kernel
    assert e2.mean == e2_post.mean
    assert e2.kernel == e2_post.kernel

    # Test posteriors.
    approx(f1_post.mean(x), y[:, 0:1], atol=1e-3)
    approx(f2_post.mean(B.concat(x, y[:, 0:1], axis=1)), y[:, 1:2], atol=1e-3)
示例#6
0
def test_logpdf(x, w):
    prior = Measure()
    f1, e1 = GP(EQ(), measure=prior), GP(2e-1 * Delta(), measure=prior)
    f2, e2 = GP(Linear(), measure=prior), GP(1e-1 * Delta(), measure=prior)
    gpar = GPAR().add_layer(lambda: (f1, e1)).add_layer(lambda: (f2, e2))

    # Generate some data.
    y = gpar.sample(x, w, latent=True)

    # Compute logpdf.
    x1 = WeightedUnique(x, w[:, 0])
    x2 = WeightedUnique(B.concat(x, y[:, 0:1], axis=1), w[:, 1])
    logpdf1 = (f1 + e1)(x1).logpdf(y[:, 0])
    logpdf2 = (f2 + e2)(x2).logpdf(y[:, 1])

    # Test computation of GPAR.
    assert gpar.logpdf(x, y, w) == logpdf1 + logpdf2
    assert gpar.logpdf(x, y, w, only_last_layer=True) == logpdf2

    # Test resuming computation.
    x_partial, x_ind_partial = gpar.logpdf(x,
                                           y,
                                           w,
                                           return_inputs=True,
                                           outputs=[0])
    assert gpar.logpdf(x_partial, y, w, x_ind=x_ind_partial,
                       outputs=[1]) == logpdf2

    # Test that sampling missing gives a stochastic estimate.
    y[1, 0] = np.nan
    all_different(
        gpar.logpdf(x, y, w, sample_missing=True),
        gpar.logpdf(x, y, w, sample_missing=True),
    )
示例#7
0
def test_sample(x, w):
    prior = Measure()

    # Test that it produces random samples.
    f1, noise1 = GP(EQ(), measure=prior), 1e-1
    f2, noise2 = GP(EQ(), measure=prior), 2e-1
    gpar = GPAR().add_layer(lambda: (f1, noise1)).add_layer(lambda: (f2, noise2))
    all_different(gpar.sample(x, w), gpar.sample(x, w))
    all_different(gpar.sample(x, w, latent=True), gpar.sample(x, w, latent=True))

    # Test that posterior latent samples are around the data that is conditioned on.
    prior = Measure()
    f1, noise1 = GP(EQ(), measure=prior), 1e-10
    f2, noise2 = GP(EQ(), measure=prior), 2e-10
    gpar = GPAR().add_layer(lambda: (f1, noise1)).add_layer(lambda: (f2, noise2))
    y = gpar.sample(x, w, latent=True)
    gpar = gpar | (x, y, w)
    approx(gpar.sample(x, w), y, atol=1e-3)
    approx(gpar.sample(x, w, latent=True), y, atol=1e-3)
示例#8
0
def test_infer_size():
    x = B.linspace(0, 2, 5)

    m = Measure()
    p1 = GP(EQ(), measure=m)
    p2 = GP(2 * EQ().stretch(2), measure=m)
    k = MultiOutputKernel(m, p1, p2)

    assert infer_size(k, x) == 10
    assert infer_size(k, p1(x)) == 5
    assert infer_size(k, (x, p1(x))) == 15
示例#9
0
    def __init__(
        self,
        kernels: List[Kernel],
        h: AbstractMatrix,
        noise_obs: B.Numeric,
        noises_latent: B.Numeric,
    ):
        measure = Measure()

        # Create latent processes.
        xs = [GP(k, measure=measure) for k in kernels]
        ILMMPP.__init__(self, measure, xs, h, noise_obs, noises_latent)
示例#10
0
def test_infer_size():
    x = B.linspace(0, 2, 5)

    m = Measure()
    p1 = GP(EQ(), measure=m)
    p2 = GP(2 * EQ().stretch(2), measure=m)
    k = MultiOutputKernel(m, p1, p2)

    assert infer_size(k, x) == 10
    assert infer_size(k, p1(x)) == 5
    assert infer_size(k, (x, p1(x))) == 15

    # Check that the dimensionality must be inferrable.
    assert infer_size(EQ(), x) == 5
    with pytest.raises(RuntimeError):
        infer_size(ADK(EQ()), x)
示例#11
0
def test_dimensionality():
    m = Measure()
    p1 = GP(EQ(), measure=m)
    p2 = GP(2 * EQ().stretch(2), measure=m)

    k1 = MultiOutputKernel(m, p1, p2)
    k2 = MultiOutputKernel(m, p1, p1)

    assert dimensionality(EQ()) == 1
    assert dimensionality(k1) == 2

    # Test the unpacking of `Wrapped`s and `Join`s.
    assert dimensionality(k1 + k2) == 2
    assert dimensionality(k1 * k2) == 2
    assert dimensionality(k1.periodic(1)) == 2
    assert dimensionality(k1.stretch(2)) == 2

    # Test consistency check.
    with pytest.raises(RuntimeError):
        dimensionality(k1 + EQ())
示例#12
0
def test_conditioning(x, w):
    prior = Measure()
    f1, noise1 = GP(EQ(), measure=prior), 1e-10
    f2, noise2 = GP(EQ(), measure=prior), 2e-10
    gpar = GPAR().add_layer(lambda: (f1, noise1)).add_layer(lambda: (f2, noise2))

    # Generate some data.
    y = B.concat(f1(x, noise1).sample(), f2(x, noise2).sample(), axis=1)

    # Extract posterior processes.
    gpar = gpar | (x, y, w)
    f1_post, noise1_post = gpar.layers[0]()
    f2_post, noise2_post = gpar.layers[1]()

    # Test noises.
    assert noise1 == noise1_post
    assert noise2 == noise2_post

    # Test posteriors.
    approx(f1_post.mean(x), y[:, 0:1], atol=1e-3)
    approx(f2_post.mean(B.concat(x, y[:, 0:1], axis=1)), y[:, 1:2], atol=1e-3)
示例#13
0
def test_fdd_take():
    with Measure():
        f1 = GP(1, EQ())
        f2 = GP(2, Exp())
        f = cross(f1, f2)

    x = B.linspace(0, 3, 5)
    # Build an FDD with a very complicated input specification.
    fdd = f((x, (f2(x), x), f1(x), (f2(x), (f1(x), x))))
    n = infer_size(fdd.p.kernel, fdd.x)
    fdd = f(fdd.x, matrix.Diagonal(B.rand(n)))

    # Flip a coin for every element.
    mask = B.randn(n) > 0
    taken_fdd = B.take(fdd, mask)

    approx(taken_fdd.mean, B.take(fdd.mean, mask))
    approx(taken_fdd.var, B.submatrix(fdd.var, mask))
    approx(taken_fdd.noise, B.submatrix(fdd.noise, mask))
    assert isinstance(taken_fdd.noise, matrix.Diagonal)

    # Test that only masks are supported, for now.
    with pytest.raises(AssertionError):
        B.take(fdd, np.array([1, 2]))
示例#14
0
def test_update_inputs():
    prior = Measure()
    f = GP(EQ(), measure=prior)

    x = np.array([[1], [2], [3]])
    y = np.array([[4], [5], [6]], dtype=float)
    res = B.concat(x, y, axis=1)
    x_ind = np.array([[6], [7]])
    res_ind = np.array([[6, 0], [7, 0]])

    # Check vanilla case.
    gpar = GPAR(x_ind=x_ind)
    approx(gpar._update_inputs(x, x_ind, y, f, None), (res, res_ind))

    # Check imputation with prior.
    gpar = GPAR(impute=True, x_ind=x_ind)
    this_y = y.copy()
    this_y[1] = np.nan
    this_res = res.copy()
    this_res[1, 1] = 0
    approx(gpar._update_inputs(x, x_ind, this_y, f, None), (this_res, res_ind))

    # Check replacing with prior.
    gpar = GPAR(replace=True, x_ind=x_ind)
    this_y = y.copy()
    this_y[1] = np.nan
    this_res = res.copy()
    this_res[0, 1] = 0
    this_res[1, 1] = np.nan
    this_res[2, 1] = 0
    approx(gpar._update_inputs(x, x_ind, this_y, f, None), (this_res, res_ind))

    # Check imputation and replacing with prior.
    gpar = GPAR(impute=True, replace=True, x_ind=x_ind)
    this_res = res.copy()
    this_res[:, 1] = 0
    approx(gpar._update_inputs(x, x_ind, y, f, None), (this_res, res_ind))

    # Construct observations and update result for inducing points.
    obs = Obs(f(np.array([1, 2, 3, 6, 7])), np.array([9, 10, 11, 12, 13]))
    res_ind = np.array([[6, 12], [7, 13]])

    # Check imputation with posterior.
    gpar = GPAR(impute=True, x_ind=x_ind)
    this_y = y.copy()
    this_y[1] = np.nan
    this_res = res.copy()
    this_res[1, 1] = 10
    approx(gpar._update_inputs(x, x_ind, this_y, f, obs), (this_res, res_ind))

    # Check replacing with posterior.
    gpar = GPAR(replace=True, x_ind=x_ind)
    this_y = y.copy()
    this_y[1] = np.nan
    this_res = res.copy()
    this_res[0, 1] = 9
    this_res[1, 1] = np.nan
    this_res[2, 1] = 11
    approx(gpar._update_inputs(x, x_ind, this_y, f, obs), (this_res, res_ind))

    # Check imputation and replacing with posterior.
    gpar = GPAR(impute=True, replace=True, x_ind=x_ind)
    this_res = res.copy()
    this_res[0, 1] = 9
    this_res[1, 1] = 10
    this_res[2, 1] = 11
    approx(gpar._update_inputs(x, x_ind, y, f, obs), (this_res, res_ind))
示例#15
0
import matplotlib.pyplot as plt
from wbml.plot import tweak

from stheno import B, Measure, GP, EQ

# Define points to predict at.
x = B.linspace(0, 10, 100)

# Construct a prior.
prior = Measure()
f1 = GP(3, EQ(), measure=prior)
f2 = GP(3, EQ(), measure=prior)

# Compute the approximate product.
f_prod = f1 * f2

# Sample two functions.
s1, s2 = prior.sample(f1(x), f2(x))

# Predict.
post = prior | ((f1(x), s1), (f2(x), s2))
mean, lower, upper = post(f_prod(x)).marginals()

# Plot result.
plt.plot(x, s1, label="Sample 1", style="train")
plt.plot(x, s2, label="Sample 2", style="train", ls="--")
plt.plot(x, s1 * s2, label="True product", style="test")
plt.plot(x, mean, label="Approximate posterior", style="pred")
plt.fill_between(x, lower, upper, style="pred")
tweak()
            for j in range(n):
                ps[i] += A[i, j] * self.ps[j]
        return VGP(ps)


# Define points to predict at.
x = B.linspace(0, 10, 100)
x_obs = B.linspace(0, 10, 10)

# Model parameters:
m = 2
p = 4
H = B.randn(p, m)

# Construct latent functions.
prior = Measure()
us = VGP([GP(EQ(), measure=prior) for _ in range(m)])
fs = us.lmatmul(H)

# Construct noise.
e = VGP([GP(0.5 * Delta(), measure=prior) for _ in range(p)])

# Construct observation model.
ys = e + fs

# Sample a true, underlying function and observations.
samples = prior.sample(*(p(x) for p in fs.ps), *(p(x_obs) for p in ys.ps))
fs_true, ys_obs = samples[:p], samples[p:]

# Compute the posterior and make predictions.
post = prior | (*((p(x_obs), y_obs) for p, y_obs in zip(ys.ps, ys_obs)), )
示例#17
0
文件: eq.py 项目: wesselb/gpcm
# Setup experiment.
n = 881  # Add last one for `linspace`.
noise = 0.1
t = B.linspace(-44, 44, n)
t_plot = B.linspace(44, 44, 500)

# Setup true model and GPCM models.
kernel = EQ()
window = 2
scale = 1
n_u = 40
n_z = 88

# Sample data.
m = Measure()
gp_f = GP(kernel, measure=m)
gp_y = gp_f + GP(noise * Delta(), measure=m)
truth, y = map(B.flatten, m.sample(gp_f(t_plot), gp_y(t)))

# Remove region [-8.8, 8.8].
inds = ~((t >= -8.8) & (t <= 8.8))
t = t[inds]
y = y[inds]


def comparative_kernel(vs_):
    return vs_.pos(1) * kernel.stretch(vs_.pos(1.0)) + vs_.pos(noise) * Delta()


run(
import matplotlib.pyplot as plt
from wbml.plot import tweak

from stheno import Measure, GP, EQ, RQ, Linear, Delta, Exp, B

B.epsilon = 1e-10

# Define points to predict at.
x = B.linspace(0, 10, 200)
x_obs = B.linspace(0, 7, 50)

# Construct a latent function consisting of four different components.
prior = Measure()
f_smooth = GP(EQ(), measure=prior)
f_wiggly = GP(RQ(1e-1).stretch(0.5), measure=prior)
f_periodic = GP(EQ().periodic(1.0), measure=prior)
f_linear = GP(Linear(), measure=prior)

f = f_smooth + f_wiggly + f_periodic + 0.2 * f_linear

# Let the observation noise consist of a bit of exponential noise.
e_indep = GP(Delta(), measure=prior)
e_exp = GP(Exp(), measure=prior)

e = e_indep + 0.3 * e_exp

# Sum the latent function and observation noise to get a model for the observations.
y = f + 0.5 * e

# Sample a true, underlying function and observations.
(
import matplotlib.pyplot as plt
from wbml.plot import tweak

from stheno import Measure, GP, EQ, RQ, Linear, Delta, Exp, B

B.epsilon = 1e-10

# Define points to predict at.
x = B.linspace(0, 10, 200)
x_obs = B.linspace(0, 7, 50)

with Measure() as prior:
    # Construct a latent function consisting of four different components.
    f_smooth = GP(EQ())
    f_wiggly = GP(RQ(1e-1).stretch(0.5))
    f_periodic = GP(EQ().periodic(1.0))
    f_linear = GP(Linear())
    f = f_smooth + f_wiggly + f_periodic + 0.2 * f_linear

    # Let the observation noise consist of a bit of exponential noise.
    e_indep = GP(Delta())
    e_exp = GP(Exp())
    e = e_indep + 0.3 * e_exp

    # Sum the latent function and observation noise to get a model for the observations.
    y = f + 0.5 * e

# Sample a true, underlying function and observations.
(
    f_true_smooth,
    f_true_wiggly,
import matplotlib.pyplot as plt
from wbml.plot import tweak

from stheno import B, Measure, GP, EQ, Delta

# Define points to predict at.
x = B.linspace(0, 10, 100)
x_obs = B.linspace(0, 10, 20)

# Constuct a prior:
prior = Measure()
w = lambda x: B.exp(-(x**2) / 0.5)  # Window
b = [(w * GP(EQ(), measure=prior)).shift(xi)
     for xi in x_obs]  # Weighted basis funs
f = sum(b)  # Latent function
e = GP(Delta(), measure=prior)  # Noise
y = f + 0.2 * e  # Observation model

# Sample a true, underlying function and observations.
f_true, y_obs = prior.sample(f(x), y(x_obs))

# Condition on the observations to make predictions.
post = prior | (y(x_obs), y_obs)

# Plot result.
for i, bi in enumerate(b):
    mean, lower, upper = post(bi(x)).marginals()
    kw_args = {"label": "Basis functions"} if i == 0 else {}
    plt.plot(x, mean, style="pred2", **kw_args)
plt.plot(x, f_true, label="True", style="test")
plt.scatter(x_obs, y_obs, label="Observations", style="train", s=20)
示例#21
0
import matplotlib.pyplot as plt
import wbml.out as out
from wbml.plot import tweak

from stheno import B, Measure, GP, Delta

# Define points to predict at.
x = B.linspace(0, 10, 200)
x_obs = B.linspace(0, 10, 10)

# Construct the model.
prior = Measure()
slope = GP(1, measure=prior)
intercept = GP(5, measure=prior)
f = slope * (lambda x: x) + intercept

e = 0.2 * GP(Delta(), measure=prior)  # Noise model

y = f + e  # Observation model

# Sample a slope, intercept, underlying function, and observations.
true_slope, true_intercept, f_true, y_obs = prior.sample(
    slope(0), intercept(0), f(x), y(x_obs))

# Condition on the observations to make predictions.
post = prior | (y(x_obs), y_obs)
mean, lower, upper = post(f(x)).marginals()

out.kv("True slope", true_slope[0, 0])
out.kv("Predicted slope", post(slope(0)).mean[0, 0])
out.kv("True intercept", true_intercept[0, 0])