다운로드
작성자: admin 작성일시: 2017-08-01 16:57:50 조회수: 2107 다운로드: 117
카테고리: 머신 러닝 태그목록:

가우시안 혼합 모형과 EM 방법

가우시안 혼합 모형

실수값을 출력하는 확률변수 X가 사실 눈에 보이지 않는(관측되지 않는) K-클래스 카테고리 확률변수 Z의 값에 따라 다른 기댓값과 분산을 가지는 복수의 가우시안 정규 분포들로 이루어진 모형을 가우시안 혼합(Gaussian Mixture) 모형이라고 한다.

$$ p(x) = \sum_Z p(z)p(x|z) = \sum_{k=1}^{K} \theta_k \mathcal{N}(x|\mu_k, \Sigma_k) $$
  • $p(x)$ : 전체 분포
  • $p(x|z)$ : 혼합 모형의 각 성분(component)이 되는 개별적인 연속 확률분포. 여기에서는 가우시안 정규 분포
  • $p(z)$ : 카테고리 확률분포
  • $\theta_k$: 카테고리 확률분포의 모수. 모든 성분 중 특정한 $Z$가 선택될 확률
  • $\sum\theta_k = 1$ : 카테고리 확률분포의 모수 제한 조건

베르누이-가우시안 혼합 모형

카테고리가 두 개인 가우시안 혼합 모형은 베르누이-가우시안 혼합 모형(Bernouilli Gaussian-Mixuture Model)이라고 한다.

다음은 2개의 카테고리와 2차원 가우시안 정규 분포를 가지는 가우시안 혼합 모형 데이터의 예이다.

In [2]:
from numpy.random import randn

n_samples = 500

mu1 = np.array([0, 0])
mu2 = np.array([-6, 3])
sigma1 = np.array([[0., -0.1], [1.7, .4]])
sigma2 = np.eye(2)

np.random.seed(0)
X = np.r_[1.0 * np.dot(randn(n_samples, 2), sigma1) + mu1,
          0.7 * np.dot(randn(n_samples, 2), sigma2) + mu2,
         ]
plt.scatter(X[:, 0], X[:, 1], s=5)
plt.show()

가우시안 혼합모형과 모수 추정과 내재변수모형

데이터로부터 가우시안 혼합모형의 모수를 추정한다는 것은 그 카테고리 분포의 모수 및 각 카테고리에서의 가우시안 정규 분포 모수를 모두 추정하는 것을 말한다. 이 때 어려운 점은 likelihood 함수가 선형대수 방법으로 쉽게 구할 수 없는 복잡한 형태를 가진다는 점이다.

$N$개의 데이터에 대한 $X$의 결합 확률 분포, 즉 likelihood 는 다음과 같다.

$$ \prod_{i=1}^N p(x_i) = \prod_{i=1}^N \sum_{z_i} p(z_i)p(x_i|z_i) = \prod_{i=1}^N \sum_{k=1}^{K} \theta_k \mathcal{N}(x_i|\mu_k, \Sigma_k)$$

Log likelihood는 다음과 같아진다.

$$ LL = \sum_{i=1}^N \log \left( \sum_{k=1}^{K} \theta_k \mathcal{N}(x_i|\mu_k, \Sigma_k) \right) $$

미분값이 0이 되는 모수값을 쉽게 구할 수 있는 형태가 아니라는 것을 알 수 있다.

만약 데이터 $x_i$가 어떤 카테고리 $z_i$에 속하는지를 안다면 그에 해당하는 가우시안 정규 분포 함수

$$p(X=x_i|Z=z_i) = \mathcal{N}(x_i |\mu_{z_i}, \Sigma_{z_i})$$

를 사용하여 로그 함수 내부의 덧셈이 없어지고 likelihood 함수를 쉽게 정의할 수 있을 것이다. 하지만 실제로는 데이터 $x_i$가 가지고 있는 카테고리 값 $z_i$를 알 수가 없기 때문에 likelihood 함수가 위와 같이 로그 함수의 내부에 덧셈이 들어가는 복잡한 비선형 함수가 된다.

이렇게 관측 데이터가 보이지 않는, 즉 내부에 숨겨진(latent) 확률 변수를 포함하는 모형을 내재변수모형(latent variable model)이라고 한다. 내재변수는 카테고리값도 될 수 있고 실수값도 될 수 있다. 혼합모형은 카테고리값인 내재변수를 가지는 내재변수 모형이라고 할 수 있다.

EM(Expectation-Maximization)

혼합모형의 모수추정에서 중요한 역할을 하는 것 중의 하나가 바로 각 데이터가 어떤 카테고리에 속하는가를 알려주는 조건부 확률 $p(z|x)$ 값이다. 이 값을 responsibility라고 한다.

$$ \begin{eqnarray} \gamma_{ik} &=& p(z_i=k|x_i) \\ &=& \dfrac{p(z_i=k)p(x_i|z_i=k)}{p(x_i)} \\ &=& \dfrac{p(z_i=k)p(x_i|z_i=k)}{\sum_{k=1}^K p(x_i,z_i=k)} \\ &=& \dfrac{p(z_i=k)p(x_i|z_i=k)}{\sum_{k=1}^K p(z_i=k)p(x_i|z_i=k)} \end{eqnarray} $$

가우시안 혼합 모형의 경우 다음과 같이 정리할 수 있다.

$$ \gamma_{ik} = \dfrac{\theta_k \mathcal{N}(x_i|\mu_k, \Sigma_k)}{\sum_{k=1}^K \theta_k \mathcal{N}(x_i|\mu_k, \Sigma_k)} $$

이 식은 모수로부터 responsibility를 추정한다.

$$ (\theta_k, \mu_k, \Sigma_k) \;\; \implies \;\; \gamma_{ik} $$

$\gamma_{ik}$는 $i$번째 데이터 $x_i$가 카테고리 $k$에서 만들어졌을 확률을 나타낸다.

위에서 구한 log likelihood 함수를 $\mu_k$로 미분하여 0이 되도록 하는 방정식을 만들면 다음과 같다.

$$ 0 = - \sum_{i=1}^N \dfrac{p(z_i=k)p(x_i|z_i=k)}{\sum_{k=1}^K p(z_i=k)p(x_i|z_i=k)} \Sigma_k (x_i - \mu_k ) $$

이를 정리하면,

$$ \sum_{i=1}^N \gamma_{ik} (x_i - \mu_k ) = 0$$$$ \mu_k = \dfrac{1}{N_k} \sum_{i=1}^N \gamma_{ik} x_i $$

위 식에서 $$ N_k = \sum_{i=1}^N \gamma_{ik} $$

이고 $k$ 카테고리에 속하는 데이터의 수와 비슷한 의미를 가진다. 즉 $\mu_k$는 $k$카테고리에 속하는 데이터의 샘플 평균과 같의 의미이다.

마찬가지로 log likelihood를 $\Sigma_k$로 미분하여 최대화하는 모수값을 구하면 다음과 같다.

$$ \Sigma_k = \dfrac{1}{N_k} \sum_{i=1}^N \gamma_{ik} (x_i-\mu_k)(x_i-\mu_k)^T $$

마지막으로 log likelihood를 $\theta_k$로 미분하여 최대화하는 모수값을 구해야 하는데 이 때 카테고리값의 모수가 가지는 제한 조건으로 인해 Lagrange multiplier 를 추가해야 한다.

$$ LL + \lambda \left(\sum_{k=1}^K \theta_k - 1 \right) $$

이를 $\theta_k$로 미분하여 0이 되는 값을 찾으면 다음과 같다.

$$ \theta_k = \dfrac{N_k}{N} $$

이 세가지 식은 모두 responsibility로부터 모수를 구하고 있다.

$$ \gamma_{ik} \;\; \implies \;\; (\theta_k, \mu_k, \Sigma_k ) $$

원래는 연립방정식의 해를 구하는 방법으로 responsibility를 포함한 모수값을 추정해야 한다. 그러나 만약 식의 형태가 responsibility를 알고 있다면 모수를 추정하는 것이 간단하도록 만들어져 있기 때문에 EM(Expectation-Maximization)이라고 하는 iterative 방법을 사용하면 연립방정식의 해를 구하는 것보다 더 쉽게 모수를 추정할 수 있다.

EM 방법은 모수와 responsiblity를 번갈아 추정하며 정확도를 높여가는 방법이다.

  • E step 에서는 우리가 현재까지 알고 있는 모수가 정확하다고 가정하고 이를 사용하여 각 데이터가 어느 카테고리에 속하는지 즉, responsiblity를 추정한다.
$$ (\theta_k, \mu_k, \Sigma_k) \;\; \implies \;\; \gamma_{ik} $$
  • M step 에서는 우리가 현재까지 알고 있는 responsibility가 정확하다고 가정하고 이를 사용하여 모수값을 추정한다.
$$ \gamma_{ik} \;\; \implies \;\; (\theta_k, \mu_k, \Sigma_k) $$

이를 반복하면 모수와 responsibility를 동시에 점진적으로 개선할 수 있다.

클러스터링

각각의 데이터에 대해 responsibility을 알게되면 responsibility가 가장 큰 카테고리를 찾아내어 그 데이터가 어떤 카테고리에 속하는지를 알 수 있다. 즉 클러스터링을 할 수 있다.

$$ k_i = \arg\max_{k} \gamma_{ik} $$

사실 K-means clustering은 EM 방법의 특수한 경우라고 볼 수 있다.

Scikit-Learn의 GaussianMixture 클래스

In [3]:
from sklearn.mixture import GaussianMixture
In [4]:
model = GaussianMixture(n_components=2, init_params='random', random_state=0, max_iter=1)
model.fit(X)
Out:
GaussianMixture(covariance_type='full', init_params='random', max_iter=1,
        means_init=None, n_components=2, n_init=1, precisions_init=None,
        random_state=0, reg_covar=1e-06, tol=0.001, verbose=0,
        verbose_interval=10, warm_start=False, weights_init=None)
In [5]:
gamma = model.predict_proba(X)
In [6]:
plt.scatter(X[:, 0], X[:, 1], s=50, linewidth=1, edgecolors="b", cmap=plt.cm.binary, c=gamma[:, 0])
plt.show()
In [7]:
def plot_gaussianmixture(n, k=10):
    model = GaussianMixture(n_components=2, init_params='random', random_state=1, tol=1e-9, max_iter=n)
    model.fit(X)
    gamma = model.predict_proba(X)
    plt.scatter(X[:, 0], X[:, 1], s=50, linewidth=1, edgecolors="b", cmap=plt.cm.binary, c=gamma[:, 0])
    plt.show()
    return model
In [8]:
plot_gaussianmixture(5);