GPFlow多个独立实现同一个GP,不规则采样times/lengths
GPFlow multiple independent realizations of same GP, irregular sampling times/lengths
在GPflow中,我有多个时间序列,采样时间在时间序列之间没有对齐,时间序列可能有不同的长度(纵向数据)。我假设它们是来自同一 GP 的独立实现。使用 svgp 以及更普遍的 GPflow 处理此问题的正确方法是什么?我需要使用核心区域化吗?共区域化笔记本假定相关轨迹,而我想要共享 mean/kernel 但独立。
是的,在 GPflow 中实现的 Coregion
内核可以用来解决您的问题。
让我们根据您描述的生成模型设置一些数据,时间序列的长度不同:
import numpy as np
import gpflow
import matplotlib.pyplot as plt
Ns = [80, 90, 100] # number of observations for three different realizations
Xs = [np.random.uniform(0, 10, size=N) for N in Ns] # observation locations
# three different draws from the same GP:
k = gpflow.kernels.Matern52(variance=2.0, lengthscales=0.5) # kernel
Ks = [k(X[:, None]) for X in Xs]
Ls = [np.linalg.cholesky(K) for K in Ks]
vs = [np.random.randn(N, 1) for N in Ns]
fs = [(L @ v).squeeze(axis=-1) for L, v in zip(Ls, vs)]
为 gpflow GP 模型实际设置训练数据:
# output indicator for the observations: which timeseries is this?
os = [o * np.ones(N) for o, N in enumerate(Ns)] # [0 ... 0, 1 ... 1, 2 ... 2]
# now assemble the three timeseries in single data set:
allX = np.concatenate(Xs)
allo = np.concatenate(os)
allf = np.concatenate(fs)
X = np.c_[allX, allo]
Y = allf[:, None]
assert X.shape == (sum(Ns), 2)
assert Y.shape == (sum(Ns), 1)
# now let's set up a copy of the original kernel:
k2 = gpflow.kernels.Matern52(active_dims=[0]) # the same as k above, but with different hyperparameters
# and a Coregionalization kernel that effectively says they are all independent:
kc = gpflow.kernels.Coregion(output_dim=len(Ns), rank=1, active_dims=[1])
kc.W.assign(np.zeros(kc.W.shape))
kc.kappa.assign(np.ones(kc.kappa.shape))
gpflow.set_trainable(kc, False) # we want W and kappa fixed
Coregion
内核定义协方差矩阵 B = W Wᵀ + diag(kappa),因此通过设置 W=0 我们规定零相关(独立实现)和 kappa=1(实际上是默认值)确保原始内核副本的方差超参数仍然可以解释。
现在构建实际模型并优化超参数:
k2c = k2 * kc
m = gpflow.models.GPR((X, Y), k2c, noise_variance=1e-5)
opt = gpflow.optimizers.Scipy()
opt.minimize(m.training_loss, m.trainable_variables, compile=False)
很好地恢复了初始方差和长度尺度超参数。
如果你想预测,你必须在 m.predict_f()
的 Xnew
参数中提供额外的“输出”列,例如如下:
Xtest = np.linspace(0, 10, 100)
Xtest_augmented = np.c_[Xtest, np.zeros_like(Xtest)]
f_mean, f_var = m.predict_f(Xtest_augmented)
(将输出列设置为 0、1 或 2 并不重要,因为我们将它们全部设置为与我们选择的 W
和 kappa
相同)。
如果您的输入超过one-dimensional,您可以设置
active_dims=list(range(X.shape[1] - 1))
表示第一个内核,active_dims=[X.shape[1]-1]
表示 Coregion
内核。
在GPflow中,我有多个时间序列,采样时间在时间序列之间没有对齐,时间序列可能有不同的长度(纵向数据)。我假设它们是来自同一 GP 的独立实现。使用 svgp 以及更普遍的 GPflow 处理此问题的正确方法是什么?我需要使用核心区域化吗?共区域化笔记本假定相关轨迹,而我想要共享 mean/kernel 但独立。
是的,在 GPflow 中实现的 Coregion
内核可以用来解决您的问题。
让我们根据您描述的生成模型设置一些数据,时间序列的长度不同:
import numpy as np
import gpflow
import matplotlib.pyplot as plt
Ns = [80, 90, 100] # number of observations for three different realizations
Xs = [np.random.uniform(0, 10, size=N) for N in Ns] # observation locations
# three different draws from the same GP:
k = gpflow.kernels.Matern52(variance=2.0, lengthscales=0.5) # kernel
Ks = [k(X[:, None]) for X in Xs]
Ls = [np.linalg.cholesky(K) for K in Ks]
vs = [np.random.randn(N, 1) for N in Ns]
fs = [(L @ v).squeeze(axis=-1) for L, v in zip(Ls, vs)]
为 gpflow GP 模型实际设置训练数据:
# output indicator for the observations: which timeseries is this?
os = [o * np.ones(N) for o, N in enumerate(Ns)] # [0 ... 0, 1 ... 1, 2 ... 2]
# now assemble the three timeseries in single data set:
allX = np.concatenate(Xs)
allo = np.concatenate(os)
allf = np.concatenate(fs)
X = np.c_[allX, allo]
Y = allf[:, None]
assert X.shape == (sum(Ns), 2)
assert Y.shape == (sum(Ns), 1)
# now let's set up a copy of the original kernel:
k2 = gpflow.kernels.Matern52(active_dims=[0]) # the same as k above, but with different hyperparameters
# and a Coregionalization kernel that effectively says they are all independent:
kc = gpflow.kernels.Coregion(output_dim=len(Ns), rank=1, active_dims=[1])
kc.W.assign(np.zeros(kc.W.shape))
kc.kappa.assign(np.ones(kc.kappa.shape))
gpflow.set_trainable(kc, False) # we want W and kappa fixed
Coregion
内核定义协方差矩阵 B = W Wᵀ + diag(kappa),因此通过设置 W=0 我们规定零相关(独立实现)和 kappa=1(实际上是默认值)确保原始内核副本的方差超参数仍然可以解释。
现在构建实际模型并优化超参数:
k2c = k2 * kc
m = gpflow.models.GPR((X, Y), k2c, noise_variance=1e-5)
opt = gpflow.optimizers.Scipy()
opt.minimize(m.training_loss, m.trainable_variables, compile=False)
很好地恢复了初始方差和长度尺度超参数。
如果你想预测,你必须在 m.predict_f()
的 Xnew
参数中提供额外的“输出”列,例如如下:
Xtest = np.linspace(0, 10, 100)
Xtest_augmented = np.c_[Xtest, np.zeros_like(Xtest)]
f_mean, f_var = m.predict_f(Xtest_augmented)
(将输出列设置为 0、1 或 2 并不重要,因为我们将它们全部设置为与我们选择的 W
和 kappa
相同)。
如果您的输入超过one-dimensional,您可以设置
active_dims=list(range(X.shape[1] - 1))
表示第一个内核,active_dims=[X.shape[1]-1]
表示 Coregion
内核。