머신러닝

1-1 Scikit-learn 에 의한 K-means clustering 비지도학습

coding art 2019. 9. 25. 19:21
728x90


아래의 K-means Clustering  코드를 돌려 보려면 필자의 졸저 "파이선 코딩 초보자를 위한 텐서플로우 OpenCV 머신 러닝" 의 1장 아나콘다 Back end 설치 편을 참조하기 바란다.

머신 러닝을 배우려는 파이선 코딩 초보자들이 가지게 될 확률이 높은 의문점들을


하나하나 찾아내어 실제 풀어보고 결과를 확인해볼 수 있는 머신 러닝!

인터넷 교보문고에서 450페이지19900원에 판매중입니다.











_______________________________________________________________________________________________________________



MNIST 수기 문자 판독이라든지 또는 Iris flowers 데이타 베이스를 사용하는 Classification 머신 러닝 문제들은 이미 정답을 알고 있는 기출문제들과 같은 성격의 지도 학습(Supervised Learning) 으로 분류된다. 지도 학습에서는 학습 데이터에 대한 정답을 알고 있으며 이 정답을 예를 들면 One-hot-code 로 엔코딩 처리하여 라벨 값을 부여하여 학습한 후에 별도의 통계학적 테스트(test or validation) 과정을 거치게 된다.

 

반면에 데이터는 있지만 Classification을 위한 정확한 라벨 값을 모르는 경우는 Grouping 작업 즉 Clustering 작업을 통해 Classification 처리를 하면서 라벨 값을 오히려 부여해야 한다. 클러스터링의 목적은 자연스럽게 데이터를 Grouping 하여 동일한 클러스터에 속하는 아이템들이라면 속성은 서로 비슷해야 하며 타 클러스터에 속한 아이템들의 속성과는 완전히 차별화 되어야 할 것이다.

 

이러한 목적 달성을 위해 클러스터링 작업에서 이미 잘 알려진 k-means 알고리듬을 사용하면서 클러스터별 아이템들의 속성이 유사함을 찾아내어 데이터의 계층적 클러스터 트리 구조를 세울 수 있어야 한다. K-means 알고리듬은 클러스터링 알고리듬 중에서도 아주 쉬우며 효율적인 기법으로서 계층구조형 (hiararchical)이나 밀도기반(density-based) 기법과는 대조적인 프로토타입 기반(prototype- based)의 클러스터링이다.

 

프로토타입이란 원형 또는 시제품 내지는 견본으로서 각 클러스터를 대표할 수 있는 중심(centroid, average) 이라든지 빈도수가 가장 높은 대푯값(medoid)을 의미하기도 한다. k-means 알고리듬은 공 모양의 클러스터를 찾아내는데 좋긴 하지만 처음부터 몇 개의 클러스터를 지정할 것인지 설정하고 들어가야 하는 약점도 있다. k 값을 잘못 선택하면 클러스터링이 엉망이 되기도 하는데 이럼 문제점 들을 해결하기 위한 엘보우 기법이나 실루엣 작도법도 차후에 소개하기로 한다.

 

K-meams 클러스터링은 고차원형 데이터에도 적용이 가능하지만 시각적인 이해를 돕기 위해서 Scikit-learn 라이브러리 모듈인 make_blobs 을 사용하면서 2차원형 데이터 예제를 살펴보자. blob 이란 비누방울처럼 방울들이 많이 생겼을 때 볼 수 있는 모양을 뜻한다.

 

다음 예제는 샘플 수가 150개이며 2개의 평면 좌표형 feature를 가지면서 센터를 3개로 처리하기로 한다. 클러스터의 표준 편차는 0.5 로 하고 데이터 순서는 셔플을 허용하기로 하며 랜덤성은 없다고 가정한다. 데이터를 import 한 후에 matplotlib 를 사용하여 작도해 보자. 머린 러닝 예제에서 데이터를 읽어 올 경우 대체로 학습용과 테스트용으로 나누는 것이 보통이다. 여기서도 X y 로 처리하는데 X는 라벨이 없는 데이터 인데 y 가 무엇인지 앞으로 알아보기로 한다.


이와 같이 작도된 데이터를 대상으로 k-means 알고리듬에 의해 샘플의 feature 간의 유사성을 찾아보도록 하자. 위 그림에서 3그룹으로 나뉘어진 각 샘플군의 (x1, x2) 좌표를 사용하여 3개의 중심을 계산하자. x1X[:, 0] 이며 x2X[:, 1]이 된다.

 

x 와 점 z 사이의 유클리드 거리 계산 공식을 살펴보자.



클러스털 별로 중심 μ가 계산되어 있다면 각각의 클러스터별로 샘플과 중심과의 거리의 합을 계산하여 합산하자. 아래 식에서 x μ는 벡터 성분이다. 인덱스 I 는 같은 클러스터에 속하는 점들을 뜻하며 인덱스 j 는 이미 계산해둔 중심의 좌표를 뜻한다. 점들과 중심이 같은 클러스터라면 웨이트 값이 1 이 되고 그렇치않으면 0 으로 둔다. 각 클러스터별 분산 값의 합을 계산하는 셈이며 SSE를 클러스터 이너셔(cluster inertia)라고 부른다..



KMeans 루틴을 사용하여 학습을 시켜 보자. Clustering에서 학습이란 각 클러스터 별로 랜덤하게 n-init 수만큼 seed를 선택하여 max_iter 수 이내에 최소값을 가지는 출력을 계산해 보는 일이다.

 



학습에 의해 km 이 얻어졌다면 즉 샘플 데이터군인 X를 사용하여 테스트를 해 보자. 이 부분은 중심을 찾기 위해 사용했던 셈플 데이터 X를 학습 후 다시 입력하여 확인하는 과정으로서 테스트나 validation 과정은 아니며 결과를 확인해 보기 위해서 색상별로 중심과 함께 작도해 보는 것이다.

 

만약 클러스터 수인 n_cluster 값을 1 이나 2를 입력하게 되면 엉뚱한 값이 얻어짐에 유의하자.


마지막으로 셸에서 y를 출력해 보면 클러스터링 작업 후 결정되는 라벨 값들인 0, 1,2 임을 알 수 있다.



#K-means_data_plot_01

from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt

## Grouping objects by similarity using k-means
## K-means clustering using scikit-learn

X, y = make_blobs(n_samples=150,
                  n_features=2,
                  centers=3,
                  cluster_std=0.5,
                  shuffle=True,
                  random_state=0)

plt.scatter(X[:, 0], X[:, 1],
            c='white', marker='o',
            edgecolor='black', s=100)
plt.grid()
plt.tight_layout()
plt.show()

km = KMeans(n_clusters=3, init='random', n_init=10, max_iter=300,
            tol=1e-04,random_state=0)

y_km = km.fit_predict(X)

plt.scatter(X[y_km == 0, 0],X[y_km == 0, 1], s=50, c='lightgreen',
            marker='s',edgecolor='black', label='cluster 1')
plt.scatter(X[y_km == 1, 0], X[y_km == 1, 1], s=50, c='orange',
            marker='o',edgecolor='black',label='cluster 2')
plt.scatter(X[y_km == 2, 0], X[y_km == 2, 1],s=50, c='lightblue',
            marker='v', edgecolor='black',label='cluster 3')
plt.scatter(km.cluster_centers_[:, 0], km.cluster_centers_[:, 1],
            s=250, marker='*', c='red', edgecolor='black',
            label='centroids')

plt.legend(scatterpoints=1)
plt.grid()
plt.tight_layout()
plt.show()