前言
上一篇高斯过程回归原理推导,我们已经就高斯过程回归进行了数学推导。此时就使用Python对其进行代码实现。
代码实现
本代码使用高斯核函数,其公式如下
k
(
x
1
,
x
2
)
=
exp
{
−
∣
∣
x
1
−
x
2
∣
∣
2
2
2
σ
2
}
k(x_1,x_2)=\exp\left\{-\frac{||x_1-x_2||_2^2}{2\sigma^2}\right\}
k(x1,x2)=exp{−2σ2∣∣x1−x2∣∣22}
分子处是L2范数
来看一下结果
红色点为训练集,蓝色为测试集,阴影部分为置信区间。先验期望为0.
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
np.random.seed(2) #随机数种子
def kernel(x1,x2):
'''
高斯核函数
:param x1: 输入x1
:param x2: 输入x2
:return: 返回相乘的值
'''
sigma=1
L2=np.sum(x1**2,1).reshape(-1,1)+np.sum(x2**2,1)-2*x1@x2.T
result=np.exp(-L2/(2*sigma**2))
return result
class GPR():
def __init__(self):
pass
def train(self,X,Y):
self.x=X #储存训练集
self.y=Y #储存训练集
def predition(self,test_x):
priori_mean=0 #先验均值
noise_var=0.001 #噪声标准差
K_XX=kernel(self.x,self.x) #k(x,x)
K_tx_tx=kernel(test_x,test_x) #k(x*,x*)
K_tx_X=kernel(test_x,self.x) #k(x*,x)
K_XX_inv=np.linalg.inv(K_XX+noise_var**2*np.eye(K_XX.shape[0])) #求逆并加上噪声项的方差
#求解,套公式
mean=priori_mean+K_tx_X@K_XX_inv@(self.y-priori_mean) #期望
cov=K_tx_tx-K_tx_X@K_XX_inv@K_tx_X.T+noise_var**2*np.eye(K_tx_tx.shape[0]) #方差
return mean,cov
def plot_figure(x,y,test_x,mean,confidence):
'''
绘图函数,与模型无关
:param x: 训练集x轴
:param y: 训练集y轴
:param test_x: #测试集x轴
:param mean: #测试集y轴
:param confidence: #置信度
:return:
'''
plt.scatter(test_x,mean)
plt.scatter(x,y,marker="x",c="r")
plt.fill_between(test_x.reshape(-1),
mean.reshape(-1)+confidence,
mean.reshape(-1)-confidence,
alpha=0.1,
color="g")
plt.show()
def y(data):
a=np.cos(data)+stats.norm.rvs(0,1,size=data.shape) #加上噪声
return a
if __name__ == '__main__':
x=np.arange(0,10,2).reshape(-1,1) #生成训练集x,0到10,步长为2
y=y(x).reshape(-1,1) #计算对应的y,加上噪声
test_x=np.arange(0,20,0.2).reshape(-1,1) #生成测试集
gpr=GPR() #初始化模型
gpr.train(x,y) #导入模型训练集
mean,cov=gpr.predition(test_x) #预测
confidence=1.96*np.sqrt(np.diag(cov)) #计算置信度,但不除以数据长度(为了直观看到区间)
plot_figure(x,y,test_x,mean,confidence) #绘图