티스토리 뷰

반응형

비계층적 군집분석(k-means clustering)





 비계층적 군집분석 k-means는 현업에서도 많이 사용된다고 합니다.

계층적 군집 분석과 순차적으로 그룹을 할당하는지의 여부만 다를 뿐 굉장히 유사합니다.


계층적 군집은 말 그래도 순차적으로 데이터들을 군집화하지만, 

비계층적 군집분석은 랜덤으로 데이터를 군집화하고 군집 과정에서 중앙값의 변화에 따라 각 데이터들을 적절한 클러스터로 이동시켜줍니다.


먼저 확인적 군집분석이라고 불리우는데, 계속해서 클러스터(그룹)의 중앙값을 계산하면서, 해당 클러스터 안에 있는 데이터의 그룹이 적절한지 계속해서 확인해줍니다.


즉, 특정 관측치가 기존 소속되어있던 클러스터의 확장으로 중앙값과 멀어진다면, 모델의 판단에 의해 해당 관측치를 다른 클러스터로 이동시켜준다는 말이죠. 


계속적인 확인으로 계층적 군집 분석보다 훨씬 더 많은 연산을 수행하므로, 보다 빠른 속도로 만들어졌습니다.

(계속적인 확인(연산) : 클러스터의 중심 계산, 경우의 수를 연산, 클러스터 중심값의 변화마다 기존 관측치 데이터를 소속에 계속 포함시킬지 제외할지 고려)


k-means clustering은 군집의 수를 이미 알고 있을 때 사용합니다. k 값을 미리 정해야하기 때문이죠



install.packages("graphics")

library(graphics)

kmeans(x, centers)




k-means clustering 적용

> install.packages("graphics")

> library(graphics)

> library(flexclust)      # nutrient data set

> data(nutrient) 


# k-means clustering 적용

> kms <- kmeans(nutrient, 5)   

> kms

K-means clustering with 5 clusters of sizes 6, 11, 3, 6, 1       # 5개의 각 클러스터에 소속된 관측치 개수 확인


Cluster means:                      각 관측치가 몇 번째 클러스터에 포함되었는지 확인

     energy  protein       fat    calcium     iron

1 361.66667 18.66667 31.000000   8.666667 2.433333

2 168.18182 21.09091  8.000000  12.090909 2.027273

3 270.00000 19.66667 20.666667   9.000000 2.533333

4  98.33333 14.66667  3.166667 101.333333 2.883333

5 180.00000 22.00000  9.000000 367.000000 2.500000


Clustering vector:

       BEEF BRAISED           HAMBURGER          BEEF ROAST          BEEF STEAK 

                  1                   3                   1                   1 

        BEEF CANNED     CHICKEN BROILED      CHICKEN CANNED          BEEF HEART 

                  2                   2                   2                   2 

     LAMB LEG ROAST LAMB SHOULDER ROAST          SMOKED HAM          PORK ROAST 

                  3                   3                   1                   1 

      PORK SIMMERED         BEEF TONGUE         VEAL CUTLET      BLUEFISH BAKED 

                  1                   2                   2                   2 

          CLAMS RAW        CLAMS CANNED     CRABMEAT CANNED       HADDOCK FRIED 

                  4                   4                   4                   2 

   MACKEREL BROILED     MACKEREL CANNED         PERCH FRIED       SALMON CANNED 

                  2                   4                   2                   4 

    SARDINES CANNED         TUNA CANNED       SHRIMP CANNED 

                  5                   2                   4 


Within cluster sum of squares by cluster:

[1]  5142.253  9237.236  1587.420 19329.242     0.000

 (between_SS / total_SS =  91.8 %)


Available components:                # 모델 이름에 출력 가능한 컴포넌트


[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss" "betweenss"   

[7] "size"         "iter"         "ifault" 


# between_SS : 클러스터 간 분산 정도 -> 분산이 클 수록 클러스터끼리 확연한 분리


# within_SS : 클러스터 내 데이터의 분산 정도 -> 작을수록(밀집) 클러스터가 잘 구분

# between_SS 가 클 수록 within_SS가 작아짐

# total_SS = between_SS + within_SS 

   -> totalss 값이 클 수록 클러스터가 잘 분류되었다는 의미 (클러스터 간 분산이 크고, 클러스터 내 관측치들은 밀집)


> kms$totss

[1] 428461.7

> kms$centers

     energy  protein       fat    calcium     iron

1 361.66667 18.66667 31.000000   8.666667 2.433333

2 168.18182 21.09091  8.000000  12.090909 2.027273

3 270.00000 19.66667 20.666667   9.000000 2.533333

4  98.33333 14.66667  3.166667 101.333333 2.883333

5 180.00000 22.00000  9.000000 367.000000 2.500000

> kms$withinss

[1]  5142.253  9237.236  1587.420 19329.242     0.000



# 변수간 관계 확인

> plot(nutrient, col = kms$cluster)

# energy 와 fat 컬럼은 서로 강한 상관관계를 갖는 것을 확인 가능

   - 상관관계가 커질수록 클러스터가 명확히 구분

   - 그래프를 통해 대략적으로, 열량별로 클러스터링이 되지 않았나 예상 가능 (저열량 ~ 고열량 식품)

   - 그래프로 컬럼의 힌트를 얻고 분류분석에 적용할 수 있음

   - 클러스터의 목적은 세부적으로 데이터를 분석해서 정답(어떻게 분류되는지의 기준)을 찾고 분류 분석에 적용하기 위함



# K 변화에 따른 withinss의 변화

> within <- c()

> for(i in 1:10) {

     within[i] <- sum(kmeans(nutrient, centers = i)$withinss)

   }

> plot(1:10, within, type="b", xlab = "Number of Clusters", ylab = "Within group sum of squares")

# withinss(클러스터 내부 데이터의 분산 정도)의 변화를 보면,

     K가 증가할수록, 클러스터 내의 분산이 작아지는 것을 확인할 수 있음



# K 변화에 따른 betweenss의 변화

> between <- c()

> for(i in 1:10) {

     between[i] <- sum(kmeans(nutrient, centers = i)$betweenss)

   }

> plot(1:10, between, type="b", xlab = "Number of Clusters", ylab = "between group sum of squares")

betweenss(클러스터 간 분산 정도)의 변화를 보면,

     K가 증가할수록, 클러스터 간 분산이 높아지는 것을 확인할 수 있음



# K 변화에 따른 정확도의 변화

> bet_ss <- c()

> for (i in 1:10) {

     kms <- kmeans(scale(iris[,c(3,4)]) , i)

     bet_ss[i] <- round(kms$betweenss / kms$totss * 100,1)

   }


> y_name = paste("between_ss","\n", "/", "\n", "total_ss", collapse = '')

> par(oma=c(0,1,0,0))        # 그래프 여백 조절(하,좌,상,우)

> par(mgp=c(1,0.1,0))       # 그래프 내 축 여백 조절(제목, 눈금, 지표선)

> plot(1:10, bet_ss, type="b", 

        xlab = "Number of Clusters",

        ylab = y_name, ylim=c(0,100), las = 1)

# 클러스터의 개수 K가 증가할수록, 예측도가 높이지는 것을 확인할 수 있음





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