【问题标题】:Gaussian Process Regression incremental learning高斯过程回归增量学习
【发布时间】:2020-07-16 10:13:12
【问题描述】:

我想更多地了解高斯过程回归:我正在使用 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) 配件

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

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

【问题讨论】:

    标签: python scikit-learn gaussian-process online-machine-learning


    【解决方案1】:

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

    虽然并非所有算法都可以增量学习(即,一次看不到所有实例),但所有实现 partial_fit API 的估计器都是候选者。实际上,从小批量实例中增量学习的能力(有时称为“在线学习”)是核外学习的关键,因为它保证在任何给定时间,在主内存。

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

    【讨论】:

    • 是的,当然!我找到了一个相关的 github 链接。我会把它留给任何会偶然发现相同问题的人:github.com/Bigpig4396/…
    【解决方案2】:

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

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

    以下是基于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
    

    您可以看到,与从头开始培训相比,再培训的时间要短得多。虽然这可能不是完全增量的,但它可以帮助在使用流数据的环境中加快训练速度。

    【讨论】:

    • 是的,它可以通过优化对数边际似然来完成,但更好的做法是在训练时简单地找到内核矩阵的逆矩阵。我使用块矩阵逆和 Sherman Morrison 公式来逐步学习新的数据点。在这种情况下,对可能性进行数值优化会产生更不准确的结果。此外,优化数据流的可能性不一定在计算上更便宜,因为优化器不一定收敛得更快。
    • 我刚刚注意到 @manh-khôi-duong 对 Desertnaut 答案的评论。发布该评论作为此问题的答案似乎是个好主意。
    猜你喜欢
    • 2023-03-22
    • 2015-09-10
    • 2018-12-06
    • 2016-09-29
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 2021-05-26
    相关资源
    最近更新 更多