3

我想计算 GPFlow 中 GP 回归的协方差矩阵的行列式。我猜我可以用这个函数得到协方差矩阵:

GPModel.predict_f_full_cov

这里建议使用此功能:

https://gpflow.readthedocs.io/en/develop/notebooks/regression.html

但是,我不知道如何使用这个函数或它返回什么。我需要知道一个返回整个模型的协方差矩阵的函数,然后我需要知道如何计算它的行​​列式。

经过一番努力,我想出了如何给 predict_f_full_cov 一些我感兴趣的点,如下所示:

c = m.predict_f_full_cov(np.array([[.2],[.4],[.6],[.8]])))

这返回了两个数组,其中第一个是我沿 x 轴要求的点的预测函数的平均值。第二个数组有点神秘。我猜这是协方差矩阵。我用这个把它拉出来:

covMatrix = m.predict_f_full_cov(np.array([[.2],[.4],[.6],[.8]]))[1][0]

然后我查找了如何计算行列式,如下所示:

x = np.linalg.det(covMatrix)

然后我计算了它的对数以获得协方差矩阵的熵:

print(-10*math.log(np.linalg.det(covMatrix)))

我使用两组不同的数据运行了两次。第一个噪音大,第二个噪音低。奇怪的是,低噪声数据集的熵上升了。我很茫然。

我发现,如果我只是在一个应该是线性的小区域上计算协方差矩阵,那么上下调整噪声不会达到我的预期。此外,如果我将 GP 回归到大量点,则行列式变为 0.0。

这是我正在使用的代码:

import gpflow
import numpy as np
N = 300
noiseSize = 0.01
X = np.random.rand(N,1)
Y = np.sin(12*X) + 0.66*np.cos(25*X)  + np.random.randn(N,1)*noiseSize + 3
k = gpflow.kernels.Matern52(1, lengthscales=0.3)
m = gpflow.models.GPR(X, Y, kern=k)
m.likelihood.variance = 0.01
aRange = np.linspace(0.1,0.9,200)
newRange = []
for point in aRange:
    newRange.append([point])
covMatrix = m.predict_f_full_cov(newRange)[1][0]
import math
print("Determinant: " + str(np.linalg.det(covMatrix)))
print(-10*math.log(np.linalg.det(covMatrix)))
4

1 回答 1

1

因此,首先,多元法线(和 GP,给定一组固定的对其进行评估的点)的熵仅取决于其协方差矩阵。

回答您的问题:

  1. 是的 - 当您使集合 $X$ 越来越密集时,您正在使协方差矩阵越来越大,并且对于许多简单的协方差内核,这使得行列式越来越小。我的猜测是,这是因为大型矩阵的行列式有很多乘积项(参见莱布尼茨公式),并且项小于 1 的乘积往往比它们的总和更快地趋于零。您可以轻松地验证这一点:

维度和 Covar

代码:

import numpy as np
import matplotlib.pyplot as plt
import sklearn.gaussian_process.kernels as k

plt.style.use("ggplot"); plt.ion()

n = np.linspace(2, 25, 23, dtype = int)
d = np.zeros(len(n))

for i in range(len(n)):
    X = np.linspace(-1, 1, n[i]).reshape(-1, 1)
    S = k.RBF()(X)
    d[i] = np.log(np.linalg.det(S))

plt.scatter(n, d)
plt.ylabel("Log Determinant of Covariance Matrix")
plt.xlabel("Dimension of Covariance Matrix")

在进入下一点之前,请注意多元法线的熵也有来自矩阵大小的贡献,因此即使行列式下降到零,维度也有很小的贡献。

  1. 正如人们所预料的那样,随着噪声的减少,熵和行列式确实会减少,但不会完全趋于零;由于协方差中存在其他内核,它们将减少到行列式。对于下面的演示,协方差的维度保持不变($10*10$),噪声水平从 0 开始增加:

错误和行列式

代码:

e = np.logspace(1, -10, 30)
d = np.zeros(len(e))
X = np.linspace(-1, 1, 10).reshape(-1, 1)

for i in range(len(e)):
    S = (k.RBF() + k.WhiteKernel(e[i])) (X)
    d[i] = np.log(np.linalg.det(S))

e = np.log(e)

plt.scatter(e, d)
plt.ylabel("Log Determinant")
plt.xlabel("Log Error")
于 2018-11-26T18:07:06.990 回答