
베이즈 최적화의 개념적 이해
요약
베이즈 최적화의 개념을 수리적 모델과 NumPy 코드를 통해 설명합니다. 노이즈가 포함된 데이터에서 불확실성을 다루는 베이즈 추론의 원리와 RBF 커널, 획득 함수(Acquisition Function)의 역할을 다룹니다.
핵심 포인트
- 베이즈 추론을 이용한 노이즈 포함 데이터의 예측 원리 이해
- NumPy를 활용한 베이즈 최적화의 수리적 모델 구현
- RBF 커널의 정의와 코드 적용 방법
- 정보량을 극대화하기 위한 획득 함수(UCB 등)의 개념
베이즈 최적화를 어떻게 수리적 모델과 코드로 연결할지를 NumPy로 작성한 코드를 게시합니다.
**베이즈 최적화 (Bayesian Optimization)**에서는 베이즈 추론 (Bayesian Inference)을 수행하는 Noise 등의 하이퍼파라미터 (Hyperparameter)를 최적화하는 것을 가리킵니다.
**베이즈 추론 (Bayesian Inference)**이란 불확실성을 포함한 예측 모델입니다.
구체적인 예로 설문조사 최적화를 생각해 봅시다.
설문 항목을 어떻게 구성할지 고민할 때, 단순히 수집된 응답만을 바탕으로 다음 항목을 생각한다면, 예를 들어 적당히 설문 "같은" 답변을 한 사람이 있을 경우 이 결과가 명백히 악영향을 미칠 것이라고 생각합니다. 이를 해결하는 것이 **베이즈 추론 (Bayesian Inference)**의 구체적인 예입니다.
그럼, 문제 설정을 생각해 봅시다!
noise는 $\sigma \sim \mathcal{N}(0, 0.01)$로 설정되어 있습니다.
$$
y = \sin(2\pi{x}) + noise * \sqrt{0.01}
$$
이것으로 Noise를 포함한 데이터가 되었습니다.
이번에는 이 Noise를 추정하여 데이터가 어느 정도 범위에 있는지 등을 살펴보는 것이 목적입니다!
먼저 관측 데이터를 생성해 봅시다.
np.random.seed(42) # 재현성 확보를 위해 Seed 값 고정
train_x = np.linspace(0,1,100) # 0부터 1 사이에서 100개 지점 선택.
# 참 함수: sin(2*pi*x) 에 약간의 노이즈를 추가
...
그럼 시각화를 해봅시다!
# 베이즈 최적화 (Bayesian Optimization)의 Motivation은 이 노이즈가 포함된 데이터에서도 예측을 하고 싶다는 것입니다.
plt.title('노이즈가 어떻게 작용하는지 이해하기.')
plt.plot(train_x, train_y, label="실험 데이터 Plot")
...
출력 결과는 다음과 같습니다.
다음 출력 결과를 보면 알 수 있듯이, 역시 Noise가 들어가 있기 때문에 본래의 함수로부터 지그재그 형태로 어긋나 있습니다.
이 지그재그를 추정하는 것이 Motivation입니다.

베이즈와 떼려야 뗄 수 없는 것이 커널 함수 (Kernel Function)입니다.
이는 매우 편리하지만, 커널 트릭 (Kernel Trick) 등을 이해하면 좋겠지만, 아마 이 기사에는 다 적을 수 없으므로 추후 작성할 기사의 링크를 삽입해 두겠습니다.
이번에는 기본적인 RBF 커널 (RBF Kernel)을 사용합니다.
$$
RBF(x_1, x_2) = \sigma^2 \exp(\frac{|x_1 - x_2|^2}{2l^2})
$$
위와 같이 표현할 수 있습니다.
코드에서는 다음과 같이 작성합니다.
def rbf_kernel(x1, x2, output_scale, lengthsale):
sq_dist = (x1[:, None], x2[None, :])
return output_scale * np.exp(sq_dist **2 / 2 * lengthscale **2)
다음으로 획득 함수 (Acquisition Function)에 대해 설명하겠습니다.
획득 함수의 이미지는 $x_1$이라는 점을 선택했을 때, 정보량이 늘어나도록 $x_2$를 선택하는 것입니다. 그 선택을 기술하는 것입니다.
이번에는 UCB를 사용해 보겠습니다.
$\mu$는 평균, $\sigma$는 분산을 나타내며, $\beta$ 또한 하이퍼파라미터 (Hyperparameter)입니다.
$$
UCB(\x) = \mu + \beta \sigma
$$
코드에서는
def upper_confidence_bound(mu, std, beta=2.0)
return mu + beta * std
먼저 주변 로그 가능도 (Marginal Log-likelihood) 식을 기재하겠습니다. 유도는 LLM에게 물어보는 것을 추천합니다.
선형대수, 통계학 등 다양한 지식이 필요하여 즐겁습니다. $\theta$는 하이퍼파라미터 (Hyperparameter) (Noise, Lengthscale, outputscale)를 가리킵니다.
$$
log_p(y | X, \theta) = -\frac{1}{2}y^T\Sigma^{-1}y - \frac{1}{2}log|\Sigma| - \frac{N}{2}log(2 \pi)
$$
로 표현할 수 있습니다. 구현은 다음과 같습니다.
def negative_marginal_log_likelihood(paramas, x, y):
lengthscale, outputscale, noise = params
N = len(y)
...
베이즈 추론 (Bayesian Inference)에서는 사후 분산 (Posterior Variance), 사후 평균 (Posterior Mean)을 구함으로써 예측의 불확실성을 밝힙니다.
먼저 아래에서 사후 분산·평균이 산출됩니다.
사후 평균
$$
사후 평균
$$
\mu_{* } = K_{X_{*}X}(K_{XX} + ext{noise}^2 I)^{-1}y$$
mu_s = K_sX @ np.linalg.inv(K_XX + noise * np.eye(N)) @ train_y
사후 분산
$$
\Sigma_{* } = K_{x_{* }X}(K_{XX} + ext{noise}^2 I)^{-1}K_{XX}$$
sigma_s = K_ss - K_sX @ np.linalg.inv(K_XX + noise * np.eye(N)) @ K_sX.T
예측 전체 코드를 보겠습니다.
def predict(test_x, train_x, train_y, lengthscale, output_scale, noise):
N_train = len(train_x)
K_XX = rbf_kernel(train_x, train_x, outputscale, lengthscale)
...
여기서 최적화와 예측, 훈련을 진행합니다.
코드는 Appendix에 게재하겠지만, 여기서는 먼저 훈련 후의 그림을 보여드리겠습니다.
아래를 보시면 어느 정도 이해가 되시겠지만, 위는 훈련을 한 후의 가우시안 프로세스(Gaussian Process) 모델로 예측한 그림입니다.
이처럼 파란색으로 불확실성을 예측할 수 있으며, 관측점들 역시 이번에는 운 좋게 모두 불확실성으로 예측된 부분에 들어와 있습니다.
위에서 간단하게 설명드렸습니다.
이론적인 부분은 아마 향후 학습을 위해 작성해 나갈 예정이지만, Appendix에 코드를 전부 게재했으니 시간이 되시면 한번 실행해 보세요.
# %% [markdown]
# ## import
# %%
...
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기