소개
이 실습에서는 파이썬의 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 에서 더 많은 실험을 통해 기술을 향상시킬 수 있습니다.