본문 바로가기

ML with SckitLearn

[DBSCAN] 밀도기반 군집화 Cluster Algorithm

반응형

밀도 기반 군집화의 대표적인 알고리즘으로 DBSCAN(Density Based Spatial Clustering of Applicayions with Noise)이 있습니다. DBSCAN은 특정 공간 내에 데이터 밀도 차이를 기반 알고리즘으로 하고 있어서 복잡한 기하학적 분포도를 가진 데이터 세트에 대해서도 군집화를 잘 수행합니다.

 


DBSCAN 용어정리

 

˙ Epsilon (입실론 주변 영역): 개별 데이터를 중심으로 입실론 반경을 가지는 원형의 영역입니다.

˙ Min Points(최소 데이터 개수): 개별 데이터의 입실론 주변 영역에 포함되는 타 데이터의 개수입니다.

 

˙ Core Point(핵심 포인트): 주변 영역 내에 최소 데이터 개수 이상의 타 데이터를 가지고 있을 경우 해당 데이터를 핵심 포인트라고 합니다.

˙ Neighbor Point(이웃 포인트): 주변 영역 내에 위치한 타 데이터를 이웃 포인트라고 합니다.

˙ Bordor Point(경계 포인트): 주변 영역 내에 최소 데이터 개수 이상의 이웃 포인트를 가지고 있지 않지만 핵심 포인트를 이웃 포인트로 가지고 있는 데이터를 경계 포인트라고 합니다.

˙ Noise Point(잡은 포인트): 최소 데이터 개수 이상의 이웃 포인트를 가지고 있지 않으며, 핵심 포인트도 이웃 포인트로 가지고 있지 않는 데이터를 잡음 포인트라고 합니다.

 

 


DBSCAN Code Test

 

 

Epsilon(eps)를 0.6, Min Points(min_samples)를 8로 하여 DBSCAN진행합니다.

from sklearn.cluster import DBSCAN
from sklearn.datasets import load_iris
import pandas as pd

iris_data = load_iris()
irisDF = pd.DataFrame(data=iris_data.data, columns=['sepal_length','sepal_width','petal_length','petal_width'])

dbscan = DBSCAN(eps=0.6, min_samples=8, metric='euclidean')
dbscan_labels = dbscan.fit_predict(iris_data.data)

irisDF['dbscan_cluster'] = dbscan_labels
irisDF['target'] = iris_data.target

iris_result = irisDF.groupby(['target'])['dbscan_cluster'].value_counts()
print(iris_result)

 

#print(iris_result)
target  dbscan_cluster
0        0                49
        -1                 1
1        1                46
        -1                 4
2        1                42
        -1                 8

-1이라는 값이 보이는데요. 이는 Noise Point를 의미합니다. 따라서 DBSCAN에서 0과 1두 개의 군집으로 군집화 됩니다. DBSCAN은 군집의 개수를 알고리즘에 따라 자동으로 지정하므로 DBSCAN에서 군집의 개수를 지정하는 것은 무의미하다고 할 수 있습니다. 

 

DBSCAN을 적용할 때는 특정 군집 개수로 군집을 강제하지 않는 것이 좋습니다. DBSCAN알고리즘에 적절한 eps와 min_samples파라미터를 통해 최적의 군집을 찾는 게 중요합니다. 일반적으로 eps의 값을 크게 하면 반경이 커져 포함하는 데이터가 많아지므로 노이즈 데이터 개수가 작아집니다. min_samples를 크게 하면 주어진 반경 내에서 더 많은 데이터를 포함시켜야 하므로 노이즈 데이터 개수가 커지게 됩니다.

 

PCA를 이용하여 2개의 피처로 변환한 뒤 이미지로 나타내면 하기와 같습니다.

pca = PCA(n_components=2)
pca_transformed = pca.fit_transform(iris_data.data)

irisDF['pca_x'] = pca_transformed[:,0]
irisDF['pca_y'] = pca_transformed[:,1]
print(irisDF)

maker0_ind = irisDF[irisDF['dbscan_cluster']==0].index
maker1_ind = irisDF[irisDF['dbscan_cluster']==1].index
maker2_ind = irisDF[irisDF['dbscan_cluster']==-1].index

plt.scatter(x=irisDF.loc[maker0_ind,'pca_x'], y=irisDF.loc[maker0_ind, 'pca_y'], marker='o')
plt.scatter(x=irisDF.loc[maker1_ind,'pca_x'], y=irisDF.loc[maker1_ind, 'pca_y'], marker='s')
plt.scatter(x=irisDF.loc[maker2_ind,'pca_x'], y=irisDF.loc[maker2_ind, 'pca_y'], marker='^')

plt.xlabel('PCA 1')
plt.ylabel('PCA 2')
plt.title('3 Cluster Visualization by 2 PCA Components')
plt.show()

 

반응형