brunch

You can make anything
by writing

C.S.Lewis

by 첨물 May 19. 2021

빅분기실기 연습(7)

R프로그램_군집화(Kmeans)

머신러닝을 크게 세 가지로 구별하면


1 지도 학습 (X, Y 가 각각 주어지면, 임의의 X에 대하여 Y를 예측)

2 비지도 학습(X 들만 주어진 상태에서 각각의 특성들을 가지고 분류하여 Y를 예측)

3. 강화 학습 (에러를 줄이면 점수를 주면서 최적의 방법을 찾는 것. 알파고)


지난번에 의사결정 나무 방법을 통하여 IRIS의 네 가지 변수(꽃잎 길이, 꽃잎 너비, 꽃받침 길이, 꽃받침 너비)와 붓꽃의 종류가 주어진 상태에서 각각의 변수들의 값이 어떨 때 어떻게 꽃의 종류가 분류가 되었는지 찾아보고, 임의의 붓꽃이 주어지면 이게 의사결정 나무를 통해 붓꽃의 종류를 맞출 수 있는 예제를 해 보았다. 이것은 위 머신러닝 중에 지도 학습에 해당한다.


 그럼 네 개의 변수 값들만 알고 있을 때, 3종의 꽃으로 분류해 볼 수 있는 방법이 없을까? 비지도 학습... 그중에 군집화가 있고, 대표적인 것이 Kmeans이다. 각각의 특성들을 가지고 분포되어 있는 점들이 있을 때 분류하고 싶은 개수만큼 임의의 점을 찍은 후 그 점과 가까운 것들끼리로 묶는다. 각각 묶인 그룹의 평균값을 다시 중심점으로 해서 다시 한번 전체 점들을 분류한다. 이렇게 몇 번을 거듭하면 더 이상 중심점이 옮겨지지 않을 때 분류가 끝나게 된다.





그럼 R로 구현해 보자


data(iris) #데이터 불러오기

a<-iris

head(a) #데이터 앞부분 보기


> head(a)

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species

1          5.1         3.5          1.4         0.2  setosa

2          4.9         3.0          1.4         0.2  setosa

3          4.7         3.2          1.3         0.2  setosa

4          4.6         3.1          1.5         0.2  setosa

5          5.0         3.6          1.4         0.2  setosa


6          5.4         3.9          1.7         0.4  setosa


음. Species에 각각의 꽃 종류가 표시되어 있다. 일단 이것을 없애자.



a$Species = NULL


그리고 kmeans 함수에 a 값을 넣고, 3개로 분류해보자. R은 쉽게 이걸 한 번에 할 수 있다. 150개의 데이터를 3개(cluster에 1,2,3번으로 표시)로 구별했고, centers가 12로 된 것 보니, 아마 12번을 거쳐서 최적화한 것 같다.


kc<-kmeans(a,3) #종류가 3개인 군집분석 (비지도 학습)

summary(kc)


> summary(kc)

             Length Class  Mode   

cluster      150    -none- numeric

centers       12    -none- numeric

totss          1    -none- numeric

withinss       3    -none- numeric

tot.withinss   1    -none- numeric

betweenss      1    -none- numeric

size           3    -none- numeric

iter           1    -none- numeric


ifault         1    -none- numeric


그러면 어떻게 150개를 분류했는지 표로 보자. table 함수로 원래 iris$Species 를 1,2,3으로 각각 몇 개씩 할 당되었는지 보자. setosa는 50개 잘 분류했고, versicolor는 2번으로 48개, 3번으로 2개로 분류했고, virginica는 2번으로 14개, 3번으로 36개를 분류했다. 지난번 의사결정 나무에서도 versicolor는 49개를 제대로 하고, 1개는 virginica로 나누고, virginica는 45개를 제대로 하고, 5개는 versicolor로 나누는 의사결정식을 만들었었는데, 군집화 kmeans는 각각의 특성만으로 나누었으니 맞추는 확률이 떨어진 것 같다.  


table(iris$Species,kc$cluster)


> table(iris$Species,kc$cluster)

            

              1  2  3

  setosa     50  0  0

  versicolor  0 48  2

  virginica   0 14 36


그리고 plot을 그려보자. 꽃잎(Petal)의 길이와 너비만으로 x축, y축을 표현해서 그려보려고 한다. color 값은 1,2,3번의 값을 가지는 것으로 구별하려고 kc$cluster로 했다. 그림을 보면 좌측 하단이 setosa로 보이고, 이것은 아래 두 개와는 별개로 분류가 잘 되어 있다. 지난번 의사 결정 나무에서 분류한 것과 비교해보자. 그러면 왼쪽 아래 검은 점은 setosa로 보이고, 빨간 점은 versicolor, 녹색점은 virginica로 볼 수 있다. 중간에 섞여 있는 점들이 보이는데, 이것이 두 종류를 헷갈리게 만드는 역할을 하였다.



그럼 혹시 꽃받침의 길이와 너비로 분류하면 더 잘할 수 있을까? 아래 그림을 보면 검은색 점은 별개로 떨어져 있지만 여전히 빨간색과 녹색은 약간 섞여 있어 보인다.



plot(a[c("Sepal.Length", "Sepal.Width")], col=kc$cluster)


 여기서 빅분기 실기연습(1)에서 해 보았던 공분산, 즉 꽃잎의 길이와 꽃받침의 길이 간의 상관성이 있는지 보고 싶어 진다. 즉 변수들 간의 상관성이 있는지 살펴보는 것.



.libPaths("c:/myRproject/Library") #패키지 불렀을 때 에러 안 나도록 함

install.packages("corrplot")

library(corrplot)

mcor=cor(a)

mcor

round(mcor,2) #소수 둘째 자리로 만듦

corrplot(mcor)



음. 이걸 보면 꽃받임 길이(Sepal.Length)와 꽃잎 길이(Petal.Length), 꽃잎 너비(Petal.Width) 간에 강한 상관성이 나오는 것을 알 수 있다.



도대체 붓꽃 3종이 어떻게 생겼는지 다시 보자.


Setosa(좌),  Versicolor(중), Verginica(우)

와. 다 예쁜 꽃으로만 보이는데 이걸 구별하다니... 가장 가장자리가 꽃받임이고, 가장 안쪽에 길게 뻗은 것이 꽃잎이구나. 구글에 찾아보면 헷갈리게 표시된 것이 많았다. 꽃잎이 안쪽, 그걸 받이는 것이 가장 바깥쪽.



가장 안쪽 꽃잎만 보니, 가장 작은 게 setosa로 보이고, 점점 길어지는 순으로 versicolor, verginica로 구별할 수 있다. 그럼 위에서 kmeans로 분류한 것과 어느 정도 맞아떨어진다. 그런데 눈으로 보아도 versicolor와 virginica는 비슷해 보인다.



꽃잎이 길수록, 꽃받임의 길이가 길어지는 것은 어쩌면 당연한 것이리라. 마지막으로 공분산이 큰 변수들끼리 이것도 산점도 그래프로 그려보자.


library(lattice)

xyplot(Sepal.Length~Petal.Length, data=a, col=kc$cluster)

xyplot(Sepal.Length~Petal.Width, data=a, col=kc$cluster)

xyplot(Petal.Length~Petal.Width, data=a, col=kc$cluster)


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari