비지도 학습 방법 K-means 군집화 기술 이해와 K 초기화 방법들
K-means 알고리즘은 비지도 학습 Unsupervised Learning 방법 중 하나로 군집화 Clustering 문제를 풀기 위한 기술 중 하나 입니다. 명칭에서처럼 데이터를 평균값을 기반으로 K 개의 유사한 그룹으로 묶어주는 방법입니다. 계산 복잡도가 낮아 처리 속도에서 빠른 편에 속하며 원형 형태의 군집을 구분할 때 적합합니다. 다양하고 복잡한 형태의 군집에 적용은 한계가 있으며, 군집 수 K는 자동 결정이 아닌 사전에 결정해야 할 변수 입니다.
단계별 작동 원리는 간단합니다.
1) 초기값 K개 중심점 선택 또는 특정 방식으로 초기화
2) 각 데이터 포인트를 Euclidean Distance 기반하여 가장 가까운 중심점 할당
3) 각 군집(Cluster)에 속한 모든 데이터의 평균값 계산 및 중심점 업데이트
4) 더 이상 중심점이 변화하지 않거나 지정된 반복 횟수를 만족할 때까지 반복
그림에서처럼 초기점이 C1과 C2라면 각 포인트 별 거리 계산을 통해 평균값을 업데이트 하면 초기점들은 우측 그림에서처럼 각 군집에 중심으로 이동하게 됩니다.
K-means에서는 군집수 K가 제대로 설정되느냐에 따라 성능을 좌우합니다. 사전에 군집수를 알고 있으면 좋겠지만 대부분 알지 못하기 때문에 적절한 K를 찾아야 할 때가 많습니다. 아래는 적절한 K를 찾기 위한 몇 방법들입니다.
Elbow method (엘보우 방법)
클러스터 수에 따른 총 제곱거리 합(Sum of Squared Errors: SSE)을 그래프로 그려서 꺾이는 지점을 K로 선택, 시각적으로 직관적이어서 많이 활용.
Silhouette (실루엣 계수)
각 데이터가 해당 클러스터에 잘 속해 있는지를 평가, 범위 -1.0 ~ +1.0 사이로 값이 클수록 군집화가 잘 되었다는 의미. 다양한 K값에 대해 계산하고 가장 높은 값을 갖는 K를 선택하며 정량적으로 평가.
Gap Statistic (갭 통계량)
군집화 결과의 SSE와 랜덤한 군집화 SSE의 차이를 비교하여 최적 K를 결정, 구현 복잡성과 계산 비용이 큰 단점이 있음.
이 외에 Davies-Bouldin Index와 Calinski-Harabasz Index 등이 있습니다. 아래는 적절한 K를 찾기 위한 Elbow Method 예제와 K-means 군집화 파이썬 예제 입니다.
# Elbow Method Example ----------------------------------
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
# 샘플 데이터 생성
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=42)
# K 값에 따른 SSE 리스트
sse = []
# 다양한 K값(1~11)에 대해 K-Means
for k in range(1, 11):
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(X)
sse.append(kmeans.inertia_) # inertia_가 바로 SSE 값
# Elbow 그래프 시각화
plt.plot(range(1, 11), sse, marker='o')
plt.xlabel('클러스터 수 (K)')
plt.ylabel('오차 제곱합 (SSE)')
plt.title('Optimal K')
plt.grid(True)
plt.show()
# K-means algorithm example ------------------------
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
# 1.샘플 데이터 생성
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)
# 2.KMeans (K=4)
kmeans = KMeans(n_clusters=4)
kmeans.fit(X)
# 3.예측된 클러스터
y_kmeans = kmeans.predict(X)
# 4. 결과 시각화
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis') # 각 클러스터 색상표시
# 5. 중심점 표시
centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75, marker='X')
plt.title("K-means Clustering Result")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.grid(True)
plt.show()