⊢MachineLearning

비지도학습 : 군집화 모델 - 계층적 군집화

최 수빈 2025. 3. 17. 01:55

 

계층적 군집화(Hierarchical Clustering)

 

데이터 포인트들을 계층 구조로 그룹화하는 군집화 방법

 

  • 데이터 포인트를 점진적으로 병합하거나 분할하여 군집을 형성
  • 계층적 구조를 시각화할 수 있는 덴드로그램(Dendrogram) 생성

 

계층적 군집화의 방식

 

병합 군집화(Agglomerative Clustering)

  1. 각 데이터 포인트를 개별 군집으로 시작
  2. 가장 가까운 군집을 반복적으로 병합

분할 군집화(Divisive Clusterting)

  1. 모든 데이터 포인트를 하나의 군집으로 시작
  2. 반복적으로 가장 멀리 떨어진 군집을 분할

 

계층적 군집화의 작동 원리

 

  1. 거리 행렬 계산
    각 데이터 포인트 간의 거리를 계산하여 거리 행렬을 생성
    대표적인 거리 계산 방법 : 유클리드 거리(Euclidean distance)
  2. 군집 병합/분할
    병합 군집화 : 가장 가까운 군집을 반복적으로 병합
    분할 군집화 : 가장 멀리 떨어진 군집을 반복적으로 분할
  3. 덴드로그램 생성
    군집화 과정을 트리 형태로 시각화
    최적의 군집 개수를 결정하는 데 활용

 

계층적 군집화 실습

 

Kaggle의 쇼핑몰 고객 데이터(Mall_Customers.csv)를 이용하여 계층적 군집화를 수행

 

 

데이터 로드, 전처리

import kagglehub
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import AgglomerativeClustering
import scipy.cluster.hierarchy as sch

path = kagglehub.dataset_download("vjchoudhary7/customer-segmentation-tutorial-in-python")
csv_path = os.path.join(path, "Mall_Customers.csv")

# 데이터셋 불러오기
df = pd.read_csv(csv_path)

# 데이터 확인
print(df.head())

# 필요한 열만 선택
X = df[['Age', 'Annual Income (k$)', 'Spending Score (1-100)']]

# 데이터 정규화 - 데이터를 정규화(평균=0, 분산=1)하여 군집화를 수행하기 적절한 형태로 변환
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

"""
   CustomerID  Gender  Age  Annual Income (k$)  Spending Score (1-100)
0           1    Male   19                  15                      39
1           2    Male   21                  15                      81
2           3  Female   20                  16                       6
3           4  Female   23                  16                      77
4           5  Female   31                  17                      40
"""

 

 

덴드로그램(Dendrogram) 생성

 

덴드로그램을 사용하여 최적의 군집 개수(k)를 결정

X축은 데이터 포인트, Y축은 유클리드 거리(Euclidean distance)를 나타냄

plt.figure(figsize=(10, 7))
dendrogram = sch.dendrogram(sch.linkage(X_scaled, method='ward'))
plt.title('Dendrogram')
plt.xlabel('Customers')
plt.ylabel('Euclidean distances')
plt.show()
Customers - Euclidean distances Dendrogram

 

덴드로그램을 살펴보면서 가장 크게 단절된 지점(수평선이 길게 이어진 부분)을 기준으로 최적의 군집 개수를 선택

 

 

 

계층적 군집화 모델 학습 및 시각화

 

덴드로그램을 분석하여 최적의 군집 개수(k=5)로 설정하고 모델 학습

# 계층적 군집화 모델 생성 및 학습
hc = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='ward')
y_hc = hc.fit_predict(X_scaled)

# 결과 시각화
plt.figure(figsize=(10, 7))
plt.scatter(X_scaled[y_hc == 0, 0], X_scaled[y_hc == 0, 1], s=100, c='red', label='Cluster 1')
plt.scatter(X_scaled[y_hc == 1, 0], X_scaled[y_hc == 1, 1], s=100, c='blue', label='Cluster 2')
plt.scatter(X_scaled[y_hc == 2, 0], X_scaled[y_hc == 2, 1], s=100, c='green', label='Cluster 3')
plt.scatter(X_scaled[y_hc == 3, 0], X_scaled[y_hc == 3, 1], s=100, c='cyan', label='Cluster 4')
plt.scatter(X_scaled[y_hc == 4, 0], X_scaled[y_hc == 4, 1], s=100, c='magenta', label='Cluster 5')
plt.title('Clusters of customers')
plt.xlabel('Age')
plt.ylabel('Annual Income (k$)')
plt.legend()
plt.show()
Clusters of customers
  • 고객들이 5개의 군집으로 분류됨
  • 군집별 특성을 분석하여 마케팅 전략을 수립 가능

 

 

모델 평가 - 실루엣 점수(Silhouette Score)

 

군집화 모델이 얼마나 잘 분리되었는지 평가하기 위해 실루엣 점수(Silhouette Score)를 계산

실루엣 점수는 1에 가까울수록 좋은 군집화를 의미

from sklearn.metrics import silhouette_score

# 실루엣 점수 계산
silhouette_avg = silhouette_score(X_scaled, y_hc)
print(f'Silhouette Score: {silhouette_avg}')

"""
Silhouette Score: 0.39002826186267214
"""

 

*실루엣 점수 해석

  • 0.5 이상 : 군집화가 비교적 잘 수행됨
  • 0.3~0.5 : 군집화가 보통 수준
  • 0.3 미만 : 군집이 명확하지 않음 (군집 개수 조정 필요)

 

*계층적 군집화 vs K-means 비교

  계층적 군집화 k-means 군집화
군집 개수 설정 덴드로그램을 통해 결정 k값을 미리 설정
계산 비용 데이터가 많아질수록 연산량 증가 상대적으로 계산 비용 낮음
유연성 다양한 거리 측정 방식 지원 유클리드 거리를 주로 사용
해석 가능성 덴드로그램으로 군집 형성 과정 분석 가능 군집 형성 과정이 보이지 않음

데이터 크기가 작을 때 : 계층적 군집화가 유용

데이터 크기가 클 때 : k-means가 효율적

 

알고리즘 시간 복잡도 설명
병합 군집화(Agglomerative Clustering) O(n²) ~ O(n³) 데이터 포인트 간 거리 행렬을 계산하고 반복적으로 병합 수행
분할 군집화(Divisive Clustering) O(2ⁿ) 모든 데이터가 포함된 하나의 군집에서 시작해 모든 가능한 분할을 탐색
k-means O(n) ~ O(nk) 데이터 개수(n)와 클러스터 개수(k)에 따라 선형적으로 증가
  • 계층적 군집화(특히 분할 군집화)는 연산량이 기하급수적으로 증가해서 대규모 데이터에 적용하기 어려움
  • k-means는 데이터가 많아져도 상대적으로 빠른 속도로 실행 가능
  • 계층적 군집화는 거리 행렬(distance matrix)를 저장해야하기 때문에 데이터가 많아질수록 거리 행렬이 기하급수적으로 커지는 반면, k-means는 개별 데이터 포인트만 저장, 연산 수행하여 메모리 사용량이 적음 → 특히, 스트리밍 데이터(실시간 데이터)에서도 효율적으로 사용 가능
  • 계층적 군집화는 잘못 병합되거나 분할되면 처음부터 다시 수행해야하는 반면, k-means는 k값만 변경하면 쉽게 다른 개수의 군집을 설정할 수 있음