: K-평균과 유사하게, 군집의 중심을 지속적으로 움직이면서 군집화를 수행함
: 그러나, K-평균이 중심에 소속된 데이터의 평균 거리 중심으로 이동하는데 반해,
: 평균 이동은 데이터가 모여있는 밀도가 가장 높은 곳으로 이동시키면서 군집화하는 방법
평균 이동 군집화는 데이터의 분포도를 이용해 군집 중심점을 찾음
군집 중심점은 데이터 포인트가 모여있는 곳이라는 생각에서 착안
이를 위해 확률 밀도 함수를 이용 함
확률 밀도 함수가 피크인 점(가장 집중적으로 데이터가 모여 있을)을 군집 중심점으로 선정하며
주어진 모델의 확률 밀도 함수를 찾기 위해서 KDE(Kernel Density Estimation)을 이용
주변 데이터와의 거리 값을 KDE 함수 값으로 입력한 뒤, 그 반환 값을 현재 위치에서 업데이트하면서 이동하는 방식
KDE(Kernel Density Estimation)
: 커널 함수를 통해 어떤 변수의 확률 밀도 함수를 추정하는 대표적인 방법
: 개별 데이터 각각에, 커널 함수를 적용한 값을 모두 더한 뒤 데이터 건수로 나눠 확률 밀도 함수를 추정한다.
확률 밀도 함수 PDF(Probability Density Function)
: 확률 변수의 분포를 나타내는 함수 (정규 분포, 감마 분포, t-분포 등)
커널 함수의 예시) 가우시안 커널 함수 적용
수식
: 커널 함수, : 확률 변수 값, : 관측값, : 대역폭(bandwidth)
대역폭 : KDE 형태를 부드럽거나 뾰족한 형태로 평활화(smoothing)하는데 적용
- 작은 값: 좁고 뾰족한 KDE를 가짐. 과적합 되기 쉬움. 많은 수의 군집 중심점을 가짐
- 큰 값: 과도하게 평활화된 KDE를 가짐. 과소적합 되기 쉬움. 적은 수의 군집 중심점을 가짐
⇒ 적절한 h를 계산하는 것이 KDE 기반의 평균 이동에서 매우 중요하다.
사용
import numpy as np
from sklearn.datasets import make_blobs
from sklearn.cluster import MeanShift
X, y = make_blobs(n_samples=200, n_features=2, centers=3,
cluster_std=0.7, random_state=0)
meanshift= MeanShift(bandwidth=0.8)
cluster_labels = meanshift.fit_predict(X)
print('cluster labels 유형:', np.unique(cluster_labels))
> cluster labels 유형: [0 1 2 3 4 5]
meanshift= MeanShift(bandwidth=1) # bandwidth 변경
cluster_labels = meanshift.fit_predict(X)
print('cluster labels 유형:', np.unique(cluster_labels))
> cluster labels 유형: [0 1 2]
⭐️ estimate_bandwidth(X)
⭐️ : 최적의 대역폭 찾아줌. 파라미터로 피처 데이터 세트(X) 입력
from sklearn.cluster import estimate_bandwidth
# estimate_bandwidth()로 최적의 bandwidth 계산
bandwidth = estimate_bandwidth(X)
print('bandwidth 값:', round(bandwidth,3))
> bandwidth 값: 1.816
------------------------------------------------------------
import pandas as pd
clusterDF = pd.DataFrame(data=X, columns=['ftr1', 'ftr2'])
clusterDF['target'] = y
# estimate_bandwidth()로 최적의 bandwidth 계산
best_bandwidth = estimate_bandwidth(X)
meanshift= MeanShift(bandwidth=best_bandwidth)
cluster_labels = meanshift.fit_predict(X)
print('cluster labels 유형:',np.unique(cluster_labels))
> cluster labels 유형: [0 1 2]
평균 이동의 장점
평균 이동의 단점
활용
: 군집화를 적용하고자 하는 데이터가, 여러 개의 가우시안 분포를 가진 데이터 집합들이 섞여서 생성된 것이라는 가정하에, 군집화를 수행하는 방식
모수 추정 : 개별 정규 분포의 평균과 분산 추정, 각 데이터가 어떤 정규분포에 해당되는지의 확률 추정
사용
from sklearn.mixture import GaussianMixture
gmm = GaussianMixture(n_components=3, random_state=0).fit(iris.data)
gmm_cluster_labels = gmm.predict(iris.data)
# 클러스터링 결과를 irisDF 의 'gmm_cluster' 컬럼명으로 저장
irisDF['gmm_cluster'] = gmm_cluster_labels
irisDF['target'] = iris.target
# target 값에 따라서 gmm_cluster 값이 어떻게 매핑되었는지 확인.
iris_result = irisDF.groupby(['target'])['gmm_cluster'].value_counts()
print(iris_result)
> target gmm_cluster
> 0 0 50
> 1 2 45
> 1 5
> 2 1 50
> Name: gmm_cluster, dtype: int64
장점 : KMeans보다 유연하게 다양한 데이터 세트에 잘 적용될 수 있다. (Not 원형 범위여도 작동 잘 함)
단점 : 수행시간이 오래 걸린다.
: 입실론 주변 영역의 최소 데이터 갯수를 포함하는 밀도 기준을 충족시키는 데이터인, 핵심 포인트를 연결하면서 군집화를 구성하는 방식
: 데이터의 분포가 기하학적으로 복잡한 데이터 세트에도 효과적으로 군집화 가능
수행 방법
사용
from sklearn.cluster import DBSCAN
dbscan = DBSCAN(eps=0.6, min_samples=8, metric='euclidean')
dbscan_labels = dbscan.fit_predict(iris.data)
irisDF['dbscan_cluster'] = dbscan_labels
irisDF['target'] = iris.target
iris_result = irisDF.groupby(['target'])['dbscan_cluster'].value_counts()
print(iris_result)
> target dbscan_cluster
> 0 0 49
> -1 1
> 1 1 46
> -1 4
> 2 1 42
> -1 8
> Name: dbscan_cluster, dtype: int64
# 군집 레이블이 -1인 것은 노이즈에 속하는 군집을 의미
파라미터
파라미터 | 설명 |
---|---|
eps | 입실론(epsilon) |
개별 데이터를 중심으로 입실론 반경을 가지는 원형의 영역
일반적으로 1 이하의 값 설정 |
| min_samples | 최소 데이터 개수(min points)
개별 데이터의 입실론 주변 영역에 포함되는 타 데이터의 개수 (자기 자신 포함) |
make_circles() 원본
Kmeans (거리기반 군집화)
GMM (확률 기반 군집화)
DBSCAN
: 각 군집화 기법은 나름의 장/단점을 가지고 있으며, 군집화 하려는 데이터의 특성에 맞게 선택해야 한다.