머신러닝에는 다양한 종류의 군집화(clustering) 알고리즘이 존재하며, 이러한 알고리즘은 모두 파이썬으로 구현할 수 있습니다. 이 글에서는 그중 하나인 평균 이동(Mean-Shift) 알고리즘을 파이썬으로 구현하는 방법을 살펴보겠습니다. 평균 이동 알고리즘은 비지도 학습(unsupervised learning) 기법으로 활용되는 대표적인 군집화 알고리즘입니다.
평균 이동 알고리즘이란?
평균 이동 알고리즘은 사전에 어떠한 통계적 가정도 두지 않는 비모수(non-parametric) 알고리즘입니다. 각 데이터 포인트를 데이터 밀도가 가장 높은 영역 방향으로 반복적으로 이동시키면서 군집에 할당하는 방식으로 작동합니다.
데이터 포인트가 가장 밀집된 지점을 해당 군집의 중심점(centroid)이라고 부릅니다. K-평균(K-means) 군집화와의 가장 큰 차이점은, K-평균에서는 군집의 개수를 미리 직접 지정해야 한다는 점입니다. 반면 평균 이동 알고리즘은 주어진 데이터 자체로부터 군집의 개수를 자동으로 찾아냅니다.
평균 이동 알고리즘의 동작 단계
- 각 데이터 포인트를 자기 자신만의 군집에 할당합니다.
- 각 군집의 중심점(centroid)을 계산합니다.
- 중심점의 위치를 반복적으로 갱신합니다.
- 중심점을 더 높은 밀도 영역 쪽으로 이동시킵니다.
- 중심점이 더 이상 이동할 수 없는 위치에 도달하면 알고리즘을 종료합니다.
scikit-learn을 활용한 구현 예제
아래는 파이썬의 scikit-learn 라이브러리를 사용해 평균 이동 알고리즘을 구현한 예제 코드입니다.
import numpy as np
from sklearn.cluster import MeanShift
import matplotlib.pyplot as plt
from matplotlib import style
style.use("ggplot")
from sklearn.datasets import make_blobs
centers = [[3,3,1],[4,5,5],[11,10,10]]
X, _ = make_blobs(n_samples=950, centers=centers, cluster_std=0.89)
plt.title("Mean-Shift Algorithm Implementation")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.scatter(X[:,0], X[:,1])
plt.show()
ms = MeanShift()
ms.fit(X)
labels = ms.labels_
clusterCent = ms.cluster_centers_
print(clusterCent)
numCluster = len(np.unique(labels))
print("Estimated clusters:", numCluster)
colors = 10*['r.','g.','b.','c.','k.','y.','m.']
for i in range(len(X)):
plt.plot(X[i][0], X[i][1], colors[labels[i]], markersize=3)
plt.scatter(clusterCent[:,0], clusterCent[:,1],
marker=".", color='k', s=20, linewidths=5, zorder=10)
plt.show()실행 결과
[[ 3.05250924 3.03734994 1.06159541] [ 3.92913017 4.99956874 4.86668482] [10.99127523 10.02361122 10.00084718]] Estimated clusters: 3
실행 결과를 보면, 알고리즘이 실제 중심값인 [3,3,1], [4,5,5], [11,10,10]에 매우 근접한 세 개의 군집 중심을 성공적으로 추정했으며, 군집 개수 역시 3개로 정확하게 예측한 것을 확인할 수 있습니다. 첫 번째 그래프는 생성된 데이터의 산점도를, 두 번째 그래프는 군집별로 서로 다른 색상이 적용된 최종 군집화 결과를 나타냅니다.
코드 설명
- 필요한 패키지들을 임포트하고, 사용 편의성을 위해 별칭(alias)을 정의합니다.
- 'style' 클래스의 'use' 함수에 'ggplot'을 지정하여 matplotlib 그래프 스타일을 설정합니다.
- 'make_blobs' 함수를 사용해 군집 형태의 샘플 데이터를 생성합니다.
- xlabel, ylabel, title 함수를 통해 X축, Y축 라벨과 그래프 제목을 지정합니다.
- 'MeanShift' 클래스를 호출해 모델 객체를 생성하고 변수에 할당합니다.
- fit 메서드로 데이터를 모델에 학습시킵니다.
- labels_ 속성으로 각 데이터의 군집 라벨을, cluster_centers_ 속성으로 군집 중심 좌표를 얻고, 고유한 라벨의 개수를 세어 군집 수를 계산합니다.
- 데이터를 산점도로 시각화하고, 학습된 군집화 결과도 함께 그래프로 표시합니다.
- 'show' 함수를 호출해 결과를 화면에 출력합니다.
참고로, 예전 버전의 scikit-learn에서 사용되던 sklearn.datasets.samples_generator 모듈은 현재 폐기(deprecated)되었으므로, 최신 버전에서는 위 코드처럼 sklearn.datasets에서 make_blobs를 직접 임포트하는 것이 좋습니다. 또한 평균 이동 알고리즘에서는 대역폭(bandwidth) 파라미터가 군집화 성능에 큰 영향을 미치므로, 필요에 따라 estimate_bandwidth 함수를 활용해 데이터에 적합한 값을 자동으로 설정할 수 있습니다.