1.高斯过程是定义在连续域上的无限多个服从高斯分布的随机变量所组成的随机过程
2.高斯过程回归有两个视角:权重空间视角和函数空间视角,这两者是等价的
3.权重空间视角是贝叶斯线性回归与核函数的结合形式
4.函数空间视角是函数服从高斯过程的随机变量,能优化“黑盒子”函数的效果
5.高斯过程回归也应用在机器学习模型超参数调节中,效率比网格搜索、随机搜索都要高
高斯过程回归有两个视角,一个是权重空间视角(weight-space view),另一个是函数空间视角(function-space view),它们达到的效果一样的。我们先从高斯过程开始介绍,理解这两个视角下的高斯过程回归,你会发现它其实是贝叶斯线性回归的非线性形式,且为后面深入理解贝叶斯调参打下基础。
高斯过程
高斯过程(Gaussian Process,GP)是定义在连续域上的无限多个服从高斯分布的随机变量所组成的随机过程。
一个高斯过程由mean function和kernel function唯一确定(高斯过程存在性定理).
下面通过一个例子来理解高斯过程。
假设人的心率在一天中是服从正态分布的,那么心率就是一个随机变量,在每天的任意一个时刻测量都会得到一个值。如果星期一到星期四都进行测量,那么就会得到下面的一幅图:
从函数视角去看,每天有无数个时刻,这些时刻的测量值就构成了一个无限维的高斯分布,我们就把这个过程称为高斯过程。
注:关于例子更多的解释见参考资料第一个链接
高斯回归:权重空间角度
在贝叶斯线性回归一文中,我们求解了以参数为随机变量视角下线性回归的问题,这里回顾一下问题与结论:
本文,我们思考一个更普遍的情况。如果特征与参数之间不再是线性的关系,而是其他非线性关系的时候,如何求解参数的概率分布呢?
我们在核函数一文中提到了一种解决思路,对特征做高维映射,使得其在高维空间上与参数是线性关系的。而高斯过程回归的第一个视角,正是研究这个问题的。
跟核函数一样,对特征向量X做高维映射后贝叶斯线性回归求解参数如下:
下面我们求解其均值与方差
高维空间上均值计算:
为了计算方差,我们需要用到woodbury formula公式:
根据该公式可以计算高维空间上方差:
于是我们得到高维空间上贝叶斯线性回归参数概率分布:
我们观察其均值与方差的表达式,可以发现
因此,分布函数可以改写成下面的形式:
我们也把这个过程称为高斯过程回归,它实质上是贝叶斯线性回归与核方法的结合形式.
这里需要澄清的是,该过程与高斯过程没有关系,它仅仅是一个名字,我们也把这个从参数角度的推导称为高斯过程回归的权重空间视角(weight-space view)
高斯回归:函数空间角度
函数空间关注的是f(x),把它当作一个随机变量,根据贝叶斯线性回归映射到高维空间有:
于是f(x)均值为
协方差为
这里可以得到两点:
首先随机变量f(x)之间的协方差可以通过样本点的核函数计算得到;其次它们的一系列组合{f(x)}就是服从一个高斯过程GP
把上面的结果应用到回归里面,就是高斯过程回归,问题变成下面这样:
注:这里的均值,协方差是关于f(x)的均值和协方差,这一点需要清晰
注:求解高斯条件概率分布见文章高斯分布
我们把上面以函数视角的推导过程称为函数空间视角(function space view)的高斯过程回归.
仔细观察上面的推导过程,我们始终不知道特征X与参数w之间的关系,这给我们一个很有用的启发,就是我们不需要知道函数的表达式,也可以对它进行建模。就是把函数表达式当作黑盒子,利用高斯过程回归,依然能拟合其分布。这个思想也应用到了机器学习的调参中,我们后面提到贝叶斯优化再具体讲解。
高斯过程回归应用
下面通过一个例子,来直观感受高斯过程回归的原理。小编通过python实现这个过程,分为手动实现和sklearn包内置模块实现。
我们假设要优化的黑盒子函数为f(x)=xsinx,为了演示方便,设x只有一维特征。利用python生成只有6个样本点的训练集。
def y(x, noise_sigma=0.0):
x = np.asarray(x)
y = x*np.sin(x) + np.random.normal(0, noise_sigma, size=x.shape)
return y.tolist()
train_X = np.array([1, 3, 5, 6, 7, 8]).reshape(-1, 1)
train_y = y(train_X, noise_sigma=1e-4)
test_X = np.arange(0, 10, 0.1).reshape(-1, 1)
我们指定核函数为RBF函数,为其设置RBF函数的超参数
sca_l = 1 #sklearn内置以标准差为参数
ga = 1/(2*sca_l*sca_l) #python内置的rbf核函数为gamma参数
在文章核函数中,我们知道sklearn.metrics.pairwise提供的RBF是以gamma参数传入,而高斯回归模块提供的是标准差,所以用两个参数统一,为了比较手动和自动的区别是否一致
手动实现
根据函数空间的高斯回归的均值与方差表达式,编写下面程序
K = rbf_kernel(train_X,gamma=ga)
u = np.array([0 for i in train_y]).reshape(-1,1) #均值假设为0
a = rbf_kernel(test_X,train_X,gamma=ga) #k(x*,x)
k = linalg.inv(K+np.diag(np.random.normal(0, scale=1e-4, size=K.shape))) #(K+o^2I)^-1
c = rbf_kernel(train_X,test_X,gamma=ga) #k(x,x*)
mu = np.array([u[0] for i in test_X]).reshape(-1,1)+np.dot(np.dot(a,k),train_y-u) #均值后验
cov = rbf_kernel(test_X,gamma=ga)-np.dot(np.dot(a,k),c) #更新协方差矩阵
test_y = mu.ravel()
uncertainty = 1.96 * np.sqrt(np.diag(cov)) #95%置信区间
作图看看结果
自动实现
sklearn提供了高斯回归的模块包,我们利用内置包看看结果是否与手动结果一致
from sklearn.gaussian_process.kernels import RBFfrom sklearn.gaussian_process import GaussianProcessRegressor
ker = RBF(length_scale=sca_l, length_scale_bounds='fixed')
gpr = GaussianProcessRegressor(kernel=ker, n_restarts_optimizer=2,normalize_y=False)
gpr.fit(train_X, train_y)
mu, cov = gpr.predict(test_X, return_cov=True)
test_y = mu.ravel()
uncertainty = 1.96 * np.sqrt(np.diag(cov))
plt.figure()
plt.title("GPR自动实现")
plt.fill_between(test_X.ravel(), test_y + uncertainty, test_y - uncertainty, alpha=0.1)
plt.plot(test_X, test_y, label="predict")
plt.scatter(train_X, train_y, label="train", c="red", marker="x")
plt.legend()
plt.show()
最后,高斯回归也应用在超参数较多的调参中,叫贝叶斯优化调参,它比网格搜索,随机搜索都高效,我们不久将会推出文章详细介绍
参考资料:
http://www.columbia.edu/~jwp2128/Teaching/E6892/papers/mlss2012_cunningham_gaussian_processes.pdf
https://scikit-learn.org/stable/user_guide.html