티스토리 뷰

반응형

계층적 군집 분석(hierarchical clustering) 수행 및 시각화





hclust(d, method = "complete", members = NULL)



# 1. 거리행렬 구하기

> v1 <- c(1,3,6,10,18)

> d1 <- dist(v1)

> d1

   1  2  3  4

2  2         

3  5  3      

4  9  7  4   

5 17 15 12  8


# 2. 거리행렬 모델 적용

> m1 <- hclust(d1, method = 'average')

> m1


Call:

hclust(d = d1, method = "average")


Cluster method   : average 

Distance         : euclidean 

Number of objects: 5


** method : 클러스터와 관측치와의 거리 계산 기준 

  - single : 최단거리법

  - complete : 최장거리법, 완전기준법 

  - average : 평균기준법 

  - median : 중앙중심법 


# 3. 시각화(벤다이어그램)

> plot(m1, hang = -10)   # 분석 결과에 대한 가설 검정을 할 수 없으므로 정확한 해석이 필요

                                      (1,2,3,4)와 (5) 두 개의 클러스터의 생성

                                   # hang : 관측치를 맞춰주기 위한 옵션


> rect.hclust(m1, k = 2)   # 클러스터를 k 기준으로 군집




#. 데이터에 적용

> install.packages("flexclust")   #nutrient 데이터셋을 사용하기 위한 패키지

> library(flexclust)

> data(nutrient)      # 유사한 식품 그룹 파악

> str(nutrient)

> head(nutrient)

                energy protein fat calcium iron

BEEF BRAISED       340      20  28       9  2.6

HAMBURGER          245      21  17       9  2.7

BEEF ROAST         420      15  39       7  2.0

...


# 1. 거리행렬 구하기

> nutrient_scaled <- scale(nutrient)    # 거리 기반이므로 표준화 필요 

> d <- dist(nutrient_scaled)

> as.matrix(d)[1:4,]         # 거리 계산

             BEEF BRAISED HAMBURGER BEEF ROAST BEEF STEAK BEEF CANNED CHICKEN BROILED CHICKEN CANNED

BEEF BRAISED    0.0000000  1.376933   1.769715  0.5487938    2.419605        3.247922       2.872737

HAMBURGER       1.3769332  0.000000   3.005141  1.9108691    1.154676        2.010848       1.702709

BEEF ROAST      1.7697153  3.005141   0.000000  1.2801255    4.042327        4.567355       4.453714

BEEF STEAK      0.5487938  1.910869   1.280126  0.0000000    2.933722        3.737122       3.405070



# 2. 거리행렬 모델 적용(계층적 군집화)

> fit <- hclust(d, method="average")  # method의 종류보다는 어떤 의도 하에 분류할 것인지에 따라 설명변수를 선택하는 것이 중요

> plot(fit, hang=-1 , cex=0.8)


# 군집 수 설정

> install.packages("NbClust")

> library(NbClust)

> nc <- NbClust(nutrient_scaled, distance="euclidean", min.nc=2, max.nc=15, method="average")

******************************************************************* 

* Among all indices:            

# 앞 숫자는 NB 클러스터 수행 시 분산, 표준편차 등 여러가지 통계적 수치들이 나오는데, 이러한 측정 지표들의 개수를 의미

# 특표가 가장 많은 4개 기준의 클러스터를 참고  

* 4 proposed 2 as the best number of clusters       # 4개에 대한 지표가 2개가 가장 좋은 클러스터라고 제안

* 4 proposed 3 as the best number of clusters 

* 2 proposed 4 as the best number of clusters 

* 4 proposed 5 as the best number of clusters 

* 1 proposed 9 as the best number of clusters 

* 1 proposed 10 as the best number of clusters 

* 2 proposed 13 as the best number of clusters 

* 1 proposed 14 as the best number of clusters 

* 4 proposed 15 as the best number of clusters 


                   ***** Conclusion *****                            

 

* According to the majority rule, the best number of clusters is  2   # 클러스터의 최적 개수는 2개

                                                                                       # 때에 따라 해석이 다르므로 참고로만

 

******************************************************************* 

# 모든 지표에 대한 그래프, 기울기가 급변하는 포인트(elbow point)가 좋은 지점 (5)


# 적합한 클러스터 개수를 cutree 함수로 확인 

> clusters <- cutree(fit, k=5)

> table(clusters)     # 군집별 데이터 개수 확인

clusters

 1  2  3  4  5 

 7 16  1  2  1



# 3. 시각화(벤다이어그램)

> plot(fit, hang= -1, cex=0.8)


> rect.hclust(fit, k=5)         # plot 함수로 시각화 , 지표의 추천 클러스터 개수를 지정 




#. 기준법 비교

### 모델 비교를 위한 함수 생성

> f_cluster <- function(data, y, k=3, method='average'){

     dist_iris <- dist(data)                                      # 거리행렬 연산

     cluster_iris <- hclust(dist_iris, method = method)

     cutree_iris <- cutree(cluster_iris, k = k)

     v1 <- cutree_iris == as.numeric(y)     # Factor -> numeric

     return(sum(v1) / nrow(data) * 100)

   }


# 1. 평균 기준법 (average)

> f_cluster(iris[,-5], iris$Species, method = 'average')  

[1] 90.66667

> f_cluster(scale(iris[,-5]), iris$Species, method = 'average')  

[1] 68.66667

# 불필요한 설명 변수를 제거

> f_cluster(iris[,3:4], iris$Species, method = 'average')  

[1] 96

> f_cluster(scale(iris[,3:4]), iris$Species, method = 'average')  

[1] 98    # 평균 기준법이 가장 좋은 예측력을 보임



# 2. 최단거리 기준법 (single)

> f_cluster(iris[,-5], iris$Species, method = 'single')  

[1] 68

> f_cluster(scale(iris[,-5]), iris$Species, method = 'single')  

[1] 66

# 불필요한 변수 제거

> f_cluster(iris[,3:4], iris$Species, method = 'single')  

[1] 66

> f_cluster(scale(iris[,3:4]), iris$Species, method = 'single')  

[1] 67.33333



# 3. 최장거리 기준법 (complete)

> f_cluster(iris[,-5], iris$Species, method = 'complete') 

[1] 49.33333

> f_cluster(scale(iris[,-5]), iris$Species, method = 'complete')

[1] 78.66667

# 불필요한 변수 제거

> f_cluster(iris[,3:4], iris$Species, method = 'complete')  

[1] 47.33333

> f_cluster(scale(iris[,3:4]), iris$Species, method = 'complete')

[1] 50



# 4. 중앙중심 기준법 (median)

> f_cluster(iris[,-5], iris$Species, method = 'median')  

[1] 43.33333

> f_cluster(scale(iris[,-5]), iris$Species, method = 'median')

[1] 78.66667

> # 불필요한 변수 제거

> f_cluster(iris[,3:4], iris$Species, method = 'median')  

[1] 96

> f_cluster(scale(iris[,3:4]), iris$Species, method = 'median')

[1] 50.66667


# 결론 : 1. 불필요한 설명변수는 데이터간 거리 차이를 커지게 함 -> 예측력 상실

              2. 가장 좋은 기준법이란 없음 -> 데이터에 따라 높은 예측도를 보이는 기준이 다름



### 적용

> scaled_iris <- scale(iris[,3:4])

> dist_iris <- dist(scaled_iris)

> cluster_iris_avg <- hclust(dist_iris, method="average")

> cutree_iris_avg <- cutree(cluster_iris_avg, k=3)

> table(cutree_iris_avg)

cutree_iris_avg

 1  2  3 

50 51 49


> plot(cluster_iris_avg, hang=-1 , cex=0.8)

> rect.hclust(cluster_iris_avg, k=3)


> scaled_iris <- as.data.frame(scaled_iris)

> plot(scaled_iris$Petal.Length, scaled_iris$Petal.Width, col=cutree_iris_avg, pch=cutree_iris_avg)




참고: KIC 캠퍼스 머신러닝기반의 빅데이터분석 양성과정

반응형
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday