본문 바로가기

ML with SckitLearn

[K-Means] K-평균 Clustering 알고리즘 이해

반응형

K-평균은 군집화(Clustering)에서 가장 일반적으로 사용되는 알고리즘입니다. K-평균은 군집 중심점(centroid)이라는 특정한 임의의 지점을 선택해 해당 중심에 가장 가까운 포인트들을 선택하는 군집화 기법입니다.

 

1. K-Means Algorithm 이해하기

군집 중심점은 선택된 포인트의 평균 지점으로 이동하고 이동된 중심점에서 다시 가까운 포인트를 선택, 다시 중심점을 평균 지점으로 이동하는 프로세스를 반복적으로 수행합니다. 모든 데이터 포인트에서 더이상 중심점의 이동이 없을 경우에 반복을 멈추고 해당 중심점에 속하는 데이터 포인트들을 군집화하는 기법입니다.

 

2. K-Means Algorithm  장점

  • 일반적인 군집화에서 가장 많이 활용되는 알고리즘입니다.
  • 알고리즘이 쉽고 간결

3. K-Means Algorithm  단점

  • 거리 기반 알고리즘으로 속성의 개수가 매우 많을 경우 군집화 정확도가 떨어집니다.
  • 반복을 수행하는데, 반복 횟수가 많을 경우 수행 시간이 매우 느려집니다.
  • 몇 개의 군집(Cluster)을 선택해야 할지 결정하기 어렵습니다.

 

4. 사이킷런 K-Means Class

사이킷런 패키지는 K-Means평균을 구현하기 위해 KMeans 클래스를 제공합니다. 전체 설명은 Scikit-Learn.org를 참고바랍니다.

from sklearn.cluster import KMeans

class sklearn.cluster.Kmeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=1, algorihtm='auto')
  • n_clusters: 군집화할 수, 즉 군집 중심점의 개수를 의미합니다.
  • init: 초기에 군집 중심점의 좌표를 설정할 방식을 말하며 보통은 임의로 중심을 설정하지 않고 일반적으로 k-means++방식으로 최초 설정합니다.
  • n_init: 서로 다른 군집 중심점(centroid)을 최초 셋팅한다.
  • max_iter: 최대 반복 횟수, 이 횟수 이전 모든 데이터의 중심점 이동이 없으면 종료

 

4. K-Means Algorithm Code Test

Iris Data를 3개의 그룹으로 Clustering하는 코드입니다. 이를 위해 n_cluster=3, init='k-means++', max_iter=300으로 설정한 Kmeans를 만들고 fit()을 수행하면 됩니다.

from sklearn.preprocessing import scale
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
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)
kmeans = KMeans(n_clusters=3, init='k-means++', max_iter=300, random_state=0)
kmeans.fit(irisDF)
print(kmeans.labels_)
print(kmeans.cluster_centers_)
print(kmeans.n_iter_)

 

Kmeans객체는 군집화 수행이 완료돼 군집화와 관련된 주요 속성을 알 수가 있습니다.

  • labels_ : 각 데이터 포인트가 속한 군집 중심점 레이블
  • cluster_centers_ : 각 군집 중심점 좌표. 이를 이용하면 군집 중심점 좌표가 어디인지 시각화할 수 있습니다.
  • n_iter_ : 수행된 이동 횟수

Kmeans객체는 각 군집을 구성하는 단어 피처가 군집의 중심(Centroid)을 기준으로 얼마나 가깝게 위치해 있는지 cluster_centers_라는 속성으로 제공합니다. cluster_centers_는 배열 값으로 제공되며, 행은 개별 군집을, 열은 개별 피처를 의미합니다. 각 배역 내의 값은 개별 군집 내의 상대 위치를 숫자 값으로 표현한 일종의 좌표 값입니다. 예를 들어 cluster_centers[0,1]은 0번 군집에서 두 번째 피처의 위치 값입니다.

 

labels_의 값이 0,1,2로 돼 있으며, 이는 각 레코드가 첫 번째 군집, 두 번째 군집, 세 번째 군집에 속함을 의미합니다.

#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(kmeans.labels_)
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 0 0 0 0 2 0 0 0 0
 0 0 2 2 0 0 0 0 2 0 2 0 2 0 0 2 2 0 0 0 0 0 2 0 0 0 0 2 0 0 0 2 0 0 0 2 0
 0 2]

#print(kmeans.cluster_centers_)
[[6.85       3.07368421 5.74210526 2.07105263]
 [5.006      3.428      1.462      0.246     ]
 [5.9016129  2.7483871  4.39354839 1.43387097]]
 
 #print(kmeans.n_iter_)
 3

 

 

이번에는 Iris Data의 품종 분류 값과 얼마나 차이가 나는지로 군집화가 효과적으로 되어 있는지 확인해보겠습니다.

결과적으로   target을  'setosa'=0,  'versicolor'=1,  'virginica'=2로 보고 setosa가 1번 그룹으로 잘 묶이고, versicolor가 2개의 그룹으로 묶이지만 2개는 0번 그룹으로 간다는 것을 의미합니다. 마지막으로 virginica는 0번과 2번 그룹이 혼합되어 있음을 의미합니다.

irisDF['target'] = iris_data.target
irisDF['cluster'] = kmeans.labels_
iris_result = irisDF.groupby(['target','cluster'])['sepal_length'].count()
print(iris_result)
#print(iris_result)
target  cluster
0       1          50
1       0           2
        2          48
2       0          36
        2          14

 

마지막으로 시각화를 위해 4개 속성을 가진 Iris데이타를 2차원 평면에 적합하게 만들기 의해 PCA를 이용해 4개의 속성을 2개로 차원축소한 뒤에 개별데이타로 나타내 보겠습니다.

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['cluster']==0].index
maker1_ind = irisDF[irisDF['cluster']==1].index
maker2_ind = irisDF[irisDF['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()
#print(irisDF)
	sepal_length  sepal_width  petal_length  ...  cluster     pca_x     pca_y
0             5.1          3.5           1.4  ...        1 -2.684126  0.319397
1             4.9          3.0           1.4  ...        1 -2.714142 -0.177001
2             4.7          3.2           1.3  ...        1 -2.888991 -0.144949
3             4.6          3.1           1.5  ...        1 -2.745343 -0.318299
4             5.0          3.6           1.4  ...        1 -2.728717  0.326755
..            ...          ...           ...  ...      ...       ...       ...
145           6.7          3.0           5.2  ...        0  1.944110  0.187532
146           6.3          2.5           5.0  ...        2  1.527167 -0.375317
147           6.5          3.0           5.2  ...        0  1.764346  0.078859
148           6.2          3.4           5.4  ...        0  1.900942  0.116628
149           5.9          3.0           5.1  ...        2  1.390189 -0.282661

[150 rows x 8 columns]

 

Clustering이 되었다고 하여 해당 Cluster가 정확한지 확신할 수 없기에 군집화가 잘 되었는지 확인할 수 있는 실루엣(Shilhouette Analysis)에 대해 알아보면 도움이 됩니다.

반응형