高斯过程回归:核

Machine LearningMachine LearningBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

本实验展示了如何在 Python 的 Scikit-learn 库中使用不同的核函数进行高斯过程回归(GPR)。GPR 是一种非参数回归技术,它可以将复杂模型拟合到带有噪声的数据上。核函数用于确定任意两个输入点之间的相似度。核函数的选择很重要,因为它决定了拟合数据的模型形状。在本实验中,我们将介绍 GPR 中最常用的核函数。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签页,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/CoreModelsandAlgorithmsGroup(["Core Models and Algorithms"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/CoreModelsandAlgorithmsGroup -.-> sklearn/gaussian_process("Gaussian Processes") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/gaussian_process -.-> lab-49148{{"高斯过程回归:核"}} ml/sklearn -.-> lab-49148{{"高斯过程回归:核"}} end

导入库

我们首先导入必要的库。

import matplotlib.pyplot as plt
import numpy as np
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, RationalQuadratic, ExpSineSquared, ConstantKernel, DotProduct, Matern

创建训练数据

接下来,我们创建一个将在不同部分中使用的训练数据集。

rng = np.random.RandomState(4)
X_train = rng.uniform(0, 5, 10).reshape(-1, 1)
y_train = np.sin((X_train[:, 0] - 2.5) ** 2)
n_samples = 5

辅助函数

在介绍高斯过程可用的每个单独核之前,我们将定义一个辅助函数,用于绘制从高斯过程中抽取的样本。

def plot_gpr_samples(gpr_model, n_samples, ax):
    """绘制从高斯过程模型中抽取的样本。

    如果高斯过程模型未训练,则抽取的样本是从先验分布中抽取的。否则,样本是从后验分布中抽取的。请注意,这里的一个样本对应一个函数。

    参数
    ----------
    gpr_model : `GaussianProcessRegressor`
        一个 :class:`~sklearn.gaussian_process.GaussianProcessRegressor` 模型。
    n_samples : int
        要从高斯过程分布中抽取的样本数量。
    ax : matplotlib 轴
        绘制样本的 matplotlib 轴。
    """
    x = np.linspace(0, 5, 100)
    X = x.reshape(-1, 1)

    y_mean, y_std = gpr_model.predict(X, return_std=True)
    y_samples = gpr_model.sample_y(X, n_samples)

    for idx, single_prior in enumerate(y_samples.T):
        ax.plot(
            x,
            single_prior,
            linestyle="--",
            alpha=0.7,
            label=f"采样函数 #{idx + 1}"
        )
    ax.plot(x, y_mean, color="black", label="均值")
    ax.fill_between(
        x,
        y_mean - y_std,
        y_mean + y_std,
        alpha=0.1,
        color="black",
        label=r"$\pm$ 1 标准差"
    )
    ax.set_xlabel("x")
    ax.set_ylabel("y")
    ax.set_ylim([-3, 3])

径向基函数核

径向基函数(RBF)核定义为:

k(x_i, x_j) = \exp \left( -\frac{\|x_i - x_j\|^2}{2\ell^2} \right)

其中 \ell 是长度尺度参数。

kernel = 1.0 * RBF(length_scale=1.0, length_scale_bounds=(1e-1, 10.0))
gpr = GaussianProcessRegressor(kernel=kernel, random_state=0)

fig, axs = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(10, 8))

## 绘制先验
plot_gpr_samples(gpr, n_samples=n_samples, ax=axs[0])
axs[0].set_title("来自先验分布的样本")

## 绘制后验
gpr.fit(X_train, y_train)
plot_gpr_samples(gpr, n_samples=n_samples, ax=axs[1])
axs[1].scatter(X_train[:, 0], y_train, color="red", zorder=10, label="观测值")
axs[1].legend(bbox_to_anchor=(1.05, 1.5), loc="upper left")
axs[1].set_title("来自后验分布的样本")

fig.suptitle("径向基函数核", fontsize=18)
plt.tight_layout()

有理二次核

有理二次核定义为:

k(x_i, x_j) = \left( 1 + \frac{\|x_i - x_j\|^2}{2\alpha\ell^2} \right)^{-\alpha}

其中 \ell 是长度尺度参数,\alpha 控制小尺度和大尺度特征的相对权重。

kernel = 1.0 * RationalQuadratic(length_scale=1.0, alpha=0.1, alpha_bounds=(1e-5, 1e15))
gpr = GaussianProcessRegressor(kernel=kernel, random_state=0)

fig, axs = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(10, 8))

## 绘制先验
plot_gpr_samples(gpr, n_samples=n_samples, ax=axs[0])
axs[0].set_title("来自先验分布的样本")

## 绘制后验
gpr.fit(X_train, y_train)
plot_gpr_samples(gpr, n_samples=n_samples, ax=axs[1])
axs[1].scatter(X_train[:, 0], y_train, color="red", zorder=10, label="观测值")
axs[1].legend(bbox_to_anchor=(1.05, 1.5), loc="upper left")
axs[1].set_title("来自后验分布的样本")

fig.suptitle("有理二次核", fontsize=18)
plt.tight_layout()

指数正弦平方核

指数正弦平方核定义为:

k(x_i, x_j) = \exp \left( -\frac{2\sin^2(\pi\|x_i - x_j\|/p)}{\ell^2} \right)

其中 \ell 是长度尺度参数,p 控制周期性。

kernel = 1.0 * ExpSineSquared(
    length_scale=1.0,
    periodicity=3.0,
    length_scale_bounds=(0.1, 10.0),
    periodicity_bounds=(1.0, 10.0),
)
gpr = GaussianProcessRegressor(kernel=kernel, random_state=0)

fig, axs = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(10, 8))

## 绘制先验
plot_gpr_samples(gpr, n_samples=n_samples, ax=axs[0])
axs[0].set_title("来自先验分布的样本")

## 绘制后验
gpr.fit(X_train, y_train)
plot_gpr_samples(gpr, n_samples=n_samples, ax=axs[1])
axs[1].scatter(X_train[:, 0], y_train, color="red", zorder=10, label="观测值")
axs[1].legend(bbox_to_anchor=(1.05, 1.5), loc="upper left")
axs[1].set_title("来自后验分布的样本")

fig.suptitle("指数正弦平方核", fontsize=18)
plt.tight_layout()

点积核

点积核定义为:

k(x_i, x_j) = (\sigma_0 + x_i^T x_j)^2

其中 \sigma_0 是一个常数。

kernel = ConstantKernel(0.1, (0.01, 10.0)) * (
    DotProduct(sigma_0=1.0, sigma_0_bounds=(0.1, 10.0)) ** 2
)
gpr = GaussianProcessRegressor(kernel=kernel, random_state=0)

fig, axs = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(10, 8))

## 绘制先验
plot_gpr_samples(gpr, n_samples=n_samples, ax=axs[0])
axs[0].set_title("来自先验分布的样本")

## 绘制后验
gpr.fit(X_train, y_train)
plot_gpr_samples(gpr, n_samples=n_samples, ax=axs[1])
axs[1].scatter(X_train[:, 0], y_train, color="red", zorder=10, label="观测值")
axs[1].legend(bbox_to_anchor=(1.05, 1.5), loc="upper left")
axs[1].set_title("来自后验分布的样本")

fig.suptitle("点积核", fontsize=18)
plt.tight_layout()

马特恩核

马特恩核定义为:

k(x_i, x_j) = \frac{1}{\Gamma(\nu)2^{\nu - 1}}\left(\frac{\sqrt{2\nu}}{\ell}\|x_i - x_j\|\right)^\nu K_\nu\left(\frac{\sqrt{2\nu}}{\ell}\|x_i - x_j\|\right)

其中 \ell 是长度尺度参数,\nu 控制函数的平滑度。

kernel = 1.0 * Matern(length_scale=1.0, length_scale_bounds=(1e - 1, 10.0), nu = 1.5)
gpr = GaussianProcessRegressor(kernel=kernel, random_state=0)

fig, axs = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(10, 8))

## 绘制先验
plot_gpr_samples(gpr, n_samples=n_samples, ax=axs[0])
axs[0].set_title("来自先验分布的样本")

## 绘制后验
gpr.fit(X_train, y_train)
plot_gpr_samples(gpr, n_samples=n_samples, ax=axs[1])
axs[1].scatter(X_train[:, 0], y_train, color="red", zorder=10, label="观测值")
axs[1].legend(bbox_to_anchor=(1.05, 1.5), loc="upper left")
axs[1].set_title("来自后验分布的样本")

fig.suptitle("马特恩核", fontsize=18)
plt.tight_layout()

总结

在本实验中,我们学习了如何在 Python 的 Scikit-learn 库中使用不同的核进行高斯过程回归。我们涵盖了高斯过程回归中最常用的核,包括径向基函数核、有理二次核、指数正弦平方核、点积核和马特恩核。我们还学习了如何使用一个辅助函数绘制从高斯过程中抽取的样本。

总结

恭喜你!你已经完成了“高斯过程回归:核”实验。你可以在 LabEx 中练习更多实验来提升你的技能。