가우시안 믹스쳐 모델(GMM, Gaussian Mixture Model)

김승혁·2024년 11월 20일

가우시안 믹스쳐 모델(GMM, Gaussian Mixture Model)은 통계적 모델 중 하나로, 여러 개의 가우시안(정규) 분포가 혼합된 확률 모델입니다. 이 모델은 주어진 데이터가 여러 개의 서로 다른 그룹이나 군집으로 나눠질 수 있다고 가정하고, 각 그룹은 정규 분포를 따르는 확률 분포로 모델링됩니다. GMM은 비지도 학습의 일종으로, 주로 클러스터링에 사용됩니다.

1. GMM의 기본 개념

GMM은 데이터를 여러 개의 가우시안 분포가 혼합된 형태로 모델링합니다. 즉, 각 데이터 포인트는 여러 가우시안 분포 중 하나에서 생성된 것이라고 보고, 각 가우시안 분포에 대해 확률적인 가중치를 부여합니다. 이를 통해 GMM은 데이터가 여러 다른 분포에서 온 것처럼 설명할 수 있습니다.

GMM에서의 수학적 모델링은 다음과 같습니다:

  • 데이터 xxKK개의 가우시안 분포로 이루어진 혼합에서 생성됩니다.
  • 각 가우시안 분포는 평균 μk\mu_k와 공분산 Σk\Sigma_k로 정의됩니다.
  • 각 가우시안 분포에는 혼합 가중치 πk\pi_k가 주어집니다. πk\pi_k는 각 분포가 데이터에서 차지하는 비율을 나타내며, 모든 πk\pi_k의 합은 1이 됩니다.

전체 확률 밀도 함수는 다음과 같이 표현됩니다:
p(x)=k=1KπkN(xμk,Σk)p(x) = \sum_{k=1}^{K} \pi_k \mathcal{N}(x | \mu_k, \Sigma_k)
여기서 N(xμk,Σk)\mathcal{N}(x | \mu_k, \Sigma_k)kk-번째 가우시안 분포의 확률 밀도 함수이며, πk\pi_kkk-번째 분포의 혼합 가중치입니다.

2. GMM의 주요 요소

  • 가우시안 분포: GMM은 여러 개의 가우시안 분포(정규 분포)를 사용합니다. 각 분포는 고유한 평균과 공분산을 가집니다.
  • 혼합 가중치: 각 가우시안 분포는 데이터에서 차지하는 비율을 나타내는 가중치 πk\pi_k가 있습니다. 각 가중치의 합은 1입니다.
  • EM 알고리즘(Expectation-Maximization): GMM은 매개변수를 학습하기 위해 EM 알고리즘을 사용합니다. EM 알고리즘은 두 단계로 이루어집니다:
    1. E-step (Expectation): 현재 모델을 사용하여 각 데이터 포인트가 각 가우시안 분포에서 발생할 확률(후방 확률)을 계산합니다.
    2. M-step (Maximization): 후방 확률을 사용하여 가우시안 분포의 파라미터(평균, 공분산, 혼합 가중치)를 최대화합니다.

이 과정을 반복하여 모델 파라미터를 최적화하고, 최종적으로 GMM을 학습합니다.

3. GMM의 활용

  • 클러스터링: GMM은 K-means와 같은 다른 클러스터링 기법과 비교할 때, 각 클러스터가 단일 값으로 정의된다는 점에서 차별화됩니다. 대신, 각 클러스터가 하나의 가우시안 분포로 모델링되므로, 클러스터가 원형이 아닌 타원형으로 분포할 수 있습니다.
  • 밀도 추정: GMM은 데이터의 밀도 분포를 모델링하는 데도 사용됩니다. 특히 데이터가 여러 개의 가우시안 분포로부터 생성된 것으로 가정할 수 있는 경우 유용합니다.
  • anomaly detection(이상치 탐지): 데이터 포인트가 GMM의 모델에 맞지 않으면 이상치로 간주될 수 있습니다.

4. GMM의 장점과 단점

장점:

  • 데이터의 복잡한 구조를 잘 표현할 수 있으며, 비선형적인 군집도 잘 분리할 수 있습니다.
  • K-means처럼 고정된 형태의 군집을 강요하지 않으며, 타원형 클러스터를 모델링할 수 있습니다.

단점:

  • 가우시안 분포에 대한 가정이 데이터에 맞지 않으면 성능이 떨어질 수 있습니다.
  • 초기값 설정에 따라 결과가 달라질 수 있으며, EM 알고리즘은 지역 최적해에 수렴할 수 있습니다.
  • 높은 차원의 데이터에서 공분산 행렬을 추정하는 데 어려움이 있을 수 있습니다.

5. GMM과 K-means 비교

K-means와 GMM은 모두 클러스터링 기법이지만, K-means는 각 클러스터를 단일 중심점으로 모델링하는 반면, GMM은 각 클러스터를 가우시안 분포로 모델링하여 더 유연한 형태로 데이터를 설명합니다. GMM은 클러스터의 모양이 구형이 아닌 타원형일 수 있음을 허용합니다.

결론

GMM은 데이터가 여러 개의 가우시안 분포로 생성되었다고 가정하여, 각 데이터 포인트의 확률적 분포를 모델링하는 강력한 기법입니다. EM 알고리즘을 통해 가우시안 분포의 파라미터를 추정하고, 이를 기반으로 클러스터링 및 밀도 추정에 활용할 수 있습니다.


코드 예제

import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture
from sklearn.datasets import make_blobs

# 1. 데이터 생성 (3개의 클러스터)
X, y = make_blobs(n_samples=300, centers=3, cluster_std=1.0, random_state=42)

# 2. GMM 모델을 사용한 클러스터링
gmm = GaussianMixture(n_components=3, covariance_type='full', random_state=42)
gmm.fit(X)

# 3. 예측
labels = gmm.predict(X)

# 4. GMM의 각 클러스터의 평균과 공분산 행렬
print("Means of each cluster (Gaussian component means):")
print(gmm.means_)
print("\nCovariances of each cluster:")
print(gmm.covariances_)

# 5. 클러스터링 결과 시각화
plt.figure(figsize=(8, 6))

# 각 데이터 포인트의 클러스터 라벨에 따라 색을 다르게 설정
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', s=40, marker='o')

# GMM의 중심 (각 가우시안 분포의 평균)
centers = gmm.means_
plt.scatter(centers[:, 0], centers[:, 1], c='red', marker='x', s=200, label='Cluster Centers')

plt.title("GMM Clustering")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.legend()
plt.show()

코드 설명

  • make_blobs: 가상 데이터를 생성합니다. n_samples=300은 300개의 샘플을, centers=3은 3개의 중심점(클러스터)을 생성하도록 설정합니다.
  • GaussianMixture: GMM 모델을 생성하고 데이터를 학습합니다. n_components=3은 클러스터의 개수를 3으로 설정하고, covariance_type='full'은 각 클러스터에 대해 개별적인 공분산 행렬을 사용할 것을 지정합니다.
  • fit: 데이터를 GMM 모델에 맞춥니다.
  • predict: 각 데이터 포인트가 어느 클러스터에 속하는지 예측합니다.
  • 시각화: matplotlib을 사용해 클러스터링 결과를 시각화합니다. 각 데이터 포인트는 예측된 클러스터 라벨에 따라 색이 다르게 표시됩니다. 클러스터의 중심점은 빨간색 'X'로 표시됩니다.

콘솔 출력

Means of each cluster (Gaussian component means):
[[ 7.08100478  2.52735911]
 [-5.35609544 -1.45146362]
 [ 1.69237913 -4.73895272]]

Covariances of each cluster:
[[[ 1.1604558   0.08782266]
  [ 0.08782266  0.83819468]]

 [[ 1.04021971 -0.0438538 ]
  [-0.0438538   1.04343412]]

 [[ 0.98230092 -0.0326513 ]
  [-0.0326513   0.96989991]]]

결과 해석

  • 각 클러스터는 가우시안 분포를 따르며, gmm.means_는 각 클러스터의 평균 좌표를 보여줍니다.
  • gmm.covariances_는 각 클러스터의 공분산 행렬을 출력합니다. 이 행렬은 각 클러스터가 데이터를 어떻게 분포시키는지를 나타냅니다.
  • 시각화된 결과에서 각 색깔은 GMM이 예측한 클러스터를 나타내며, 빨간색 'X'는 각 클러스터의 평균 위치를 나타냅니다.

다양한 옵션

  • covariance_type='full': 각 클러스터가 고유한 공분산 행렬을 가진다고 가정합니다.
  • n_components=3: 데이터에서 3개의 클러스터를 찾을 것이라고 설정합니다. 이 값은 데이터에 맞는 적절한 클러스터 수로 조정할 수 있습니다.

GMM은 K-means와 달리 각 클러스터가 가우시안 분포로 모델링되기 때문에, 클러스터의 형태가 구형이 아니어도 잘 동작하며, 공분산 행렬을 통해 타원형 클러스터도 잘 처리할 수 있습니다.

클러스터 수 선택

실제로 데이터를 분석할 때는 클러스터의 개수를 미리 정하는 것이 어려울 수 있습니다. 이를 위해 AIC (Akaike Information Criterion)BIC (Bayesian Information Criterion)와 같은 평가 지표를 사용하여 최적의 클러스터 수를 선택할 수 있습니다.

n_components_range = range(1, 11)
bics = [GaussianMixture(n_components=n, random_state=42).fit(X).bic(X) for n in n_components_range]

plt.plot(n_components_range, bics, label="BIC")
plt.xlabel("Number of Components")
plt.ylabel("BIC")
plt.title("BIC for Different Numbers of Components")
plt.show()

이 코드를 통해 적합한 클러스터 수를 평가할 수 있습니다.


GMM으로 데이터 분석하기

from sklearn.mixture import GaussianMixture
import numpy as np

# pandas dataframe을 numpy array로 변환
data = df.values

# GMM 모델 생성 및 학습
gmm = GaussianMixture(n_components=N, random_state=42)
gmm.fit(data)

# 각 데이터 포인트가 속한 클러스터 예측
labels = gmm.predict(data)

# 각 데이터 포인트가 속한 클러스터 확률
probabilities = gmm.predict_proba(data)

# 결과 출력
print("Cluster Labels:\n", labels)
print("Cluster Probabilities:\n", probabilities)

적절한 클러스터 개수 NN를 찾는 것은 중요한 과정입니다. 이를 위해 다양한 방법이 있지만, 대표적으로 다음과 같은 두 가지 방법을 사용할 수 있습니다:

  1. 엘보우(Elbow) 방법:
    이 방법은 클러스터 개수를 증가시키면서 각 클러스터링의 비용(이 경우 Negative Log-Likelihood)을 계산하고, 이를 그래프로 그려 "팔꿈치" 모양을 찾는 것입니다. 팔꿈치 부분이 있는 지점을 최적의 클러스터 개수로 선택합니다.

  2. 실루엣 분석(Silhouette Analysis):
    실루엣 계수는 클러스터 내 데이터 포인트의 밀집도와 다른 클러스터와의 분리도를 평가합니다. 각 클러스터 개수에 대해 실루엣 계수를 계산하고, 평균 실루엣 계수가 가장 높은 클러스터 개수를 선택합니다.

다음은 이러한 방법을 사용하는 예제 코드입니다.

엘보우 방법

from sklearn.mixture import GaussianMixture
import matplotlib.pyplot as plt

def calculate_elbow(data, max_clusters):
    n_components = np.arange(1, max_clusters + 1)
    models = [GaussianMixture(n, random_state=42).fit(data) for n in n_components]
    plt.plot(n_components, [m.bic(data) for m in models], label='BIC')
    plt.plot(n_components, [m.aic(data) for m in models], label='AIC')
    plt.legend(loc='best')
    plt.xlabel('Number of Clusters')
    plt.ylabel('Information Criterion')
    plt.show()

data = df.values
calculate_elbow(data, 10)  # 최대 클러스터 개수를 10으로 설정

실루엣 분석

from sklearn.mixture import GaussianMixture
from sklearn.metrics import silhouette_score

def calculate_silhouette(data, max_clusters):
    silhouette_scores = []
    for n in range(2, max_clusters + 1):
        gmm = GaussianMixture(n, random_state=42).fit(data)
        labels = gmm.predict(data)
        score = silhouette_score(data, labels)
        silhouette_scores.append(score)
    plt.plot(range(2, max_clusters + 1), silhouette_scores)
    plt.xlabel('Number of Clusters')
    plt.ylabel('Silhouette Score')
    plt.show()

calculate_silhouette(data, 10)  # 최대 클러스터 개수를 10으로 설정

이 방법들을 사용하여 적절한 클러스터 개수를 선택하면, 데이터에 가장 잘 맞는 클러스터링 결과를 얻을 수 있습니다! 🚀 😊

profile
열심히 사는 척

0개의 댓글