DBSCAN
Density-Based Spatial Clustering
밀도 기반 군집화 알고리즘. 이상치 탐지에 유용.
Density-Based Spatial Clustering
밀도 기반 군집화 알고리즘. 이상치 탐지에 유용.
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)은 데이터 포인트의 밀도를 기반으로 클러스터를 형성하는 비지도 학습 알고리즘입니다. K-Means와 달리 클러스터 개수를 미리 지정할 필요가 없으며, 임의의 형태(비구형)를 가진 클러스터도 발견할 수 있습니다.
1996년 Martin Ester 등이 발표한 이 알고리즘은 공간 데이터베이스에서 노이즈가 포함된 데이터의 클러스터링 문제를 해결하기 위해 개발되었습니다. 이름에서 알 수 있듯이 원래 지리 정보 시스템(GIS)과 공간 데이터 분석을 위해 설계되었습니다.
핵심 원리는 eps(epsilon) 반경 내에 min_samples 이상의 이웃 포인트가 있으면 "코어 포인트"로 분류하고, 이 코어 포인트들을 연결하여 클러스터를 확장합니다. 어떤 클러스터에도 속하지 않는 포인트는 자동으로 노이즈(-1)로 레이블링됩니다.
실무에서 DBSCAN은 이상치 탐지(fraud detection), 이미지 세그멘테이션, 고객 행동 패턴 분석, 위치 기반 서비스에서 핫스팟 식별 등에 널리 사용됩니다. 특히 데이터에 노이즈가 많거나 클러스터 형태가 불규칙한 경우 K-Means보다 훨씬 좋은 성능을 보여줍니다.
import numpy as np
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_moons
import matplotlib.pyplot as plt
# 반달 모양 데이터 생성 (K-Means가 실패하는 대표적 케이스)
X, y_true = make_moons(n_samples=300, noise=0.05, random_state=42)
# 데이터 스케일링 (DBSCAN 필수 전처리)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# DBSCAN 클러스터링
# eps: 이웃 반경, min_samples: 코어 포인트 최소 이웃 수
dbscan = DBSCAN(eps=0.3, min_samples=5)
labels = dbscan.fit_predict(X_scaled)
# 결과 분석
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
n_noise = list(labels).count(-1)
print(f"발견된 클러스터 수: {n_clusters}")
print(f"노이즈 포인트 수: {n_noise}")
print(f"코어 포인트 수: {len(dbscan.core_sample_indices_)}")
# 시각화
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=labels, cmap='viridis')
plt.title(f'DBSCAN Clustering (clusters={n_clusters}, noise={n_noise})')
plt.show()
"이상 거래 탐지에는 DBSCAN이 적합합니다. 정상 거래는 밀집되어 있고 사기 거래는 흩어져 있으니까요. K-Means와 달리 이상치를 자동으로 노이즈로 분류해줍니다."
"DBSCAN의 장점은 클러스터 개수를 미리 지정할 필요 없고, 비구형 클러스터를 찾을 수 있다는 점입니다. 다만 eps와 min_samples 튜닝이 중요하고, 밀도가 다양한 데이터에서는 HDBSCAN을 고려해야 합니다."
"데이터가 200만 건이면 DBSCAN의 O(n²) 메모리 복잡도가 문제될 수 있어요. ball_tree나 kd_tree 알고리즘을 쓰거나, 샘플링 후 레이블을 전파하는 방식을 검토해봐야 합니다."
eps는 거리 기반 파라미터입니다. 피처 스케일이 다르면 특정 피처가 거리 계산을 지배하게 됩니다. StandardScaler로 반드시 전처리하세요.
eps가 너무 크면 모든 포인트가 하나의 클러스터로, 너무 작으면 대부분이 노이즈로 분류됩니다. k-distance 그래프(elbow method)를 사용해 적절한 eps를 찾으세요.
min_samples는 최소 (차원 수 + 1)로 설정하고, eps는 k-distance 그래프의 elbow 지점을 참고하세요. 밀도가 다양한 데이터에는 HDBSCAN을 사용하세요.