클러스터링은 사실 비지도학습에서 "뭉쳐있는 것끼리 그룹화하는 거 아니야?" 라는 단순한 개념으로만 이해하고 있었다. 하지만 최근에 공부하면서 몇 가지 새로운 개념을 알게 되어서 간단하게 정리해보고자 한다.
참고한 자료는 많은데, 본 포스팅에서 중점적으로 다룰 책은 잘 알려진 '공룡책'의 군집화 파트이다.
https://www.yes24.com/Product/Goods/69752484
클러스터링 (군집화)
클러스터링, 우리말로 군집화라고 부르는 작업은 비지도학습 중 가장 대표적인 방법이다. 주로 라벨이 없는 데이터들에 라벨을 부여하고 싶을 때 많이 사용하고, 또 성능도 꽤 나쁘지 않은 것으로 보인다. (여러 경진대회에서 활발하게 사용됨.) 클러스터링을 정의하자면 '비슷한 특징을 갖는 데이터끼리 클러스터를 중심으로 그룹화하는 과정' 정도가 되겠다.
우리 교수님께선 클러스터링에서 알아야할 개념으로 총 4가지를 꼽으셨다.
1. 유사도와 거리 측정
2. 비모수통계 알고리즘 (nonparametric algorithms) Ex : k-means, k-medoids
3. 계층적 군집화 (hierarchical clustering)
4. 클러스터링 평가
4가지 주제를 다 다루기엔 너무 길어져서 이번 포스팅에선 알고리즘적인 면들만 다루어보고자 한다. 그래서 K-평균, 계층적 군집화에 밀도 기반 군집화까지 총 3가지의 클러스터링의 접근법에 대해 간단하게 정리하려고 한다.
K-Means, K-평균 알고리즘
클러스터링에서 가장 먼저 배우는 K-평균 알고리즘이다.
https://shabal.in/visuals/kmeans/1.html
위 사이트는 K-means 알고리즘이 어떻게 작동하는지를 아주 간단명료하게 보여준다.
작동 원리를 글로 표현하면 다음과 같다.
1. 사전에 몇 개의 그룹(클러스터)로 묶을 것인지를 설정한다. (K를 설정한다.)
2. 설정한 K의 크기에 맞춰 임의의 데이터를 클러스터의 중심점으로 설정한다. or 임의의 위치에 중심점을 설정한다.
3. 중심점들을 기반으로 데이터들을 가장 가까운 중심점에 배정하여 그룹화한다.
4. 그룹화가 끝나면 그룹의 중심으로 중심점들을 옮긴다.
5. 옮겨진 중심점과 데이터들 간의 거리를 다시 계산한다. 가까운 거리에 있는 중심점이 속한 클러스터로 데이터들이 옮겨간다.
6. 3,4,5 번을 결과의 변화가 없을 때까지 반복한다.
공룡책의 저자는 클러스터링의 장점으로 쉽고 간결하다는 점을, 단점으로 속성의 갯수나 데이터의 수에 따라 성능이 떨어질 수 있음을 지적하셨다. 또한 K를 직접 설정해줘야 한다는 점도 부담으로 다가올 수 있다고 짚으셨다.
가령 위와 같은 분포를 띄는 데이터가 있다고 가정하자. 본 그림을 만든 분은 클러스터를 2로 설정하였다. 그러나 과연 누가 클러스터의 개수는 2라고 분포만 보고 단언할 수 있을까? 실제 데이터의 분포는 그렇게 명확하지 않은 경우가 훨씬 많기 때문에, 이 K를 설정하는 것이 하나의 과제라고 볼 수 있다.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
# Generate synthetic data
n_samples = 300
n_features = 2
n_clusters = 3
random_state = 42
X, _ = make_blobs(n_samples=n_samples, n_features=n_features, centers=n_clusters, random_state=random_state)
# Create a K-means clustering model
kmeans = KMeans(n_clusters=n_clusters, random_state=random_state)
# Fit the model to the data
kmeans.fit(X)
# Get cluster assignments for each data point
labels = kmeans.labels_
# Get cluster centers
cluster_centers = kmeans.cluster_centers_
# Plot the data points and cluster centers
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.scatter(cluster_centers[:, 0], cluster_centers[:, 1], s=30, c='red')
plt.title('K-means Clustering')
plt.show()
K-means는 싸이킷런에서 제공하고 있다.
여담으로 얼마 전 데이콘에서 진행한 쇼츠 대회에서K-Means 클러스터링을 사용한 적이 있는데, 이건 다른 포스팅에서 다뤄보도록 하겠다.
계층적 클러스터링 (Heirarchical clustering)
계층적 클러스터링은 Recursive한, 즉 재귀적인 접근법이다. 알고리즘을 공부하신 분들이라면 '재귀'라는 단어에 치를 떨 수도 있다. (나처럼) 하지만 계층적 클러스터링은 오히려 단순하다 평가받는 K-means 보다 단순한 면이 있다.
계층적 클러스터링을 사용하려면 위와 같은 덴드로그램이라는 그림을 그려야한다. 덴드로그램을 그리는 원리도 간단한데, 그냥 거리가 가장 가까운 데이터들부터 우선적으로 이어나가면서 그리면 된다. (아래그림 참조)
이렇게 덴드로그램을 그리고 나면, cutoff 를 설정하여 클러스터를 정의할 수 있어진다.
cutoff를 거리 12로 설정했을 때의 모습이다. (빨간선이 cutoff line) 보이는 바와 같이 클러스터가 3개로 나뉘어짐을 확인할 수 있다.
계층적 클러스터링의 장점은 우선 과정과 결과를 해석하기 쉽고, 사용자가 클러스터의 개수를 선언하는 데에 부담이 없다는 것에 있다. 하지만 단점으로는 K-means보다도 계산적 소요가 크다는 점이 있다.
DBSCAN 알고리즘 (밀도기반 클러스터링)
밀도 기반 군집화에도 여러 알고리즘이 있지만 가장 대표적인 것은 DBSCAN, Density Based Spatial Clustering of Applications with Noise 가 있다. DBSCAN도 앞선 클러스터링 기법들처럼 간단하고 직관적이지만, 강력한 장점 하나를 갖고 있는데 바로 기하학적으로 복잡한 분포에 유리하다는 것이다.
공룡책에 자세한 기법이 설명되어 있는데, 입실론 반경 등의 용어들이 다소 어렵게 느껴질 수도 있다. 그래서 내가 이해한 대로 아주 쉽게 풀어서 정리하고자 한다.
1. 한 데이터를 기점으로 일정 크기의 원을 그린다.
2. 원 안에 들어오는 데이터의 개수가 많으면 그 자체로 클러스터가 된다.
3. 그 클러스터 안에 들어오는 데이터들에 같은 작업을 반복한다.
4. 추가로 클러스터에 들어오는 데이터들이 없다면, 1개의 클러스터가 완성된 것이다.
5. 클러스터에 들어오지 않은 다른 데이터들에 대해 같은 작업을 반복한다.
1,2,3,4에 해당하는 과정이 빨간색 영역이다. 노란색으로 표시된 데이터영역은, 클러스터에 포함되긴 하지만 추가적으로 다른 데이터들이 자신의 범위 안에 없으므로 클러스터의 border, 즉 경계라고 부른다. 파란색은 클러스터에 아예 포함되지 못 했으므로, 또 다른 클러스터를 구성할 것이다.
이렇게 가까이만 있으면 무조건 같은 클러스터로 본다는 점에서 기하학적으로 복잡한 분포의 데이터들도 쉽게 클러스터링할 수 있는 것이다.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_moons
# Generate synthetic data (you can replace this with your own dataset)
X, _ = make_moons(n_samples=200, noise=0.05, random_state=0)
# Create a DBSCAN clustering model
dbscan = DBSCAN(eps=0.3, min_samples=5)
# Fit the model to the data
dbscan.fit(X)
# Get cluster assignments for each data point (-1 indicates noise)
labels = dbscan.labels_
# Visualize the clusters
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.title('DBSCAN Clustering')
plt.show()
위처럼 데이터의 분포가 뭉쳐는 있는데 모양이 원이 아니라 타원, 반원 등의 형태를 띄고 있으면, K-Means나 계층적 알고리즘을 적용하기가 상당히 불편할 것이다. (가까운 거리순으로 판단하기 때문에, 다른 클러스터임에도 같은 클러스터로 인식할 경우가 흔할 것이다.) 따라서 이런 경우에는 밀도 기반의 클러스터링을 진행하는 것이 좋을 것이다. 다만 현실데이터셋에서 이런 경우가 얼마나 있을지는 의문이다.
이렇게 세 가지 클러스터링 기법에 대해 간단하게 정리해보았다. 계층적 클러스터링은 책에는 없는 내용인데 정확히는 강의자료의 출처인 다음 책에 있다. https://web.stanford.edu/class/bios221/book/
'머신러닝' 카테고리의 다른 글
머신러닝 - ROC Curve에 대한 확장 : 임계값 (0) | 2023.12.13 |
---|---|
분류 평가 지표 정리 - F1 score, ROC Curve 등 (2) | 2023.10.18 |
머신러닝 - 분류모델 평가지표 (Precision, Recall, Accuracy) + 1종, 2종오류 정리 (0) | 2023.07.15 |
머신러닝 - Naive Bayes Classifier(분류) 정리 (0) | 2023.06.17 |
머신러닝 - Regularization 과 LASSO, Ridge 정리 (0) | 2023.06.09 |