가우시안 믹스쳐 모델(GMM, Gaussian Mixture Model)은 통계적 모델 중 하나로, 여러 개의 가우시안(정규) 분포가 혼합된 확률 모델입니다. 이 모델은 주어진 데이터가 여러 개의 서로 다른 그룹이나 군집으로 나눠질 수 있다고 가정하고, 각 그룹은 정규 분포를 따르는 확률 분포로 모델링됩니다. GMM은 비지도 학습의 일종으로, 주로 클러스터링에 사용됩니다.
GMM은 데이터를 여러 개의 가우시안 분포가 혼합된 형태로 모델링합니다. 즉, 각 데이터 포인트는 여러 가우시안 분포 중 하나에서 생성된 것이라고 보고, 각 가우시안 분포에 대해 확률적인 가중치를 부여합니다. 이를 통해 GMM은 데이터가 여러 다른 분포에서 온 것처럼 설명할 수 있습니다.
GMM에서의 수학적 모델링은 다음과 같습니다:
전체 확률 밀도 함수는 다음과 같이 표현됩니다:
여기서 는 -번째 가우시안 분포의 확률 밀도 함수이며, 는 -번째 분포의 혼합 가중치입니다.
이 과정을 반복하여 모델 파라미터를 최적화하고, 최종적으로 GMM을 학습합니다.
장점:
단점:
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_는 각 클러스터의 공분산 행렬을 출력합니다. 이 행렬은 각 클러스터가 데이터를 어떻게 분포시키는지를 나타냅니다.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()
이 코드를 통해 적합한 클러스터 수를 평가할 수 있습니다.
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)
엘보우(Elbow) 방법:
이 방법은 클러스터 개수를 증가시키면서 각 클러스터링의 비용(이 경우 Negative Log-Likelihood)을 계산하고, 이를 그래프로 그려 "팔꿈치" 모양을 찾는 것입니다. 팔꿈치 부분이 있는 지점을 최적의 클러스터 개수로 선택합니다.
실루엣 분석(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으로 설정
이 방법들을 사용하여 적절한 클러스터 개수를 선택하면, 데이터에 가장 잘 맞는 클러스터링 결과를 얻을 수 있습니다! 🚀 😊