본문 바로가기

ML with SckitLearn

[GMM] Gaussian Mixture Model 개요에 대해

반응형

GMM들어가기전!  가우시안 분포란?

도수 분포 곡선이 평균값을 중심으로 좌우 대칭을 이루는 것이다. 모든 측정에서 중복으로 실험했을 경우 결과 값이 완전 똑같이 이루어지는 경우는 거의 없으며, 약간의 오차를 수반하게 된다. 가우스는 측정오차의 분포에서 중요성을 강조하였고, 이를 가우스 분포, 오차분포라고 한다. 또한 이러한 곡선을 가우스 곡선이라 한다.

 


1. GMM(Gaussian Mixture Model) 개요

군집화를 적용하고자 하는 데이터가 여러 개의 가우시안 분포를 가진 데이터 집합들이 섞여서 생성된 것이라는 가정하에 군집화를 수행하는 방법

 

전체 데이터 세트는 서로 다른 정규 분포 형태를 가진 여러 가지 확률 분포 곡선으로 구성될 수 있으며, 이러한 서로 다른 정규 분포에 기반해 군집화를 수행하는 것이 GMM군집화 방법입니다.  예를 들어 여러개의 데이터 세트가 있다면 이를 구성하는 여러 개의 정규 분포 곡선을 추출하고, 개별 데이터가 이중 어떤 정규 분포에 속하는지 결정하는 방법입니다.

 

이런 방식을 GMM에서는 모수 추정이라고 하며 모수 추정은 대표적으로 2가지 추정을 합니다.

  • 개별 정규 분포의 평균과 분산

  • 각 데이터가 어떤 정규 분포에 해당되는지의 확률

이러한 모수 추정을 위해 GMM은 EM(Expectation and Maximization)방법을 적용하며 사이킷런에서는 GMM의 EM을 지원하기 위해 GaussianMixture클래스를 지원합니다.

 

 

2. GMM(Gaussian Mixture Model) Example

군집화를 적용하고자 하는 데이터가 여러 개의 가우시안 분포를 가진 데이터 집합들이 섞여서 생성된 것이라는 가정하에 군집화를 수행하는 방법

 

GaussianMixture의 가장 중요한 파라미터는 n_components로 gaussian mixture의 모델의 수를 나타냅니다. 전체 파라미터 내용은 이곳을 확인합니다. GaussianMixture객체의 fit과 predict를 수행해 군집을 결정합니다.

from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.mixture import GaussianMixture
import pandas as pd

iris_data = load_iris()
irisDF = pd.DataFrame(data=iris_data.data, columns=['sepal_length','sepal_width','petal_length','petal_width'])
print(irisDF)

gmm = GaussianMixture(n_components=3, random_state=0).fit(iris_data.data)
gmm_cluster_labels = gmm.predict(iris_data.data)
print(gmm_cluster_labels)
irisDF['gmm_cluster'] = gmm_cluster_labels
irisDF['target'] = iris_data.target

iris_result = irisDF.groupby(['target'])['gmm_cluster'].value_counts()
print(iris_result)
#print(irisDF)
     sepal_length  sepal_width  petal_length  petal_width
0             5.1          3.5           1.4          0.2
1             4.9          3.0           1.4          0.2
2             4.7          3.2           1.3          0.2
3             4.6          3.1           1.5          0.2
4             5.0          3.6           1.4          0.2
..            ...          ...           ...          ...
145           6.7          3.0           5.2          2.3
146           6.3          2.5           5.0          1.9
147           6.5          3.0           5.2          2.0
148           6.2          3.4           5.4          2.3
149           5.9          3.0           5.1          1.8

[150 rows x 4 columns]

#print(gmm_cluster_labels)
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 2 1
 1 1 1 2 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
 
 #print(iris_result)
 target  gmm_cluster
0       0              50
1       1              45
        2               5
2       2              50

결과로 Target 0은 cluster 0으로, Target 2는 cluster 1로 모두 잘 매핑됐습니다. Target 1만 일부가 cluster 2로 매핑이 되었습니다.

 

다시 K-means로 한 결과를 확인해보면 아래와 같습니다.

kmeans = KMeans(n_clusters=4, init='k-means++', max_iter=300, random_state=0).fit(iris_data.data)
kmeans_cluster_labels = kmeans.predict(iris_data.data)
irisDF['kmeans_cluster'] = kmeans_cluster_labels
iris_result = irisDF.groupby(['target'])['kmeans_cluster'].value_counts()
print(iris_result)
#print(iris_result)
target  kmeans_cluster
0       1                 50
1       3                 26
        2                 24
2       0                 32
        2                 17
        3                  1

 

이는 어떤 알고리즘에 더 뛰어나다는 의미가 아니라 Iris 데이타 Set은 GMM 군집화에 더 효과적이라는 의미입니다.

 

GMM은 확률 기반 군집화이며 K-Means는 거리 기반 군집화입니다. 그러므로 K-Means는 평균 거리 중심으로 중심을 이동하면서 군집화를 수행하는 방식이므로 개별 군집 내의 데이터가 원형으로 흡어져 있는 경우에 더 효과적입니다.

 

그래프로 나타내면..

pca = PCA(n_components=2)
pca_transformed = pca.fit_transform(iris_data.data)

irisDF['pca_x'] = pca_transformed[:,0]
irisDF['pca_y'] = pca_transformed[:,1]
print(irisDF)

maker0_ind = irisDF[irisDF['kmeans_cluster']==0].index
maker1_ind = irisDF[irisDF['kmeans_cluster']==1].index
maker2_ind = irisDF[irisDF['kmeans_cluster']==2].index

plt.scatter(x=irisDF.loc[maker0_ind,'pca_x'], y=irisDF.loc[maker0_ind, 'pca_y'], marker='o')
plt.scatter(x=irisDF.loc[maker1_ind,'pca_x'], y=irisDF.loc[maker1_ind, 'pca_y'], marker='s')
plt.scatter(x=irisDF.loc[maker2_ind,'pca_x'], y=irisDF.loc[maker2_ind, 'pca_y'], marker='^')

plt.xlabel('PCA 1')
plt.ylabel('PCA 2')
plt.title('3 Cluster Visualization by 2 PCA Components')
plt.show()
반응형