🤖 AI/ML

K-means

K-평균 클러스터링

비지도 학습 클러스터링 알고리즘. 데이터를 K개 그룹으로 분할.

📖 상세 설명

K-means 클러스터링은 비지도 학습의 대표적인 알고리즘으로, 라벨 없는 데이터를 K개의 그룹으로 자동 분류합니다. 각 데이터 포인트가 가장 가까운 중심점(centroid)에 할당되고, 군집 내 거리의 합(inertia)을 최소화하는 방향으로 최적화됩니다.

1957년 Bell Labs의 Stuart Lloyd가 펄스 코드 변조 기술을 위해 개발했으며, 이후 1967년 James MacQueen에 의해 "K-means"라는 이름이 붙여졌습니다. 60년 넘게 사용되어 온 검증된 알고리즘입니다.

알고리즘 복잡도는 O(n * K * d * i)로, n은 데이터 수, K는 군집 수, d는 차원, i는 반복 횟수입니다. 대용량 데이터에는 MiniBatchKMeans가 더 효율적이며, 메모리 사용량도 적습니다.

실무 활용 사례로는 고객 세분화(RFM 분석), 이미지 색상 양자화(압축), 이상 탐지(군집 외 데이터 식별), 문서 클러스터링 등이 있습니다. 간단하면서도 해석이 쉬워 탐색적 데이터 분석의 첫 단계로 자주 사용됩니다.

💻 코드 예제

from sklearn.cluster import KMeans, MiniBatchKMeans
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
import numpy as np

# 테스트 데이터 생성
X, y_true = make_blobs(n_samples=1000, centers=4, cluster_std=0.6, random_state=42)

# 데이터 정규화
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Elbow Method로 최적 K 찾기
def find_optimal_k(X, max_k=10):
    inertias = []
    for k in range(1, max_k + 1):
        kmeans = KMeans(n_clusters=k, random_state=42, n_init='auto')
        kmeans.fit(X)
        inertias.append(kmeans.inertia_)

    # 기울기 변화가 가장 큰 지점 찾기
    diffs = np.diff(inertias)
    second_diffs = np.diff(diffs)
    optimal_k = np.argmax(np.abs(second_diffs)) + 2
    return optimal_k, inertias

optimal_k, inertias = find_optimal_k(X_scaled)
print(f"추천 K: {optimal_k}")

# 대용량 데이터용 MiniBatchKMeans
kmeans = MiniBatchKMeans(
    n_clusters=optimal_k,
    batch_size=256,     # 미니배치 크기
    random_state=42,
    n_init='auto'
)
labels = kmeans.fit_predict(X_scaled)

# 결과 시각화
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.plot(range(1, 11), inertias, 'bo-')
plt.axvline(x=optimal_k, color='r', linestyle='--', label=f'K={optimal_k}')
plt.xlabel('K'); plt.ylabel('Inertia'); plt.title('Elbow Method')
plt.subplot(1, 2, 2)
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=labels, cmap='viridis', alpha=0.6)
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],
            c='red', marker='X', s=200, label='Centroids')
plt.title('K-means Clustering'); plt.legend()
plt.tight_layout(); plt.show()

🗣️ 실무에서 이렇게 말하세요

💬 회의에서
"고객 구매 패턴을 K-means로 분석했더니 4개 세그먼트로 나뉘었습니다. VIP, 정기구매, 가격민감, 이탈위험 그룹으로 각각 다른 마케팅 전략을 적용하면 전환율을 높일 수 있습니다."
💬 면접에서
"K-means는 유클리드 거리 기반이라 구형(spherical) 군집에 적합합니다. 비구형 군집이나 밀도가 다른 경우엔 DBSCAN이나 GMM을 고려해야 합니다. 초기값 의존성은 k-means++로 개선할 수 있어요."
💬 기술 토론에서
"데이터가 100만 건 이상이면 MiniBatchKMeans가 훨씬 빠릅니다. 배치 크기 256~1024 정도로 설정하면 정확도는 거의 유지하면서 속도가 10배 이상 개선돼요."

⚠️ 흔한 실수 & 주의사항

범주형 데이터에 K-means 적용

K-means는 연속형 수치 데이터용입니다. 범주형 데이터에는 K-modes나 K-prototypes를 사용하세요.

아웃라이어 처리 없이 클러스터링

이상치가 있으면 중심점이 왜곡됩니다. IQR이나 Z-score로 아웃라이어를 제거하거나 robust한 알고리즘을 사용하세요.

k-means++ 초기화 사용

sklearn의 기본값(init='k-means++')은 더 나은 초기 중심점을 선택해 수렴 속도와 결과 품질을 개선합니다.

🔗 관련 용어

📚 더 배우기