GPR tutorial
高斯过程回归(Gaussian process regression,GPR)是一个随机过程(按时间或空间索引的随机变量集合),这些随机变量的每个有限集合都服从多元正态分布,即它们的每个有限线性组合都是正态分布。高斯过程的分布是所有这些(无限多)随机变量的联合概率分布。
定义:一个高斯过程是一组随机变量的集合,这组随机变量的每个有限子集构成的联合概率分布都服从多元高斯分布,即:
f
∼
G
P
(
μ
,
k
)
(
1
−
1
)
f \sim GP(\mu,k) \qquad(1-1)
f∼GP(μ,k)(1−1)
其中
μ
(
x
)
\mu(x)
μ(x)和
k
(
x
,
x
′
)
k(x,x')
k(x,x′)分别为随机变量x的均值函数和协方差函数。因此可看出,一个高斯过程实际是由随机变量的均值和协方差函数所决定。
在传统回归模型中,定义
Y
=
f
(
x
)
Y=f(x)
Y=f(x),而在高斯过程回归中,设f(x)服从高斯分布。通常假设均值为0,则:
Y
=
f
(
x
)
∼
N
(
0
,
Σ
)
(
1
−
2
)
Y=f(x)\sim N(0,\Sigma) \qquad(1-2)
Y=f(x)∼N(0,Σ)(1−2)
其中
Σ
\Sigma
Σ是协方差函数。使用核技巧,令
Σ
i
j
=
K
(
x
i
,
x
j
)
\Sigma_{ij}=K(\mathbf{x}_i,\mathbf{x}_j)
Σij=K(xi,xj),则可由求核函数K来计算协方差函数。如核函数K使用RBF核,则
Σ
i
j
=
τ
e
−
∥
x
i
−
x
j
∥
2
σ
2
\Sigma_{ij}=\tau e^\frac{-\|\mathbf{x}_i-\mathbf{x}_j\|^2}{\sigma^2}
Σij=τeσ2−∥xi−xj∥2。如使用多项式核,则
Σ
i
j
=
τ
(
1
+
x
i
⊤
x
j
)
d
\Sigma_{ij}=\tau (1+\mathbf{x}_i^\top \mathbf{x}_j)^d
Σij=τ(1+xi⊤xj)d。
因此,协方差函数
Σ
\Sigma
Σ可分解为
(
K
,
K
∗
K
∗
⊤
,
K
∗
∗
)
\begin{pmatrix} K, K_* \\K_*^\top , K_{**} \end{pmatrix}
(K,K∗K∗⊤,K∗∗)。其中K是训练核矩阵,
K
∗
K_*
K∗是训练-测试核矩阵,
K
∗
T
K_*^T
K∗T是测试-训练核矩阵。
隐函数f的条件概率分布可表示为:
f
∗
∣
(
Y
1
=
y
1
,
.
.
.
,
Y
n
=
y
n
,
x
1
,
.
.
.
,
x
n
,
x
t
)
∼
N
(
K
∗
⊤
K
−
1
y
,
K
∗
∗
−
K
∗
⊤
K
−
1
K
∗
)
(
1
−
3
)
f_*|(Y_1=y_1,...,Y_n=y_n,\mathbf{x}_1,...,\mathbf{x}_n,\mathbf{x}_t)\sim \mathcal{N}(K_*^\top K^{-1}y,K_{**}-K_*^\top K^{-1}K_* ) \qquad(1-3)
f∗∣(Y1=y1,...,Yn=yn,x1,...,xn,xt)∼N(K∗⊤K−1y,K∗∗−K∗⊤K−1K∗)(1−3)
基于机器学习库sklearn实现高斯过程回归。sklearn中GaussianProcessRegressor模块实现了高斯过程回归模型,从模型参数、属性和方法等方面介绍该模型,其主要参数包括:
| 参数名 | 参数含义 | 备注 |
|---|---|---|
| kernel | 核函数形式的高斯过程的协方差函数 | 常用核函数有:RBF、ConstantKernel;核函数的常见超参数有核的长度尺寸、长度尺寸的上下限 |
| alpha | 在模型拟合过程中加入核矩阵对角线位置的值 | (1)确保计算值形成正定矩阵,防止拟合过程中出现潜在的数值问题;(2)也可以解释为训练观测值上附加高斯测量噪声的方差;(3)如果alpha参数传递的是一个数组,它必须与用于拟合的数据具有相同的条目数,并用作依赖于数据点的噪声级 |
| random_state | 随机状态数 | 决定用于初始化中心的随机数的生成,在多次函数调用时,指定此参数保证可复现性 |

GaussianProcessRegressor回归模型的主要属性包括:
| 属性名称 | 尺寸 |
|---|---|
| X_train_ | array-like of shape (n_samples, n_features) or list of object |
| y_train_ | array-like of shape (n_samples,) or (n_samples, n_targets) |
GaussianProcessRegressor回归模型的常用方法包括:
| 方法名称 | 参数 | 返回值 |
|---|---|---|
| predict(X, return_std=False, return_cov=False) | X是高斯过程要拟合的样本点 | 用GPR模型进行预测,返回样本点预测概率分布的均值、标准差和预测联合概率分布的协方差 |
| score(X, y, sample_weight=None) | X是测试样本, y是X对应的真值 | 返回GPR模型预测的 R 2 R^2 R2系数, R 2 R^2 R2系数计算方法为 1 − ( ( ( y t r u e − y p r e d ) ∗ ∗ 2 ) . s u m ( ) ( y t r u e − y t r u e . m e a n ( ) ) ∗ ∗ 2 ) . s u m ( ) 1-\frac{(((y_{true} - y_{pred})** 2).sum()}{(y_{true} - y_{true}.mean()) ** 2).sum()} 1−(ytrue−ytrue.mean())∗∗2).sum()(((ytrue−ypred)∗∗2).sum() |
核函数在sklearn.gaussian_process.kernels模块中,常用的核函数有:
在sklearn中RBF函数有两个参数:
RBF(length_scale=1.0, length_scale_bounds=(1e-05, 100000.0))
# length_scale:核函数的长度尺寸,float or ndarray of shape (n_features,), default=1.0
# length_scale_bounds:核函数长度尺寸的上下限,若设为'fixed',则无法在超参数调整期间修改核函数长度尺寸。
kernel = RBF() + ConstantKernel(constant_value=2,constant_value_bounds=(1e-5, 1e5))
# 作用等价于:kernel = RBF() + 2
导入库:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C, WhiteKernel
import sklearn.gaussian_process.kernels as k
训练GPR模型:
def gpr_regressor(X_train,y_train,X_test,y_test,kernel=C(constant_value=1) * RBF(length_scale=1, length_scale_bounds=(1e-2, 1e2))):
"""
gpr model for regression
:param X_train: (n_samples, n_features)
:param y_train: (n_samples,)
:param X_test: (n_samples, n_features)
:param y_test: (n_samples,)
:param kernel: kernel of gpr
:return:
y_pred: mean predictions
y_pred_std: std predictions
r2: r2 score of gpr
"""
gp = GaussianProcessRegressor(kernel=kernel)
gp.fit(X_train, y_train) # Instantiated Gaussian regression model
print("the learned kernel parameters:\t {}".format(gp.kernel_)) # the learned kernel parameters
y_pred, y_pred_std = gp.predict(X_test, return_std=True)
r2 = gp.score(X_test, y_test)
print('r2 coefficient is {:.2f}'.format(r2))
return y_pred,y_pred_std,r2
预测结果可视化:
def plot_errorbar_gpr(y_pred,y_pred_std,r2,y_test):
"""
plot errorbar for gpr predictions
:param y_pred:
:param y_pred_std:
:param r2:
:param y_test: one-dimension
:return:
"""
plt.errorbar(x=y_test, y=y_pred, yerr=y_pred_std, fmt="o", label="Samples", markersize=5,color='#2698eb')
#x, y define the data locations, xerr, yerr define the errorbar sizes
plt.xlabel("ground true")
plt.ylabel("predicted ")
plt.title("Gaussian process regression, R2=%.2f" % (r2))
print("finished!")
def plot_intervel_gpr(y_pred,y_pred_std,r2,X_test):
"""
plot confidence interval for gpr predictions
:param y_pred:
:param y_pred_std:
:param r2:
:param X_test: should be one-dimension shape
:return:
"""
# 1.96 sigma = 95% confidence interval for a normal distribution
upper, lower = y_pred + 1.96 * y_pred_std, y_pred - 1.96 * y_pred_std
plt.plot(X_test, y_pred, label="GPR", ls="-")
plt.fill_between(X_test, y1=upper, y2=lower, alpha=0.2, label="95% confidence", color="#2698eb")
plt.legend(ncol=4, fontsize=12)
plt.title("Gaussian process regression, R2=%.2f" %(r2))
print("finished!")
预测概率区间图如下:

以标准差为尺度的误差线图如下:

这里列出了高斯过程回归涉及到的数学基础知识,方便大家参考。
高斯分布的四大属性:标准化(Normalization)、边缘化(Marginalization)、可加性(Summation)、条件性(Conditioning),具体数学表示如下图所示:


贝叶斯框架的基础概念包括条件概率、乘积法则、加和法则、贝叶斯定理等。
(1)条件概率
条
件
概
率
分
布
=
联
合
概
率
分
布
边
缘
概
率
分
布
(
A
−
1
)
条件概率分布=\frac{联合概率分布}{边缘概率分布} \qquad(A-1)
条件概率分布=边缘概率分布联合概率分布(A−1) i.e.
p
(
y
∣
x
)
=
p
(
x
,
y
)
p
(
x
)
p(y|x)=\frac{p(x,y)}{p(x)}
p(y∣x)=p(x)p(x,y).
(2)乘积法则(product rule)
任何联合概率分布,都可以表示为一维条件概率分布的乘积,i.e.
p
(
x
,
y
,
z
)
=
p
(
x
∣
y
,
z
)
p
(
y
∣
z
)
p
(
z
)
p(x,y,z)=p(x|y,z)p(y|z)p(z)
p(x,y,z)=p(x∣y,z)p(y∣z)p(z).
(3) 加和法则(sum rule)
任何边缘概率分布,都可以通过对联合概率分布的积分获得,i.e.
p
(
y
)
=
∫
p
(
x
,
y
)
d
x
p(y)=\int p(x,y)dx
p(y)=∫p(x,y)dx,
p
(
x
)
=
∫
p
(
x
,
y
)
d
y
p(x)=\int p(x,y)dy
p(x)=∫p(x,y)dy.
利用加和法则还可以估计条件概率分布,如已知一组随机变量
x
x
x,
y
y
y,
z
z
z构成的联合概率分布
p
(
x
,
y
,
z
)
p(x,y,z)
p(x,y,z),观测到
x
x
x,感兴趣预测
y
y
y,变量
z
z
z是未知的且与待解决的问题无关,如何只用联合概率分布
p
(
x
,
y
,
z
)
p(x,y,z)
p(x,y,z)去估计
p
(
y
∣
x
)
p(y|x)
p(y∣x)呢?
答案就是用加和法则对联合概率分布求积分:
p
(
y
∣
x
)
=
p
(
x
,
y
)
p
(
x
)
p(y|x)=\frac{p(x,y)}{p(x)}
p(y∣x)=p(x)p(x,y)=
∫
p
(
x
,
y
,
z
)
d
z
∫
p
(
x
,
y
,
z
)
d
z
d
y
\frac{\int p(x,y,z)dz}{\int p(x,y,z)dzdy}
∫p(x,y,z)dzdy∫p(x,y,z)dz
(4)贝叶斯定理(Bayes theorem)
由乘积法则和加和法则可知,任何条件概率分布可由联合概率分布获得。进一步的,利用乘积法则和加和法则,可从条件概率的定义中推导出贝叶斯定理:
p
(
y
∣
x
)
=
p
(
x
,
y
)
p
(
x
)
=
p
(
x
∣
y
)
p
(
y
)
p
(
x
)
=
p
(
x
∣
y
)
p
(
y
)
∫
p
(
x
∣
y
)
p
(
y
)
d
y
(
A
−
2
)
p(y|x)=\frac{p(x,y)}{p(x)}=\frac{p(x|y)p(y)}{p(x)}=\frac{p(x|y)p(y)}{\int p(x|y)p(y)dy} \qquad(A-2)
p(y∣x)=p(x)p(x,y)=p(x)p(x∣y)p(y)=∫p(x∣y)p(y)dyp(x∣y)p(y)(A−2).
从式中可看出,贝叶斯定理定义了当新的信息出现时,不确定性的转化规则,即:
后
验
概
率
=
似
然
概
率
×
先
验
概
率
置
信
度
(
A
−
3
)
后验概率=\frac{似然概率\times 先验概率}{置信度} \qquad(A-3)
后验概率=置信度似然概率×先验概率(A−3)
(5)贝叶斯框架
统计推断方法有频率框架和贝叶斯框架两大流派,贝叶斯框架基于贝叶斯定理去估计后验概率。应用该框架进行推断的经典描述为,给定一组独立同分布的数据
X
=
(
x
1
,
x
2
,
.
.
.
,
x
n
)
X=(x_1,x_2,...,x_n)
X=(x1,x2,...,xn),欲用概率分布
p
(
x
∣
θ
)
p(x|\theta)
p(x∣θ)估计
θ
\theta
θ,贝叶斯框架提供了使用先验概率
p
(
θ
)
p(\theta)
p(θ)编码参数
θ
\theta
θ的不确定度的方法:
p
(
θ
∣
X
)
=
∏
i
=
1
n
p
(
x
i
∣
θ
)
p
(
θ
)
∫
∏
i
=
1
n
p
(
x
i
∣
θ
)
p
(
θ
)
d
θ
(
A
−
4
)
p(\theta|X)=\frac{\prod_{i=1}^np(x_i|\theta)p(\theta)}{\int \prod_{i=1}^np(x_i|\theta)p(\theta)d\theta} \qquad(A-4)
p(θ∣X)=∫∏i=1np(xi∣θ)p(θ)dθ∏i=1np(xi∣θ)p(θ)(A−4)
考虑一个回归问题:
y
=
f
(
x
)
+
ε
(
A
−
5
)
y=f(x)+\varepsilon \qquad(A-5)
y=f(x)+ε(A−5)
为从数据中求解概率,给定特定参数w,预测模型可利用后验预测分布(posterior predictive distribution)来求解。
对于数据集D和特征X,根据贝叶斯定理以及概率分布的加和、乘积法则,后验预测分布可表示为:
P
(
Y
∣
D
,
X
)
=
∫
w
P
(
Y
,
w
∣
D
,
X
)
d
w
P(Y\mid D,X) = \int_{\mathbf{w}}P(Y,\mathbf{w} \mid D,X) d\mathbf{w}
P(Y∣D,X)=∫wP(Y,w∣D,X)dw
=
∫
w
P
(
Y
∣
w
,
D
,
X
)
P
(
w
∣
D
)
d
w
(
A
−
6
)
= \int_{\mathbf{w}} P(Y \mid \mathbf{w}, D,X) P(\mathbf{w} \mid D) d\mathbf{w} \qquad(A-6)
=∫wP(Y∣w,D,X)P(w∣D)dw(A−6)
然而上述公式的解析解(closed form)难以计算,但对于具有高斯似然和先验的特殊情况,我们可以求其高斯过程的均值和协方差,即:
P
(
y
∗
∣
D
,
x
)
∼
N
(
μ
y
∗
∣
D
,
Σ
y
∗
∣
D
)
(
A
−
7
)
P(y_*\mid D,\mathbf{x}) \sim \mathcal{N}(\mu_{y_*\mid D}, \Sigma_{y_*\mid D}) \qquad(A-7)
P(y∗∣D,x)∼N(μy∗∣D,Σy∗∣D)(A−7)
其中均值函数
μ
y
∗
∣
D
\mu_{y_*\mid D}
μy∗∣D和协方差函数
Σ
y
∗
∣
D
\Sigma_{y_*\mid D}
Σy∗∣D, 均可由核函数K计算得到:
μ
y
∗
∣
D
=
K
∗
T
(
K
+
σ
2
I
)
−
1
y
(
A
−
8
)
\mu_{y_*\mid D} = K_*^T (K+\sigma^2 I)^{-1} y \qquad(A-8)
μy∗∣D=K∗T(K+σ2I)−1y(A−8)
Σ
y
∗
∣
D
=
K
∗
∗
−
K
∗
T
(
K
+
σ
2
I
)
−
1
K
∗
(
A
−
9
)
\Sigma_{y_*\mid D} = K_{**} - K_*^T (K+\sigma^2 I)^{-1}K_* \qquad(A-9)
Σy∗∣D=K∗∗−K∗T(K+σ2I)−1K∗(A−9)
[1]cornell 高斯过程lecture
[2]https://cosmiccoding.com.au/tutorials/gaussian_processes
[3]sklearn GaussianProcessRegressor文档
[4].高斯过程可视化展示网页
[5].http://gaussianprocess.org/gpml/chapters/RW.pdf
[6].https://towardsdatascience.com/getting-started-with-gaussian-process-regression-modeling-47e7982b534d
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源