Mean Shift cluster

jh_k·2023년 2월 24일
0

비지도학습

목록 보기
5/6

Mean Shift Clustering 개요
K-Means랑 유사한데 차이점은

K-means는 중심에 소속된 데이터의 평균 거리 중심으로 이동하는 데 반해,
Mean Shift는 중심을 데이터가 모여있는 밀도가 가장 높은 곳으로 이동 시킴

특징

KDE (Kernel Density Estimation)로 확률 밀도 함수 (Probability Density Function)을 찾음
KDE를 이용하여 데이터 포인트들이 데이터 분포가 높은 곳으로 이동하면서 군집화를 수행
별도의 군집화 개수를 지정하지 않고, 데이터 분포도에 기반하여 자동으로 군집 개수 선정

커널 함수를 통해 어떤 변수의 확률 밀도 함수를 추정하는 대표적인 방법
커널 함수는 대표적으로 가우시안 분포 함수 (정규 분포 함수)가 사용됨

sklearn.cluster.MeanShift

class sklearn.cluster.MeanShift(*, bandwidth=None, seeds=None, bin_seeding=False, min_bin_freq=1, cluster_all=True, n_jobs=None, max_iter=300)[source]

bandwidthfloat, default=None

Bandwidth used in the RBF kernel.

If not given, the bandwidth is estimated using sklearn.cluster.estimate_bandwidth; see the documentation for that function for hints on scalability (see also the Notes, below)

Mean Shift Clustering 실습

make_blobs를 통해 군집화 샘플데이터 생성

import numpy as np
from sklearn.datasets import make_blobs
from sklearn.cluster import MeanShift

x,y = make_blobs(n_features=2,n_samples=200,centers=3,
                cluster_std=0.7,random_state=0)

meanshift = MeanShift(bandwidth=1)
cluster_labels = meanshift.fit_predict(x)
print('cluster labels 유형',np.unique(cluster_labels))

이때 커널에서 사용할 bandwidth를 조정해 주어야하는데 sklearn에 있는 estimate_bandwidth를 사용하겠습니다.

sklearn.cluster.estimate_bandwidth

sklearn.cluster.estimatebandwidth(_X, *, quantile=0.3, n_samples=None, random_state=0, n_jobs=None)[source]

## 최적의 bandwidth 값을 찾기위한 라이브러리
from sklearn.cluster import estimate_bandwidth

bandwidth = estimate_bandwidth(x)
print('bandwidth 값 ', round(bandwidth,3))

bandwidth 값 1.816

import pandas as pd

cluster_df = pd.DataFrame(x,columns=['ftr1','ftr2'])
cluster_df['target'] = y

# 최적의 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]

import matplotlib.pyplot as plt

cluster_df['meanshift_label'] = cluster_labels
centers = meanshift.cluster_centers_
unique_labels = np.unique(cluster_labels)
markers = ['o','s','^','x','*']

for label in unique_labels:
    label_cluster = cluster_df[cluster_df['meanshift_label']==label]
    center_x_y = centers[label]
    # 군집별로 다른 마커로 산점도 적용
    plt.scatter(x=label_cluster['ftr1'],y=label_cluster['ftr2'],marker=markers[label])
    
    # 군집별 중심 표현
    plt.scatter(x=center_x_y[0],y=center_x_y[1],s=200,color='gray',alpha=0.9,marker=markers[label])
    plt.scatter(x=center_x_y[0],y=center_x_y[1],s=270,color='gray',edgecolors='k',marker='$%d$' % label)
plt.show()

profile
Just Enjoy Yourself

0개의 댓글