AI/Clustering

[R] DBSCAN 파라미터 조정방법 in r (How to select parameters for 'dbscan()' in r)

슈퍼짱짱 2019. 8. 26. 09:00
반응형

DBSCAN에서 Eps와 MinPts 조정방법 in R

 

 

지난 포스팅에서 DBSCAN논문 리뷰와 R코드, 예시 및 파라미터 조정방법에 대해 알아보았다.

 

>> DBSCAN 논문 리뷰 바로가기

>> DBSCAN in r 바로가기

 

지난 포스팅 파라미터 조정은 클러스터에 대한 사전 지식이 있을 때, 원하는 클러스터의 모양이 있을 때라면,

이번 포스팅에서는 클러스터에 대한 사전지식이 없을 때 Eps와 MinPts를 조정하는 방법을 알아보겠다.

 


 

논문에의하면, 

 

1. 모든 포인트에 대하여 k번째로 가장 가까운 포인트와의 거리를 계산하고

2. 거리에 따라 내림차순으로 정렬한 다음

3. x축은 내림차순으로 정렬된 포인트의 index, y축은 내림차순으로 정렬된 거리로 그래프를 그린다.

4. 그래프에서 꺾이는 지점. 즉, elbow point를 찾으면 그 거리가 Eps, k가 MinPts가 된다.

 

<그래프 예시>

 


 

위 방법을 R에서 구현해 보았다.

 

1. 예시데이터 생성 및 시각화

 

1
2
3
4
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")
 
cs

 

> head(data)

 

  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

 

 

2. 주어진 포인트에 대하여 거리 구하는 function 정의

 

1
2
3
dis_eps <- function(dat, x, y){
  sqrt((dat[1]-x)^2 + (dat[2]-y)^2)
}
cs

 

3. 실행

* 논문에서 추천한 대로 k는 4로 시작해보았다.

 

1
2
3
4
5
k=4
dis <- c()
for(i in 1:nrow(data)){
  dis <- c(dis,sort(apply(data, 1, dis_eps, x=data[i,1],y<-data[i,2]))[k+1])
}
cs

 

4. 그래프로 elbow point확인

 

1
2
3
ggplot() +
  geom_point(aes(x=1:length(dis), y=sort(dis, decreasing = T))) +
  theme_bw()
cs

 

 

* 눈에 띄게 꺾이는 부분이 보이지 않는다.

 

5. k를 조정해가며 3,4번 반복실행

 

- k=2

 

 

- k=3

 

 

- k=5

 

 

k=5 부터 눈에띄게 꺽인 부분은 존재하지 않으며,

k=2일때와 k=3일때 모두 elbow 포인트의 거리는 2.236068(=sqrt(5)) 이다.

 

따라서 MinPts=2, Eps=sqrt(5)로 클러스터링 한 결과는 다음과 같다.

 

1
2
3
4
5
6
7
8
db <- dbscan(data, eps = sqrt(5), MinPts = 2)
 
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

 

 

MinPts=3, Eps=sqrt(5)의 결과

 

1
db <- dbscan(data, eps = sqrt(5), MinPts = 3)
cs

 

 

반응형
1 2 3 4