군집의 중심으로 지속적으로 움직이면서 군집화 수행.
KMeans와의 차이점
따라서, 데이터의 분포도를 이용해 군집 중심점을 찾는다. 확률 밀도 함수와 KDE(Kernel Density Estimation)를 이용
개별데이터의 특정 반경 내에 데이터 분포도를 KDE기반_MeanShift알고리즘으로 계산
KDE로 계산된 데이터가 분포도가 높은 방향으로 데이터 이동
개별데이터의 군집 중심점을 설정
지정된 반복횟수(iter)만큼 전체 데이터에 대한 KDE기반(데이터와의 거리값을 KDE함수 값으로 입력하여 반환) 데이터 이동
Kernel Density Estimation
커널함수를 통해 어떤 변수의 확률 밀도 함수를 추정
KDE =()
- 작은 h는 좁고 뾰족한 KDE → 과적합우려
- 큰 h는 과도하게 평활한 KDE → 과소적합 우려
1) 데이터생성(make_blobs)
import numpy as np
from sklearn.datasets import make_blobs
X,y=make_blobs(n_samples = 200, n_features = 2, centers =3,
cluster_std=0.7, random_state= 0)
2) MeanShift활용
from sklearn.cluster import MeanShift
h_08 =MeanShift(bandwidth=0.8).fit_predict(X)
h_2=MeanShift(bandwidth=2).fit_predict(X)
print("h=0.8: ",np.unique(h_08, return_counts=True))
print('h=2: ',np.unique(h_2, return_counts=True))
3) 최적화된 bandwidth 찾기
from sklearn.cluster import estimate_bandwidth
bandwidth = estimate_bandwidth(X)
bandwidth
1.8158484154517098
4) 군집화 시각화
import pandas as pd
import matplotlib.pyplot as plt
cluster = pd.DataFrame(X,columns=['x0','x1'])
cluster['target'] = y
cluster['meanshift'] = MeanShift(bandwidth = bandwidth).fit_predict(X)
marks = ['o','s','^']
for i in np.unique(cluster.meanshift):
target = cluster[cluster.meanshift == i]
plt.scatter(x=target['x0'], y=target['x1'], marker=marks[i])
5) y(target)값과의 매칭확인
cluster.groupby('target')['meanshift'].value_counts()
데이터가 여러 개의 가우시안 분포를 가진 집합들로 석여 생성된것이라는 가정하에 군집화 실행
(연속 확률 함수)
이러한 실제 데이터 세트에서 KMeans를 적용시켜보았을때,
GMM을 적용시켰을때,
특정공간 내에 데이터 밀도차이를 기반으로한 알고리즘.
데이터의 분포가 기하학적으로 복잡한 데이터 세트에도 효과적인 군집화 가능
eps: 개별데이터를 중심으로 입실론(epsilon)의 반경을 가지는 원형의 영역
min_sample: 입실론 주변 영역에 포함되어야 하는 타 데이터의 최소 개수
(min points(타 데이터)+1(자신))
입실론 주변 영역 내 포함되는 최소 데이터 개수를 어떻게 충족하는가
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
iris = load_iris()
cluster = pd.DataFrame(iris.data, columns = iris.feature_names)
#--------------------------------#
from sklearn.cluster import DBSCAN
dbscan = DBSCAN(eps=.6, min_samples=8, metric='euclidean')
#--------------------------------#
cluster['target'] = iris.target
cluster['dbscan'] = dbscan.fit_predict(iris.data)
cluster.groupby('target')['dbscan'].value_counts()
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
pca = PCA(n_components=2, random_state=0).fit_transform(iris.data)
cluster['x0'] = pca[:,0]
cluster['x1'] = pca[:,1]
#-----------------------------#
markers=['o', 's', '^', 'x', '*']
for i in np.unique(cluster.dbscan):
target = cluster[cluster.dbscan==i]
if i == -1: cluster_legend = 'Noise'
else : cluster_legend = 'Cluster '+str(i)
plt.scatter(x=target['x0'], y=target['x1'], s=70,
marker=markers[i], label=cluster_legend)
plt.legend()
plt.show()
iris = load_iris()
df = pd.DataFrame(iris.data, columns = iris.feature_names)
dbscan = DBSCAN(eps=.8, min_samples=8, metric='euclidean')
df['target'] = iris.target
df['dbscan'] = dbscan.fit_predict(iris.data)
df.groupby('target')['dbscan'].value_counts()
pca = PCA(n_components=2, random_state=0).fit_transform(iris.data)
cluster['x0'] = pca[:,0]
cluster['x1'] = pca[:,1]
markers=['o', 's', '^', 'x', '*']
for i in np.unique(cluster.dbscan):
target = cluster[cluster.dbscan==i]
plt.scatter(x=target['x0'], y=target['x1'], s=70, marker=markers[i])
plt.show()
from sklearn.datasets import make_circles
import seaborn as sns
X,y = make_circles(n_samples=1000, shuffle=True, noise = 0.05,
random_state=0, factor=.5)
sns.scatterplot(x=X[:,0],y=X[:,1])
DBSCAN적용하기
import pandas as pd
from sklearn.cluster import DBSCAN
dbscan = DBSCAN(eps=.2,min_samples=10,metric='euclidean').fit_predict(X)
#------데이터프레임으로------#
cluster = pd.DataFrame(X, columns = ['x0','x1'])
cluster['target'] = y
cluster['dbscan'] = dbscan
#------시각화------#
markers=['o', 's', '^', 'x', '*']
for i in np.unique(cluster.dbscan):
target = cluster[cluster.dbscan==i]
plt.scatter(x=target['x0'], y=target['x1'], s=70,
edgecolor='k', marker=markers[i])
참고: KMeans를 적용한다면?
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters =2, max_iter=1000, random_state=0).fit_predict(X)
#------데이터프레임------#
cluster = pd.DataFrame(X, columns = ['x0','x1'])
cluster['target'] = y
cluster['kmeans'] = kmeans
#------시각화------#
markers=['o', 's', '^', 'x', '*']
for i in np.unique(cluster.kmeans):
target = cluster[cluster.kmeans==i]
plt.scatter(x=target['x0'], y=target['x1'], s=70,
edgecolor='k', marker=markers[i])