高斯过程回归增量学习

Gaussian Process Regression incremental learning

我正在使用高斯过程回归的 scikit-learn 实现 here,我想拟合单个点而不是拟合整组点。但是生成的 alpha 系数应该保持不变,例如

gpr2 = GaussianProcessRegressor()
    for i in range(x.shape[0]):
        gpr2.fit(x[i], y[i])

应该和

一样
gpr = GaussianProcessRegressor().fit(x, y)

但是在访问gpr2.alpha_gpr.alpha_时,它们是不一样的。这是为什么?

事实上,我正在从事一个出现新数据点的项目。我不想再次附加 x、y 数组并适合整个数据集,因为它非常耗时。让 x 的大小为 n,那么我有:

n+(n-1)+(n-2)+...+1 € O(n^2) fittings

考虑到拟合本身是二次的(如果我错了请纠正我),运行 时间复杂度应该是 O(n^3)。如果我对 n 个点进行一次拟合会更优:

1+1+...+1 = n € O(n)

你说的其实叫在线学习或者增量学习;它本身就是机器学习中的一个巨大的子领域,并且 not 对于所有 scikit-learn 模型都是开箱即用的。引用自相关 documentation:

Although not all algorithms can learn incrementally (i.e. without seeing all the instances at once), all estimators implementing the partial_fit API are candidates. Actually, the ability to learn incrementally from a mini-batch of instances (sometimes called “online learning”) is key to out-of-core learning as it guarantees that at any given time there will be only a small amount of instances in the main memory.

在上面链接文档中的这段摘录之后,有一个完整的列表,列出了当前支持增量学习的所有 scikit-learn 模型,从中可以看出 GaussianProcessRegressor 而不是 其中之一。

虽然sklearn.gaussian_process.GaussianProcessRegressor不直接实现增量学习,但没有必要从头开始完全重新训练您的模型。

要完全理解其工作原理,您应该了解 GPR 的基本原理。关键思想是训练 GPR 模型主要包括优化内核参数以最小化某些 objective 函数(默认情况下的对数边际似然)。当在类似数据上使用相同的内核时,可以重用这些参数。由于优化器具有基于收敛的停止条件,因此可以通过使用预训练值初始化参数(所谓的热启动)来加速重新优化。

下面是一个基于 sklearn docs.

中的示例
from time import time
from sklearn.datasets import make_friedman2
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import DotProduct, WhiteKernel
X, y = make_friedman2(n_samples=1000, noise=0.1, random_state=0)
kernel = DotProduct() + WhiteKernel()

start = time()
gpr = GaussianProcessRegressor(kernel=kernel,
        random_state=0).fit(X, y)
print(f'Time: {time()-start:.3f}')
# Time: 4.851
print(gpr.score(X, y))
# 0.3530096529277589

# the kernel is copied to the regressor so we need to 
# retieve the trained parameters
kernel.set_params(**(gpr.kernel_.get_params()))

# use slightly different data
X, y = make_friedman2(n_samples=1000, noise=0.1, random_state=1)

# note we do not train this model
start = time()
gpr2 = GaussianProcessRegressor(kernel=kernel,
        random_state=0).fit(X, y)
print(f'Time: {time()-start:.3f}')
# Time: 1.661
print(gpr2.score(X, y))
# 0.38599549162834046

您可以看到,与从头开始训练相比,重新训练的时间要少得多。虽然这可能不是完全增量的,但它可以帮助加快在流数据设置中的训练。