본문 바로가기

카테고리 없음

K-means clustering in GNU R 예제

오늘 무감독 분류를 할 일이 있어서 좀 찾아보니 R에는 기본 패키지인 stats에 kmean()이란 함수가 존재했다.
코드 예제는 R 기본 패키지 설명에서 
(http://stat.ethz.ch/R-manual/R-patched/library/stats/html/kmeans.html)
require(graphics)
# a 2-dimensional example
x <- rbind(matrix(rnorm(100, sd = 0.3), ncol = 2), matrix(rnorm(100, mean = 1, sd = 0.3), ncol = 2))  #여기선 각각 다른 평균을 가지고 2 개의 난수를 발생시켜서 하나의 데이터셋으로 합쳤다. 그러니까, 두 개의 집단으로 원래 따로 넣은 애들이 분리되면 성공이 되는 문제로 만들었다. 
colnames(x) <- c("x", "y")
cl <- kmeans(x, 2) # 작업하는 함수. 데이터를 넣고, 몇 개의 집단으로 나눌 지 알려주면 끝. 여기선 두 개 집단으로 분리하라고 지시
plot(x, col = cl$cluster)
points(cl$centers, col = 1:2, pch = 8, cex=2)

kmeans(x,1)$withinss # if you are interested in that. 이번엔 하나 집단으로 나눠보기. 결과를 보면 재밌다. 

## random starts do help here with too many clusters
cl <- kmeans(x, 5, nstart = 25) # 이번엔 5개 집단으로 나눴다. 원래 특성은 두 개의 집단인데 5개의 집단으로 나눠보면 어떻게 될까? 란 아이디어. 
plot(x, col = cl$cluster)
points(cl$centers, col = 1:5, pch = 8)


k-means clustering 여기서는 차원을 더 높은 데이터로 해도 잘 됐다. 유클리드 공간이라 가정하고 하니까 최소제곱법과 같은 맥락에서 이해하면 무리가 없을 것이다. 알고리즘에 대해서는 위키를 참조하고 더 할 얘기가 있으면 적어두도록 하겠습니다. 

 http://en.wikipedia.org/wiki/K-means_clustering

Given a set of observations (x1x2, …, xn), where each observation is a d-dimensional real vector, k-means clustering aims to partition the n observations into k sets (k ≤ nS = {S1S2, …, Sk} so as to minimize the within-cluster sum of squares (WCSS):

\underset{\mathbf{S}} {\operatorname{arg\,min}} \sum_{i=1}^{k} \sum_{\mathbf x_j \in S_i} \left\| \mathbf x_j - \boldsymbol\mu_i \right\|^2
where μi is the mean of points in Si.