AI/Clustering

[R] DBSCAN R 코드, 예시, 해석, 파라미터 조정 방법

슈퍼짱짱 2019. 8. 20. 10:00
반응형

지난 포스팅에서 DBSCAN논문을 리뷰해 보았다.

이번에는 R에서 DBSCAN을 어떻게 사용하는지 알아보고자 한다.

 

>> DBSCAN 논문 리뷰 바로가기

>> 원하는 클러스터 모양이 없을 때 파라미터 조정방법 바로가기 in R

 


 

1. DBSCAN및 그래프를 그리기 위한 package loading

 

- DBSCAN은 "fpc" library에 구현되어 있다.

 

1
2
library(fpc)
library(ggplot2)
cs

 

2. clustering할 데이터 생성 및 시각화

 

1
2
3
4
5
data <- data.frame(cbind(c(sample(1:10,30, replace = T),sample(20:30,20, replace = T)),
                         c(sample(1:15,30, replace = T),sample(15:30,20, replace = T))))
names(data)<-c("X1","X2")
 
head(data)
cs

 

 

   X1 X2

1  9 11

2  2  7

3  3  8

4  3  7

5  8 15

6  2  6

 

1
2
3
4
5
ggplot(data) +
  geom_hline(yintercept = 1:30, colour="grey") +
  geom_vline(xintercept = 1:30, colour="grey") +
  geom_point(aes(x=X1,y=X2), cex=2) +
  theme_bw()
cs

 

 

 

3. clustering with DBSCAN

 

- 예를 들어 원하는 cluster모양이 다음과 같을 때

 

- eps = sqrt(10), MinPts = 4로 파라미터를 조정했다.

 

1
db <- dbscan(data, eps = sqrt(10), MinPts = 4)
cs

 

> db

dbscan Pts=50 MinPts=4 eps=3.162278

       0  1 2 3

border 5  3 2 3

seed   0 26 6 5

total  5 29 8 8 

 

> db$cluster # 각 포인트 별 속한 클러스터

 [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 2 3 3 2 2 3 0 0 2 0 3 3 3 0 2

[46] 3 2 3 2 2

 

> db$isseed # 각 포인트별 core point인지 아닌지

 [1]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE

[16]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE

[31]  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE

[46]  TRUE  TRUE FALSE FALSE  TRUE

 

* noise의 클러스터는 0이다.

 

* border : 각 클러스터에 border point 개수

* seed : 각 클러스터에 core point 개수

* total : 각 클러스터에 포함된 포인트 전체 개수

 

 

- 그 때의 결과는 다음과 같다. (noise는 black으로 표시)

 

1
2
3
4
5
6
7
library("RColorBrewer")
ggplot(data) +
  geom_hline(yintercept = 1:30, colour="grey") +
  geom_vline(xintercept = 1:30, colour="grey") +
  geom_point(aes(x=X1,y=X2,col=as.factor(db$cluster)), cex=5) +
  scale_color_manual(values = c("black",brewer.pal(n = 9, name = 'Set1'))) +
  theme_bw() + theme(legend.position = "None")
cs

 

 

- 이때, border point와 noise point는 다음과 같다. (core point는 굵게 표시한 부분에서 !만 빼주면 된다.)

 

1
2
3
4
5
6
7
ggplot() +
  geom_hline(yintercept = 1:30, colour="grey") +
  geom_vline(xintercept = 1:30, colour="grey") +
  geom_point(data = data, aes(x=X1,y=X2,col=as.factor(db$cluster)), cex=5) +
  scale_color_manual(values = c("black",brewer.pal(n = 9, name = 'Set1'))) +
  geom_point(data = data[!db$isseed,],aes(X1, X2), shape=8, cex=5) + 
  theme_bw() + theme(legend.position = "None")
cs

 

 

 

* core point & border point

 

 

core point를 기준으로 Eps 범위 안에 7 points가 존재하며,

border point를 기준으로는 4 points가 존재한다.

만약 MinPts를 core point기준으로 7로 했다면, 끝 쪽에 있는 포인트들은 같은 클러스터로 형성되지 않을 것이다.

 

예제에서 해당 포인트가 core point가 아닌 border point인 이유는 

Eps(= sqrt(10)) 범위 안에 MinPts(= 4) 만큼의 포인트 수는 포함되지 않지만,

다른 core point에 의해 cluster에 해당되기 때문이다.

 


 

- noise없이 전부 클러스터로

 

1
db <- dbscan(data, eps = sqrt(18), MinPts = 2)
cs
가장 멀리있는 (5,1) 포인트와 (8,4) 포인트 사이의 거리는 sqrt(18)이다.

 

> db

dbscan Pts=50 MinPts=2 eps=4.242641

       1 2  3

seed  30 8 12

total 30 8 12

* noise가 없기 때문에 0 cluster가 없다.

 

1
2
3
4
5
6
7
ggplot(data) +
  geom_hline(yintercept = 1:30, colour="grey") +
  geom_vline(xintercept = 1:30, colour="grey") +
  geom_point(aes(x=X1,y=X2,col=as.factor(db$cluster)), cex=5) +
  # scale_color_manual(values = c("black",brewer.pal(n = 9, name = 'Set1'))) +
  scale_color_manual(values = c(brewer.pal(n = 9, name = 'Set1'))) +
  theme_bw() + theme(legend.position = "None")
cs

 

 

반응형