개요
Gaussian 프로세스 회귀(Gaussian Process Regression, GPR)는 비선형 회귀 문제를 푸는 데 사용되는 강력한 비모수적 방법이다. Gaussian 프로세스는 기계 학습에서 함수로부터의 랜덤 변수를 모델링하며, 학습 데이터를 통해 새로운 입력 점에 대한 예측 분포를 제공한다. 이 장에서는 Cholesky 분해를 사용하여 Gaussian 프로세스 회귀 모델의 예측을 효율적으로 수행하는 방법을 설명한다.
Gaussian 프로세스 회귀의 기본 개념
Gaussian 프로세스는 모든 유한 집합의 점들이 다변량 정규 분포를 따른다고 가정한다. GPR 모델은 주어진 입력 데이터 \mathbf{X} = \{ \mathbf{x}_1, \mathbf{x}_2, \ldots, \mathbf{x}_n \}와 출력 데이터 \mathbf{y} = \{ y_1, y_2, \ldots, y_n \}를 사용하여 새로운 입력점 \mathbf{x}_*의 출력 y_*를 예측한다.
기본 모델
입력 데이터 \mathbf{X}에 대한 출력 데이터 \mathbf{y}는 다음과 같이 모델링된다:
여기서 f(\mathbf{X})는 Gaussian 프로세스로 모델링된 실제 함수이며, \mathbf{\epsilon} \sim \mathcal{N}(\mathbf{0}, \sigma_n^2 \mathbf{I})는 노이즈이다.
커널 함수
Gaussian 프로세스는 커널 함수 k(\mathbf{x}, \mathbf{x}')를 통해 입력 데이터 간의 상관성을 나타낸다. 커널 행렬 \mathbf{K}는 (k(\mathbf{x}_i, \mathbf{x}_j))로 구성되며, 여기서 각 k(\mathbf{x}_i, \mathbf{x}_j)는 두 입력점 \mathbf{x}_i와 \mathbf{x}_j 간의 커널 값이다.
확률 모델
Gaussian 프로세스 회귀 모델의 핵심은 주어진 데이터에 대해 새로운 입력점의 출력을 구하기 위해 다변량 정규 분포의 성질을 활용하는 것이다. 예측하려는 새로운 입력점 \mathbf{x}_*에 대해 다음의 결합 확률 분포를 고려한다:
여기서 \mathbf{k}_*는 \mathbf{k}_* = [k(\mathbf{x}_1, \mathbf{x}_*), \ldots, k(\mathbf{x}_n, \mathbf{x}_*)]^\top이다.
예측 (Prediction)
주어진 새로운 입력점 \mathbf{x}_*에 대한 출력 y_*의 예측 분포는 다음과 같이 구해진다:
Cholesky 분해를 사용하여 (\mathbf{K} + \sigma_n^2 \mathbf{I})의 역행렬을 계산하면 계산 효율성을 높일 수 있다.
Cholesky 분해를 이용한 효율적인 계산
Cholesky 분해는 대칭 양의 정부호 행렬 \mathbf{A}를 하삼각 행렬 \mathbf{L}과 그 전치 행렬 \mathbf{L}^\top로 분해하는 방법이다:
Gaussian 프로세스 회귀에서는 \mathbf{K} + \sigma_n^2 \mathbf{I}의 Cholesky 분해를 수행한다:
여기서 \mathbf{L}은 하삼각 행렬이다.
예측을 위한 Cholesky 분해 활용
Cholesky 분해를 사용하면 예측을 위한 계산을 효율적으로 수행할 수 있다. 다음의 단계를 따른다:
-
\mathbf{L}을 구한다: \mathbf{L} = \text{Cholesky}(\mathbf{K} + \sigma_n^2 \mathbf{I}).
-
하삼각 행렬 \mathbf{L}을 이용하여 (\mathbf{K} + \sigma_n^2 \mathbf{I})^{-1} \mathbf{y}를 다음과 같이 계산한다:
그렇게 해서 \mathbf{c} = (\mathbf{K} + \sigma_n^2 \mathbf{I})^{-1} \mathbf{y}를 얻는다.
- 예측 값을 계산한다:
- 예측 분산을 계산한다:
여기서 \mathbf{v}는 \mathbf{L} \mathbf{v} = \mathbf{k}_*를 통해 구한다.
이렇게 함으로써 예측 계산이 효율적으로 수행되며, 수치적으로도 안정적이다.
예제 코드
이제 Python을 사용하여 Gaussian 프로세스 회귀를 구현하는 예제를 소개하겠다. numpy 및 scipy 패키지를 사용하여 Cholesky 분해를 통합하는 방법을 설명한다.
import numpy as np
from scipy.linalg import cholesky, cho_solve
def kernel(X1, X2, length_scale=1.0, variance=1.0):
sqdist = np.sum(X1**2, 1).reshape(-1, 1) + np.sum(X2**2, 1) - 2 * np.dot(X1, X2.T)
return variance * np.exp(-0.5 / length_scale**2 * sqdist)
X_train = np.array([[-4], [-3], [-1], [0], [2], [3]])
y_train = np.sin(X_train).ravel()
length_scale = 1.0
variance = 1.0
noise = 1e-2
K = kernel(X_train, X_train, length_scale, variance) + noise**2 * np.eye(len(X_train))
L = cholesky(K, lower=True)
X_test = np.array([[-5], [-2], [1], [4]])
K_s = kernel(X_train, X_test, length_scale, variance)
alpha = cho_solve((L, True), y_train)
mean = np.dot(K_s.T, alpha)
v = cho_solve((L, True), K_s)
var = kernel(X_test, X_test, length_scale, variance) - np.dot(K_s.T, v)
print("예측 평균:", mean)
print("예측 분산:", var)
이 예제는 다음의 단계로 구성된다:
- 데이터 생성:
X_train
과y_train
에 데이터 점들을 생성한다. 이 예제에서는 \sin(x) 함수를 따르는 값들을 사용한다. - 커널 함수 정의: RBF 커널 함수는 두 입력 행렬 간의 커널 값을 계산한다.
- 커널 행렬 계산: 훈련 데이터의 커널 행렬을 계산하고, 거기에 노이즈를 추가한다.
- Cholesky 분해: 커널 행렬에 Cholesky 분해를 적용하여 하삼각 행렬 L을 얻는다.
- 새로운 입력점 생성:
X_test
변수에 새로운 입력점들을 추가한다. - 커널 벡터 계산: 새로운 입력점과 훈련 데이터 사이의 커널 벡터를 계산한다.
- \alpha 계산: 훈련 데이터의 출력값을 Cholesky 분해를 통해 변환하여 \alpha 값을 얻는다.
- 예측 계산: 예측의 평균과 분산을 계산한다.
Cholesky 분해의 장점
- 수치적 안정성: Cholesky 분해는 대칭 행렬의 양의 정부호를 보장하며, 수치적으로 더욱 안정적이다.
- 계산 효율성: 다른 O(n^3) 알고리즘에 비해 계산 시간이 절약된다.
- 메모리 절약: 행렬의 역을 직접 계산하지 않고 분해와 대입을 통해 결과를 얻을 수 있다.
이 장에서는 Gaussian 프로세스 회귀의 기본 원리와 Cholesky 분해를 통한 효율적인 예측 방법을 설명하였다. Gaussian 프로세스 회귀는 비선형 회귀 문제를 다루는 데 매우 강력한 도구이며, Cholesky 분해를 활용하면 계산 효율성과 수치적 안정성을 동시에 확보할 수 있다.
추가적인 주제로는 다양한 커널 함수, 하이퍼파라미터 최적화, 다변량 Gaussian 프로세스 회귀 등이 있을 수 있다. 이들의 심화된 이해는 학습 및 예측의 정밀도를 극대화하는 데 도움이 된다.