본문 바로가기

Computer Science/Machine Learning

Hierarchical Clustering에 대하여

Clustering은 Unsupervised Learning의 주요 수단입니다. 최종 목표는 데이터셋 중에 서로 가까운 데이터 포인터 들 끼리 묶어 하위 그룹을 만드는 것에 있습니다. 이번 포스팅에서는 K-means clustering에 대한 내용을 다룹니다. 중요한 포인트는 K를 고르는 것인데, 이는 알고리즘을 적용하기 전에 결정해야합니다. 만약 정확히 얼마나 많은 clusters가 사용될지 예측할 수 없다면, hierarchical clustering이 이때 사용됩니다. 즉, 모든 데이터 포인트들을 거리가 0인 점으로 잡고, 거리를 늘려가는데 이때 두 cluster가 만난다면 둘을 하나의 cluster로 잡고 dendrogram에서 평행한 선을 그어 두 점을 잇습니다. 이 과정을 계속하면 cluster는 하나만 남게 됩니다.

 

이를 코드로 살펴보겠습니다. 다음과 같은 데이터 셋을 예시로 들겠습니다.

 

import numpy as np
import matplotlib.pyplot as plt

X = np.array([
    [5,3],
    [10,15],
    [15,12],
    [24,10],
    [30,30],
    [85,70],
    [71,80],
    [60,78],
    [70,55],
    [80,91]   
    ])

labelList = range(1,11)
plt.scatter(X[:,0], X[:,1])

 

X는 넘파이 배열입니다. labelList라는 변수는 라벨링에 사용됩니다.

plt.scatter(X[:,0], X[:,1])은 scatter plot을 하는데 x축은 X배열의 첫번째 column, y축은 X배열의 두번째 column이라는 지정입니다. 점의 색을 바꾸고 싶으면 c = [[R,G,B]] 값을 입력하면 됩니다. 마커 모양도 markers 인자로 바꿀 수있습니다.

 

 

Hierarchical clustering을 위해 각 점에 라벨링을 합니다. 아래와 같은 반복문을 추가합니다.

 

for j,label in enumerate(labelList):
    plt.annotate(
        label, xy=X[j],
        xytext=(4,1), textcoords='offset pixels')
plt.show()

 

enumerate() 가 반복문 안에 있음을 주의해주세요. 

이렇게 짜면 for label in labelList 역할도 하지만, j에 대해서도 반복문이 들어가므로 한번에 작성할 수 있다는 장점이 있습니다. 

xytext = horizontal, vertical로 점에서 얼마나 떨어진 곳에 라벨을 붙일건지,

textcoords = 픽셀 단위로 지정입니다.

실행하면 아래와 같은 scatter plot을 얻습니다.

 

 

 

Dendrogram을 그리기 위해 scipy 라이브러리를 호출합니다. 여기서는 linkage()와 dendrogram()이라는 함수를 사용합니다.

 

from scipy.cluster.hierarchy import dendrogram, linkage

X_linked=linkage(X)
dendrogram(X_linked, labels=labelList)
plt.show()

 

X_linked=linkage(X) 라는 함수 한줄로 hierarchical clustering이 완성됩니다.

dendrogram에는 linked 변수와 레이블 변수를 넣습니다. 색을 바꾸고 싶다면 괄호안에 지정합니다.

 

출력 결과는 아래와 같습니다.

 

 

그래프의 디자인에 관련된 인자는 아래 링크에서 확인할 수 있습니다:

https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.dendrogram.html 

 

scipy.cluster.hierarchy.dendrogram — SciPy v1.5.4 Reference Guide

Each of them is a list of lists. Let icoord = [I1, I2, ..., Ip] where Ik = [xk1, xk2, xk3, xk4] and dcoord = [D1, D2, ..., Dp] where Dk = [yk1, yk2, yk3, yk4], then the k’th link painted is (xk1, yk1) - (xk2, yk2) - (xk3, yk3) - (xk4, yk4).

docs.scipy.org

 

X_linked를 출력하면 위와 같은 숫자들이 뜹니다. 저기서 보이는 1,2,3,10 의 숫자들은 레이블들이 아니고 파이썬이 스스로 정한 0부터의 레이블입니다. 따라서 저 숫자 1 = 2번, 2 = 3번입니다. 처음으로 2와 3이 한 클러스터가 되었고, 그래서 마지막 숫자 2는 한 클러스터 안에 몇개의 레이블이 들어있는지를 나타내는 것입니다. 두번째 줄을 보면 3 = 4번과 10이 합쳐지는데, 10은 2번과 3번이 합쳐져서 만들어진 새로운 클러스터로 즉 11번입니다. 따라서 저 클러스터 안에는 3개의 레이블이 들어있다는 뜻입니다. 세번째 column의 실수들은 각 클러스터 간의 거리입니다.

이것이 linked 함수가 클러스터를 묶는 방식입니다.

 

d = dendrogram(X_linked, label=labelList)

 

다음 코드를 실행하면 많은 숫자들이 뜨는데 대부분은 plot의 수평 수직 그래프를 표현하는 숫자들입니다.그중에 마지막 부분 'leaves'에 주목해보겠습니다.

'leaves': [4, 0, 3, 1, 2, 8, 5, 9, 6, 7], 'color_list': ['C1', 'C1', 'C1', 'C1', 'C2', 'C2', 'C2', 'C2', 'C0']

파이썬에서 4와 0은 각각 5번과 1번이라는 뜻이므로 첫번째 list는 [5번, 1번, 4번, 2번, 3번, 9번, 6번, 10번, 7번, 8번]입니다. dendrogram의 X축과 같은 순서입니다.

'Computer Science > Machine Learning' 카테고리의 다른 글