본문 바로가기
AI & 머신러닝 coding skill

머신러닝 Clustering - K-Means VS GMM

by 호빵님 2022. 5. 23.
반응형

K-Means VS GMM

K-Means 클러스터링은 군집화 범위가 원형입니다. 그러므로 데이터 세트의 분포가 원형에 가까울수록 효율이 높아집니다.

그러나 실제 데이터의 분포가 원형인 경우는 적습니다. 데이터의 분포가 만약 타원의 형태로 길쭉하게 늘어져 있다면 K-means 클러스터링은 해당 데이터에 대하여 제대로 군집화를 진행하기 어렵습니다.

이런 경우에는 데이터의 분포 방향에 따라 군집화를 진행하는 GMM 클러스터링을 사용하면 군집화 성능을 높일 수 있습니다.

임의의 데이터 생성

클러스터링 알고리즘을 테스트하기 위한 데이터 생성기를 사용해보겠습니다.

대표적으로 make_blobs() 를 사용합니다.
이를 이용해 타원형 분포를 가진 데이터를 만들어냅니다.


타원형 분포 데이터 생성을 위한 사이킷런 함수/라이브러리

  • make_blobs(n_samples, n_features, centers, cluster_std, random_state)
    • n_samples : 생성할 데이터의 총 개수
    • n_features : 데이터의 변수 개수, 시각화를 위해 보통 2개로 설정
    • centers : 군집의 개수
    • cluster_std : 데이터의 표준편차
    • random_state : 일관된 결과를 위한 설정값

 

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt

from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.mixture import GaussianMixture
from sklearn.datasets import make_blobs

from elice_utils import EliceUtils
elice_utils = EliceUtils()

"""
1. 지시 사항과 동일한 타원형 분포의 데이터를
   생성합니다.
   
   Step01. 타원형 분포의 데이터를 생성합니다.
           
           데이터의 개수는 300개,
           데이터 변수의 개수는 2개,
           군집의 개수는 3개,
           데이터의 표준편차는 0.8,
           random_state 는 0으로 설정합니다.
"""
# make_blobs()으로 데이터를 생성해보세요.
X, y = make_blobs(n_samples=300, n_features=2, centers=3, cluster_std=0.8, random_state=0)

# 데이터의 분포를 변형시키기 위해 transformation을 진행합니다.
transformation = [[0.60834549, -0.63667341],[-0.40887718,0.85253229]]
X_aniso = np.dot(X, transformation)

# 데이터 프레임 만들기 
clusterDF = pd.DataFrame(data = X_aniso, columns= ['ftr1','ftr2'])
clusterDF['target'] = y
target_list = np.unique(y)

# 생성된 데이터 시각화
def data_visualize():
    fig, ax = plt.subplots()
    plt.title('data')
    
    for target in target_list:
        target_cluster = clusterDF[clusterDF['target'] == target]
        ax.scatter(x = target_cluster['ftr1'], y = target_cluster['ftr2'])
    
    fig.savefig("plot.png")
    elice_utils.send_image("plot.png")
    
    
"""
2. K-Means 클러스터링을 수행하여
   클러스터링 결과를 데이터 프레임 내에 
   저장하는 함수를 완성합니다.
   
   Step01. 데이터 X_aniso에 대한 K-Means 
           클러스터링을 수행합니다.
           
           초기화 방식은 랜덤,
           군집의 개수는 3개, 
           random_state는 0으로 설정합니다.
           
    Step02. kmeans_label 변수에
            클러스터링 결과를 저장합니다.
"""
def K_means():
    
    k_means = KMeans(init = 'random', n_clusters =3, random_state=0)
    
    kmeans_label = k_means.fit(X_aniso).labels_
    
    clusterDF['kmeans_label']=kmeans_label
    
    # Kmeans 군집의 중심값을 뽑아 저장합니다.
    center = k_means.cluster_centers_
    
    # KMeans 군집 결과를 시각화합니다.
    unique_labels = np.unique(kmeans_label)
    fig, ax = plt.subplots()
    plt.title('K-Means')
    
    for label in unique_labels:
        label_cluster = clusterDF[clusterDF['kmeans_label'] == label]
        center_x_y = center[label]
        ax.scatter(x = label_cluster['ftr1'], y = label_cluster['ftr2'])
        ax.scatter(x = center_x_y[0], y = center_x_y[1], s = 70,color = 'k', marker = '$%d$' % label)
    
    fig.savefig("plot.png")
    elice_utils.send_image("plot.png")

    print("K-means Clustering")
    print(clusterDF.groupby('target')['kmeans_label'].value_counts())
    
    return kmeans_label
    
"""
3. GMM 클러스터링을 수행하여
   클러스터링 결과를 데이터 프레임 내에 
   저장하는 함수를 완성합니다.
   
   Step01. 데이터 X_aniso에 대한 
           GMM 클러스터링을 수행합니다.
           
           군집의 개수는 3개, 
           random_state는 0으로 설정합니다.
           
   Step02. gmm_label 변수에
           클러스터링 결과를 저장합니다.
            
"""
def GMM():
    
    gmm = GaussianMixture(n_components=3, random_state=0)
    
    gmm_label = gmm.fit_predict(X_aniso)
    
    clusterDF['gmm_label']=gmm_label
    
    unique_labels = np.unique(gmm_label)
    
    # GMM 군집 결과를 시각화합니다.
    fig, ax = plt.subplots()
    plt.title('GMM')
    
    for label in unique_labels:
        label_cluster = clusterDF[clusterDF['gmm_label'] == label]
        plt.scatter(x = label_cluster['ftr1'], y = label_cluster['ftr2'])
    
    fig.savefig("plot.png")
    elice_utils.send_image("plot.png")
    
    print("Gaussian Mixture Model")
    print(clusterDF.groupby('target')['gmm_label'].value_counts())
    
    return gmm_label

def main():
    data_visualize()
    K_means()
    GMM()

if __name__ == "__main__":
    main()

 

원본 데이터

 

 

 

 

*본 포스팅은 DX기업교육 플랫폼인 Elice academy의 머신러닝 심화 과정에서 실습한 코드를 이용해서 작성되었습니다.

https://elice.io/

 
 
 

올인원 디지털 교육 플랫폼 - 엘리스

우리 모두를 위한 교실, 엘리스와 함께 더 나은 기회를 만들어보세요

elice.io

 

 

반응형