我想计算 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)))
最佳答案
所以,首先,多元正态分布的熵(和 GP,给定一组固定的点进行评估)only depends在其协方差矩阵上。
问题的答案:
- 是的 - 当您使集合 $X$ 越来越密集时,您会使协方差矩阵越来越大,对于许多简单的协方差核,这会使行列式越来越小。我的猜测是,这是由于大矩阵的行列式具有很多 乘积项(请参阅 Leibniz formula )和小于一个项的乘积比他们的总和更快归零。您可以轻松验证这一点:
代码:
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")
在进入下一点之前,请注意多元正态的熵也有来自矩阵大小的贡献,所以即使行列式突然变为零,也有很小的贡献从维度上看。
- 正如预期的那样,随着噪声的降低,熵和行列式确实会降低,但不会完全趋于零;由于协方差中存在其他内核,它们将减少为行列式。对于下面的演示,协方差的维数保持不变 ($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")
关于python - 如何获得完整的协方差矩阵并在 GPflow 中找到它的熵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53345624/