[R] 연습

[R] 군집분석(k-means clustering편)

Simon Yoon 2021. 12. 26. 23:31

이전 포스팅에서는 차원축소의 방법 중 하나인 다차원 척도법(MDS)을 연습했었다. 시각화 과정에서 k-평균 군집화(k-means clustering)를 시행했었는데, 이번 포스팅에서 이를 한번 다시 다뤄보도록 하겠다.

 

군집분석 방법에는 계층적 군집화와 비계층적 군집화 방법이 있다. k-평균 군집화 방법은 비계층적 군집화 방법이며, 계층을 두지 않고 유사도를 바탕으로 미리 정한 k개의 군집들 중 하나에 할당한다. k-평균 군집화는 다음과 같은 순서로 진행한다.

 

  • 초기 군집의 수, k개를 사용자가 정한다.
  • k의 초기 평균값은 랜덤으로 정해진다.
  • 각 레코드는 중심이 가장 가까운 군집으로 할당된다.
  • 군집의 중심점을 다시 계산하고, 3 단계를 반복한다.
  • 더 이상의 변화가 없으면 중단한다.

이제 코드를 연습해보도록 하겠다.


이번에 사용할 데이터는 미국의 22개 공공 전력회사에 관한 데이터이다. 유사한 전력회사로 묶어 군집화 할 것이다.

Utilities.csv
0.00MB
Utilities.csv 데이터의 일부

Fixed_charge RoR Cost Load_factor Demand_growth Sales Nuclear Fuel_Cost
고정비용부담률 투자수익률 KW당 생산비용 연간 부하량 최대전력수요 증가율 매출액 원자력발전비율 총 연료비

 

# 데이터 준비
utilities.df <- read.csv("Utilities.csv")
row.names(utilities.df) <- utilities.df[,1]
utilities.df <- utilities.df[,-1]
summary(utilities.df)
colSums(is.na(utilities.df))

Q. k-평균 군집화(k-means clustering)를 하고 싶다면?

A. kmeans() 함수를 사용하자.

 

관측치 간의 거리를 이용하기 때문에 변수의 단위가 결과에 큰 영향을 미친다. 따라서 각 레코드를 다음과 같이 정규화 한 후에,

utilities.df.norm <- sapply(utilities.df, scale)
row.names(utilities.df.norm) <- row.names(utilities.df)

 

kmeans algorithm을 적용한다. 이 때, 6은 군집의 개수, nstart = 25는 kmeans 분석을 25번을 시행하고, 분산이 가장 작게 나오는 결과를 최종결과로 한다는 것이다.

km <- kmeans(utilities.df.norm, 6, nstart = 25)

 

이제 각 레코드가 어느 군집에 속하는지 알 수 있다.

km$cluster
# Arizona       Boston      Central  Commonwealth           NY     Florida     Hawaiian  
#        5            2            5            6            4            5            1 
#    Idaho     Kentucky     Madison        Nevada  New England     Northern     Oklahoma 
#        3            1            6            3            1            6            5 
# Pacific         Puget    San Diego     Southern        Texas    Wisconsin       United 
#        2            3            2            5            5            6            2 
# Virginia 
#        6

Q. k개 군집 갯수를 정하려면 어떻게 할 수 있을까?

A. factoextra 패키지의 fviz_nbclust() 함수 혹은 NbClust 패키지의 NbClust() 함수를 사용해보자.

 

먼저 factoextra 패키지의 fviz_nbclust() 함수를 사용해보면,

install.packages("factoextra")
library(factoextra)
fviz_nbclust(utilities.df.norm, kmeans, method = "wss")

 

위와 같은 엘보우 차트(elbow chart)를 볼 수 있다. k가 1에서 5로 점점 증가할 수록 군집내 거리는 크게 감소한다.

하지만 5를 넘어가게 되면 향상되는 정도는 덜하게 된다. 이런 차트를 통해서 적당한 k 값을 정할 수 있을 것이다.

 

NbClust 패키지의 NbClust() 함수를 사용해보면,

install.packages("NbClust")
library(NbClust)
nc <- NbClust(utilities.df.norm, min.nc = 2, max.nc = 10, method = "kmeans")

 

 

왼쪽의 그래프와 오른쪽의 결과 화면을 볼 수 있다. 이에 따르면 4개의 군집으로 분류하는 것이 좋다고 한다.

이러한 방법들을 사용해서 적절한 군집의 개수를 설정하고 분석한다면 더 나은 결과를 기대할 수 있을 것이다.

'[R] 연습' 카테고리의 다른 글

[R] 기초 문법 2  (0) 2022.01.13
[R] 기초 문법 1  (0) 2022.01.09
[R] 차원축소(MDS편)  (0) 2021.12.19
[R] reshape2 패키지 활용하기  (0) 2021.12.18
[R] reshape 패키지 활용하기  (0) 2021.12.17