가우시안 프로세스 회귀: 커널 이해

Beginner

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

소개

이 실습에서는 파이썬의 Scikit-learn 라이브러리에서 Gaussian Process Regression (GPR) 에 사용되는 다양한 커널을 활용하는 방법을 보여줍니다. GPR 은 노이즈가 있는 데이터에 복잡한 모델을 적합시킬 수 있는 비모수적 회귀 기법입니다. 커널 함수는 두 입력 점 사이의 유사성을 결정하는 데 사용됩니다. 커널 함수의 선택은 데이터에 적합되는 모델의 형태를 결정하기 때문에 중요합니다. 이 실습에서는 GPR 에서 가장 일반적으로 사용되는 커널에 대해 다룰 것입니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습용 Jupyter Notebook에 접근할 수 있습니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사를 자동화할 수 없습니다.

학습 중 문제가 발생하면 Labby 에 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

라이브러리 가져오기

필요한 라이브러리를 가져옵니다.

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"Sampled function #{idx + 1}",
        )
    ax.plot(x, y_mean, color="black", label="Mean")
    ax.fill_between(
        x,
        y_mean - y_std,
        y_mean + y_std,
        alpha=0.1,
        color="black",
        label=r"$\pm$ 1 std. dev.",
    )
    ax.set_xlabel("x")
    ax.set_ylabel("y")
    ax.set_ylim([-3, 3])

Radial Basis Function 커널

Radial Basis Function(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("Radial Basis Function 커널", 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()

Exp-Sine-Squared 커널

Exp-Sine-Squared 커널은 다음과 같이 정의됩니다.

$$ 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("Exp-Sine-Squared 커널", 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()

Matérn 커널

Matérn 커널은 다음과 같이 정의됩니다.

$$ 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("Matérn 커널", fontsize=18)
plt.tight_layout()

요약

이 실험에서 파이썬의 사이킷런 라이브러리에서 가우시안 프로세스 회귀를 위해 다양한 커널을 사용하는 방법을 배웠습니다. GPR 에서 가장 일반적으로 사용되는 커널, 즉 방사 기저 함수 커널, 유리수 제곱근 커널, 지수 - 사인 - 제곱 커널, 내적 커널, Matérn 커널을 다뤘습니다. 또한 도우미 함수를 사용하여 가우시안 프로세스에서 추출된 샘플을 플롯하는 방법도 배웠습니다.

요약

축하합니다! 가우시안 프로세스 회귀: 커널 실험을 완료했습니다. LabEx 에서 더 많은 실험을 통해 기술을 향상시킬 수 있습니다.