튜토리얼
07. Clustering

07. Clustering (군집화)

K-Means, DBSCAN, 계층적 군집화, Silhouette Score


학습 목표

이 튜토리얼을 완료하면 다음을 할 수 있습니다:

  • K-Means 알고리즘의 동작 원리와 목적 함수(Inertia) 이해
  • Elbow Method와 Silhouette Score를 활용한 최적의 K 선택
  • K-Means의 한계와 K-Means++ 초기화의 필요성 파악
  • DBSCAN, 계층적 군집화 등 다양한 클러스터링 알고리즘 비교
  • 실전 고객 세분화(Customer Segmentation) 적용

핵심 개념

1. Clustering이란?

비지도 학습으로 유사한 데이터를 그룹화하는 기법입니다. 라벨 없이 데이터의 구조를 발견합니다.

유형알고리즘특징
PartitioningK-Means빠름, k 지정 필요
DensityDBSCAN이상치 탐지, k 불필요
HierarchicalAgglomerative덴드로그램 시각화

2. K-Means 알고리즘 원리

K-Means는 데이터를 K개의 클러스터로 그룹화하는 가장 기본적이고 널리 사용되는 클러스터링 알고리즘입니다.

동작 과정:

  1. K개의 중심점(Centroid) 무작위 초기화
  2. 각 데이터를 가장 가까운 중심점에 할당
  3. 각 클러스터의 새로운 중심점 계산 (평균)
  4. 중심점이 변하지 않을 때까지 2-3 반복

목적 함수 (Inertia):

J=i=1nk=1Krikxiμk2J = \sum_{i=1}^{n} \sum_{k=1}^{K} r_{ik} ||x_i - \mu_k||^2

  • rikr_{ik}: 데이터 i가 클러스터 k에 속하면 1, 아니면 0
  • μk\mu_k: 클러스터 k의 중심점
from sklearn.cluster import KMeans
 
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
labels = kmeans.fit_predict(X_scaled)
centroids = kmeans.cluster_centers_
 
print(f'Inertia: {kmeans.inertia_:.2f}')
⚠️

스케일링 필수! K-Means는 거리 기반 알고리즘이므로 반드시 StandardScaler로 피처를 정규화해야 합니다.

K-Means 한계

  • k를 미리 지정해야 함
  • 구형(spherical) 클러스터만 잘 찾음
  • 이상치에 민감
  • 초기화에 따라 결과가 달라짐

3. 최적의 K 찾기

Elbow Method

Inertia 감소율이 꺾이는 지점(elbow)을 찾습니다.

inertias = []
K_range = range(1, 11)
 
for k in K_range:
    kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
    kmeans.fit(X_scaled)
    inertias.append(kmeans.inertia_)
 
plt.plot(K_range, inertias, 'bo-', linewidth=2, markersize=10)
plt.axvline(x=4, color='red', linestyle='--', label='Optimal K')
plt.xlabel('Number of Clusters (K)')
plt.ylabel('Inertia (Within-cluster sum of squares)')
plt.title('Elbow Method')
plt.legend()
plt.show()

최적 K 선택 방법 비교

방법설명
Elbow MethodInertia 감소율이 꺾이는 지점
Silhouette Score클러스터 내 응집도 vs 클러스터 간 분리도
Gap Statistic실제 데이터 vs 균일 분포 비교
도메인 지식비즈니스 요구사항 기반

실무 팁: Elbow와 Silhouette Score를 함께 사용하여 종합적으로 판단하세요. 때로는 비즈니스 요구사항이 더 중요할 수 있습니다.


4. Silhouette Score

각 샘플이 올바른 클러스터에 할당되었는지 평가하는 지표입니다.

s(i) = (b(i) - a(i)) / max(a(i), b(i))
  • a(i): 같은 클러스터 내 평균 거리 (응집도)
  • b(i): 가장 가까운 다른 클러스터까지 평균 거리 (분리도)
  • 범위: [-1, 1], 높을수록 좋음 (1에 가까울수록 클러스터가 잘 분리됨)
from sklearn.metrics import silhouette_score, silhouette_samples
 
# 전체 평균 점수
score = silhouette_score(X_scaled, labels)
print(f'Silhouette Score: {score:.4f}')
 
# 각 샘플별 점수 (시각화용)
sample_scores = silhouette_samples(X_scaled, labels)
 
# K별 Silhouette Score 비교
sil_scores = []
for k in range(2, 11):
    km = KMeans(n_clusters=k, random_state=42, n_init=10)
    labels = km.fit_predict(X_scaled)
    sil_scores.append(silhouette_score(X_scaled, labels))

5. K-Means++ 초기화

초기 중심점 선택이 K-Means 성능에 큰 영향을 미칩니다. K-Means++는 더 나은 초기화를 제공합니다.

# 초기화 방법 비교
results = []
for init_method in ['random', 'k-means++']:
    inertias_trial = []
    for _ in range(10):
        km = KMeans(n_clusters=4, init=init_method, n_init=1, random_state=None)
        km.fit(X)
        inertias_trial.append(km.inertia_)
    print(f'{init_method}: Mean={np.mean(inertias_trial):.2f}, Std={np.std(inertias_trial):.2f}')

K-Means++가 기본값입니다. scikit-learn의 KMeans는 기본적으로 init='k-means++'를 사용하므로 별도 설정이 필요 없습니다. Random 초기화보다 안정적이고 낮은 Inertia를 달성합니다.


6. DBSCAN

밀도 기반 클러스터링: 밀집 영역을 클러스터로 인식하고, 밀도가 낮은 영역은 노이즈로 처리합니다.

파라미터설명
eps이웃 거리 임계값 (반경)
min_samples핵심 포인트가 되기 위한 최소 이웃 수
from sklearn.cluster import DBSCAN
 
dbscan = DBSCAN(eps=0.5, min_samples=5)
labels = dbscan.fit_predict(X_scaled)
 
# 노이즈 포인트: label = -1
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
n_noise = list(labels).count(-1)
print(f'클러스터 수: {n_clusters}, 노이즈 수: {n_noise}')

DBSCAN 장점

  • K 지정 불필요 (자동으로 클러스터 수 결정)
  • 이상치 자동 탐지 (label = -1)
  • 비구형 클러스터 탐지 (반달, 동심원 등)
⚠️

K-Means의 한계: K-Means는 구형(spherical) 클러스터만 잘 찾습니다. 반달 모양(moons)이나 동심원(circles) 데이터에서는 DBSCAN이 훨씬 효과적입니다.


7. 계층적 군집화

트리 구조로 클러스터를 형성하며, 덴드로그램으로 시각화할 수 있습니다.

from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram, linkage
 
# sklearn으로 클러스터링
agg = AgglomerativeClustering(n_clusters=3, linkage='ward')
labels = agg.fit_predict(X_scaled)
 
# Dendrogram (scipy)
Z = linkage(X_scaled, method='ward')
plt.figure(figsize=(10, 7))
dendrogram(Z)
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('Sample Index')
plt.ylabel('Distance')
plt.show()

Linkage 방법

방법설명
ward분산 최소화 (기본, 가장 많이 사용)
complete최대 거리 (complete linkage)
average평균 거리
single최소 거리 (single linkage)

8. 알고리즘 비교

노트북에서는 다양한 데이터셋(Blobs, Moons, Circles)에서 K-Means, DBSCAN, Hierarchical Clustering을 비교합니다.

상황권장 알고리즘
k를 알고 있음, 구형 클러스터K-Means
이상치 존재, 비구형 클러스터DBSCAN
계층 구조 파악 필요Agglomerative
대용량 데이터 (10만+ 샘플)Mini-batch K-Means

9. Mini-Batch K-Means (대용량 데이터)

대용량 데이터에서는 Mini-Batch K-Means가 훨씬 빠릅니다.

from sklearn.cluster import MiniBatchKMeans
 
# 대용량 데이터
X_large, _ = make_blobs(n_samples=100000, centers=10, random_state=42)
 
# Mini-Batch K-Means
mbkm = MiniBatchKMeans(n_clusters=10, random_state=42, batch_size=1000, n_init=3)
mbkm.fit(X_large)

코드 요약

from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
 
# 스케일링 필수!
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
 
# K-Means
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
km_labels = kmeans.fit_predict(X_scaled)
 
# DBSCAN
dbscan = DBSCAN(eps=0.5, min_samples=5)
db_labels = dbscan.fit_predict(X_scaled)
 
# 평가
print(f"K-Means Silhouette: {silhouette_score(X_scaled, km_labels):.4f}")
 
# DBSCAN은 노이즈(-1) 제외하고 평가
mask = db_labels != -1
if mask.sum() > 1:
    print(f"DBSCAN Silhouette: {silhouette_score(X_scaled[mask], db_labels[mask]):.4f}")

실전 예제: 고객 세분화

노트북에서는 Mall Customers 데이터를 활용한 고객 세분화 실습을 다룹니다.

# 고객 데이터 클러스터링
X_customers = customers[['Annual_Income', 'Spending_Score']].values
X_scaled = StandardScaler().fit_transform(X_customers)
 
# 최적 K 찾기 후 클러스터링
km_final = KMeans(n_clusters=5, random_state=42, n_init=10)
customers['Cluster'] = km_final.fit_predict(X_scaled)
 
# 클러스터별 프로필 분석
cluster_profile = customers.groupby('Cluster').agg({
    'CustomerID': 'count',
    'Age': 'mean',
    'Annual_Income': 'mean',
    'Spending_Score': 'mean'
})

클러스터 해석 예시:

  • 고소득 + 고소비: VIP 고객, 프리미엄 서비스 제공
  • 고소득 + 저소비: 잠재 고객, 마케팅 타겟
  • 저소득 + 고소비: 할인 프로모션 효과적

면접 질문 맛보기

  1. K-Means의 한계와 대안은?
  2. DBSCAN의 eps와 min_samples를 어떻게 선택하나요?
  3. Silhouette Score의 의미와 해석 방법은?
  4. K-Means++가 일반 K-Means보다 나은 이유는?
  5. 대용량 데이터에서 클러스터링 성능을 높이는 방법은?

더 많은 면접 질문은 Premium Interviews (opens in a new tab)에서 확인하세요.


실습 노트북

노트북에서는 다음 추가 내용을 다룹니다:

  • K-Means 동작 과정 단계별 시각화 (iteration별 중심점 이동)
  • Silhouette Plot으로 클러스터별 품질 시각화
  • 다양한 데이터셋(Blobs, Moons, Circles)에서 알고리즘 비교
  • 3D 시각화를 통한 고객 세분화 분석
  • Mini-Batch K-Means 성능 벤치마크

이전: 06. Feature Engineering | 다음: 08. Dimensionality Reduction