머신러닝(Machine Learning)/추천 시스템(Recommendation System)

Association Analysis / Association Rule / Apriori 알고리즘 - 3 of 3

leebaro 2017. 10. 3.
728x90


연관글 보기

Association Analysis / Association Rule / Apriori 알고리즘 - 1 of 3

Association Analysis / Association Rule / Apriori 알고리즘 - 2 of 3

Association Analysis / Association Rule / Apriori 알고리즘 - 3 of 3



시각화를 이용하면 수 많은 데이터에서는 보이지 않는 특징이 쉽게 눈에 띈다는 장점이 있다. 그래프를 그리기 위해 상관관계를 보여주는 행렬을 구해서SNA(social Network Analysis) 라이브러리의 gplot 함수를 이용해 weighted graph를 그려보도록 하자.

상관관계를 그리기 위해서는 데이터타입이 matrix여야 한다. 하지만 아래과 같이 build 변수는 데이터프레임이다. 그렇기 때문에 as.matrix 함수를 이용해 형변환을 시켜줘야 한다.

str(build)
## 'data.frame':    20 obs. of  12 variables:
##  $ 병원          : num  1 0 0 0 1 0 0 1 0 0 ...
##  $ 약국          : num  1 0 0 0 0 0 0 1 0 0 ...
##  $ 카페          : num  0 0 1 1 0 1 0 0 0 0 ...
##  $ 휴대폰매장    : num  1 0 0 0 0 1 0 1 0 0 ...
##  $ 일반음식점    : num  0 1 0 0 1 0 0 0 0 1 ...
##  $ 패밀리레스토랑: num  0 1 0 0 1 0 1 0 0 1 ...
##  $ 당구장        : num  0 1 0 0 0 0 0 0 1 0 ...
##  $ 보습학원      : num  0 0 1 1 0 0 0 0 0 0 ...
##  $ 슈퍼마켓      : num  0 0 0 0 0 0 0 0 1 0 ...
##  $ 은행          : num  0 0 1 1 0 0 0 0 0 0 ...
##  $ 편의점        : num  0 1 0 0 1 0 0 0 0 1 ...
##  $ 화장품        : num  1 0 0 0 1 0 1 0 0 1 ...

데이터타입이 데이터프레임인 변수는 아래와 같이 보여진다.

build
##    병원 약국 카페 휴대폰매장 일반음식점 패밀리레스토랑 당구장 보습학원
## 1     1    1    0          1          0              0      0        0
## 2     0    0    0          0          1              1      1        0
## 3     0    0    1          0          0              0      0        1
## 4     0    0    1          0          0              0      0        1
## 5     1    0    0          0          1              1      0        0
## 6     0    0    1          1          0              0      0        0
## 7     0    0    0          0          0              1      0        0
## 8     1    1    0          1          0              0      0        0
## 9     0    0    0          0          0              0      1        0
## 10    0    0    0          0          1              1      0        0
## 11    0    0    1          0          0              0      0        1
## 12    0    0    0          0          1              1      1        0
## 13    1    1    0          1          0              0      0        0
## 14    0    0    0          0          1              1      0        0
## 15    0    0    0          0          1              1      0        0
## 16    0    0    1          0          0              0      0        1
## 17    0    0    0          0          1              1      1        0
## 18    1    1    0          1          0              0      0        0
## 19    0    0    0          0          1              1      1        0
## 20    1    1    0          1          0              0      0        0
##    슈퍼마켓 은행 편의점 화장품
## 1         0    0      0      1
## 2         0    0      1      0
## 3         0    1      0      0
## 4         0    1      0      0
## 5         0    0      1      1
## 6         0    0      0      0
## 7         0    0      0      1
## 8         0    0      0      0
## 9         1    0      0      0
## 10        0    0      1      1
## 11        0    1      0      0
## 12        0    0      0      0
## 13        0    0      0      0
## 14        0    0      1      1
## 15        0    0      1      1
## 16        0    1      0      0
## 17        0    0      0      0
## 18        0    0      0      0
## 19        0    0      0      0
## 20        0    0      0      0

아래와 같이 matrix로 형변환을 하면 출력 결과가 달라진 것을 볼 수 있다. 사실 눈으로 볼 때는 큰 차이는 없다.

as.matrix(build)
##       병원 약국 카페 휴대폰매장 일반음식점 패밀리레스토랑 당구장 보습학원
##  [1,]    1    1    0          1          0              0      0        0
##  [2,]    0    0    0          0          1              1      1        0
##  [3,]    0    0    1          0          0              0      0        1
##  [4,]    0    0    1          0          0              0      0        1
##  [5,]    1    0    0          0          1              1      0        0
##  [6,]    0    0    1          1          0              0      0        0
##  [7,]    0    0    0          0          0              1      0        0
##  [8,]    1    1    0          1          0              0      0        0
##  [9,]    0    0    0          0          0              0      1        0
## [10,]    0    0    0          0          1              1      0        0
## [11,]    0    0    1          0          0              0      0        1
## [12,]    0    0    0          0          1              1      1        0
## [13,]    1    1    0          1          0              0      0        0
## [14,]    0    0    0          0          1              1      0        0
## [15,]    0    0    0          0          1              1      0        0
## [16,]    0    0    1          0          0              0      0        1
## [17,]    0    0    0          0          1              1      1        0
## [18,]    1    1    0          1          0              0      0        0
## [19,]    0    0    0          0          1              1      1        0
## [20,]    1    1    0          1          0              0      0        0
##       슈퍼마켓 은행 편의점 화장품
##  [1,]        0    0      0      1
##  [2,]        0    0      1      0
##  [3,]        0    1      0      0
##  [4,]        0    1      0      0
##  [5,]        0    0      1      1
##  [6,]        0    0      0      0
##  [7,]        0    0      0      1
##  [8,]        0    0      0      0
##  [9,]        1    0      0      0
## [10,]        0    0      1      1
## [11,]        0    1      0      0
## [12,]        0    0      0      0
## [13,]        0    0      0      0
## [14,]        0    0      1      1
## [15,]        0    0      1      1
## [16,]        0    1      0      0
## [17,]        0    0      0      0
## [18,]        0    0      0      0
## [19,]        0    0      0      0
## [20,]        0    0      0      0

아래와 같이 build 변수를 t()함수와 %*% 연산자를 사용해 상관관계를 구하면 에러가 발생한다. t()함수는 matrix 데이터타입의 변수만 사용할 수 있기 때문이다.

b2 <- t(build) %*% build
Error in t(build) %*% build : 
  requires numeric/complex matrix/vector arguments


위와 같은 에러를 방지하기 위해서 아래와 같이 build 변수를 matrix 데이터타입으로 변환한다.

build_m <- as.matrix(build)
build_m
##       병원 약국 카페 휴대폰매장 일반음식점 패밀리레스토랑 당구장 보습학원
##  [1,]    1    1    0          1          0              0      0        0
##  [2,]    0    0    0          0          1              1      1        0
##  [3,]    0    0    1          0          0              0      0        1
##  [4,]    0    0    1          0          0              0      0        1
##  [5,]    1    0    0          0          1              1      0        0
##  [6,]    0    0    1          1          0              0      0        0
##  [7,]    0    0    0          0          0              1      0        0
##  [8,]    1    1    0          1          0              0      0        0
##  [9,]    0    0    0          0          0              0      1        0
## [10,]    0    0    0          0          1              1      0        0
## [11,]    0    0    1          0          0              0      0        1
## [12,]    0    0    0          0          1              1      1        0
## [13,]    1    1    0          1          0              0      0        0
## [14,]    0    0    0          0          1              1      0        0
## [15,]    0    0    0          0          1              1      0        0
## [16,]    0    0    1          0          0              0      0        1
## [17,]    0    0    0          0          1              1      1        0
## [18,]    1    1    0          1          0              0      0        0
## [19,]    0    0    0          0          1              1      1        0
## [20,]    1    1    0          1          0              0      0        0
##       슈퍼마켓 은행 편의점 화장품
##  [1,]        0    0      0      1
##  [2,]        0    0      1      0
##  [3,]        0    1      0      0
##  [4,]        0    1      0      0
##  [5,]        0    0      1      1
##  [6,]        0    0      0      0
##  [7,]        0    0      0      1
##  [8,]        0    0      0      0
##  [9,]        1    0      0      0
## [10,]        0    0      1      1
## [11,]        0    1      0      0
## [12,]        0    0      0      0
## [13,]        0    0      0      0
## [14,]        0    0      1      1
## [15,]        0    0      1      1
## [16,]        0    1      0      0
## [17,]        0    0      0      0
## [18,]        0    0      0      0
## [19,]        0    0      0      0
## [20,]        0    0      0      0

t()함수는 행렬을 전치를 해주는 함수이다. 아래 그림과 같이 전치란 행렬의 열과 행의 위치를 바꿔주는 것을 의미한다. 수식을 보면 XT는 X행렬의 전치행렬이다.[각주:1]

transpose

transpose

위의 build_m 행렬과 아래 build_m 행렬의 전치행렬을 비교해 보자.

t(build_m)
##                [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
## 병원              1    0    0    0    1    0    0    1    0     0     0
## 약국              1    0    0    0    0    0    0    1    0     0     0
## 카페              0    0    1    1    0    1    0    0    0     0     1
## 휴대폰매장        1    0    0    0    0    1    0    1    0     0     0
## 일반음식점        0    1    0    0    1    0    0    0    0     1     0
## 패밀리레스토랑    0    1    0    0    1    0    1    0    0     1     0
## 당구장            0    1    0    0    0    0    0    0    1     0     0
## 보습학원          0    0    1    1    0    0    0    0    0     0     1
## 슈퍼마켓          0    0    0    0    0    0    0    0    1     0     0
## 은행              0    0    1    1    0    0    0    0    0     0     1
## 편의점            0    1    0    0    1    0    0    0    0     1     0
## 화장품            1    0    0    0    1    0    1    0    0     1     0
##                [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
## 병원               0     1     0     0     0     0     1     0     1
## 약국               0     1     0     0     0     0     1     0     1
## 카페               0     0     0     0     1     0     0     0     0
## 휴대폰매장         0     1     0     0     0     0     1     0     1
## 일반음식점         1     0     1     1     0     1     0     1     0
## 패밀리레스토랑     1     0     1     1     0     1     0     1     0
## 당구장             1     0     0     0     0     1     0     1     0
## 보습학원           0     0     0     0     1     0     0     0     0
## 슈퍼마켓           0     0     0     0     0     0     0     0     0
## 은행               0     0     0     0     1     0     0     0     0
## 편의점             0     0     1     1     0     0     0     0     0
## 화장품             0     0     1     1     0     0     0     0     0

matrix 데이터타입으로 형변환 후 아래와 같이 t()함수와 %*% 연산자를 이용해 상관관계를 구한다.

b2 <- t(build_m) %*% build_m
b2
##                병원 약국 카페 휴대폰매장 일반음식점 패밀리레스토랑 당구장
## 병원              6    5    0          5          1              1      0
## 약국              5    5    0          5          0              0      0
## 카페              0    0    5          1          0              0      0
## 휴대폰매장        5    5    1          6          0              0      0
## 일반음식점        1    0    0          0          8              8      4
## 패밀리레스토랑    1    0    0          0          8              9      4
## 당구장            0    0    0          0          4              4      5
## 보습학원          0    0    4          0          0              0      0
## 슈퍼마켓          0    0    0          0          0              0      1
## 은행              0    0    4          0          0              0      0
## 편의점            1    0    0          0          5              5      1
## 화장품            2    1    0          1          4              5      0
##                보습학원 슈퍼마켓 은행 편의점 화장품
## 병원                  0        0    0      1      2
## 약국                  0        0    0      0      1
## 카페                  4        0    4      0      0
## 휴대폰매장            0        0    0      0      1
## 일반음식점            0        0    0      5      4
## 패밀리레스토랑        0        0    0      5      5
## 당구장                0        1    0      1      0
## 보습학원              4        0    4      0      0
## 슈퍼마켓              0        1    0      0      0
## 은행                  4        0    4      0      0
## 편의점                0        0    0      5      4
## 화장품                0        0    0      4      6

코드를 실행한 결과 위와 같은 결과를 얻을 수 있다. 간단히 살펴본다면 병원이 있는 병원과 약국이 함께 있는 건물은 5개, 휴대폰매장과 카페가 같이 있는 건물은 1곳이 있다는 것을 확인할 수 있다. 그럼 여기서 %*% 연산자는 행렬을 곱해주는 연산자이다. 간단히 위의 예제에서는 각 건물에 있는 건물들이 함께 있는 수를 구해준다고 이해하면 된다. 그 외에도 %%, %/%, %in%와 같은 연산자도 있다.[각주:2]

아래 코드는 b2의 대각원소를 추출해서 b2 변수에서 대각원소의 값을 빼주는 것이다. 예를들어 [1,1] 위치는 병원X병원의 값인데 당연히 같은 상점의 상관관계가 가장 높을 것이기 때문에 제거해 준다.

b2.w <- b2 - diag(diag(b2))
b2.w
##                병원 약국 카페 휴대폰매장 일반음식점 패밀리레스토랑 당구장
## 병원              0    5    0          5          1              1      0
## 약국              5    0    0          5          0              0      0
## 카페              0    0    0          1          0              0      0
## 휴대폰매장        5    5    1          0          0              0      0
## 일반음식점        1    0    0          0          0              8      4
## 패밀리레스토랑    1    0    0          0          8              0      4
## 당구장            0    0    0          0          4              4      0
## 보습학원          0    0    4          0          0              0      0
## 슈퍼마켓          0    0    0          0          0              0      1
## 은행              0    0    4          0          0              0      0
## 편의점            1    0    0          0          5              5      1
## 화장품            2    1    0          1          4              5      0
##                보습학원 슈퍼마켓 은행 편의점 화장품
## 병원                  0        0    0      1      2
## 약국                  0        0    0      0      1
## 카페                  4        0    4      0      0
## 휴대폰매장            0        0    0      0      1
## 일반음식점            0        0    0      5      4
## 패밀리레스토랑        0        0    0      5      5
## 당구장                0        1    0      1      0
## 보습학원              0        0    4      0      0
## 슈퍼마켓              0        0    0      0      0
## 은행                  4        0    0      0      0
## 편의점                0        0    0      0      4
## 화장품                0        0    0      4      0

diag()함수가 어떤 값을 추출하는지 아래 결과를 보면 쉽게 이해할 수 있다. diag()함수를 사용하면 대각원소를 추출한다.

diag(b2)
##           병원           약국           카페     휴대폰매장     일반음식점 
##              6              5              5              6              8 
## 패밀리레스토랑         당구장       보습학원       슈퍼마켓           은행 
##              9              5              4              1              4 
##         편의점         화장품 
##              5              6

아래와 같이 diag 함수를 두번 사용하면 matrix 구조로 데이터를 보여준다. b2에서 아래 값을 빼준다면, 대각원소 값은 모두 0이 나올 것이다.

diag(diag(b2))
##       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
##  [1,]    6    0    0    0    0    0    0    0    0     0     0     0
##  [2,]    0    5    0    0    0    0    0    0    0     0     0     0
##  [3,]    0    0    5    0    0    0    0    0    0     0     0     0
##  [4,]    0    0    0    6    0    0    0    0    0     0     0     0
##  [5,]    0    0    0    0    8    0    0    0    0     0     0     0
##  [6,]    0    0    0    0    0    9    0    0    0     0     0     0
##  [7,]    0    0    0    0    0    0    5    0    0     0     0     0
##  [8,]    0    0    0    0    0    0    0    4    0     0     0     0
##  [9,]    0    0    0    0    0    0    0    0    1     0     0     0
## [10,]    0    0    0    0    0    0    0    0    0     4     0     0
## [11,]    0    0    0    0    0    0    0    0    0     0     5     0
## [12,]    0    0    0    0    0    0    0    0    0     0     0     6

마지막으로 gplot 함수를 이용해 그래프를 그려준다. gplot의 도움말을 보면 전체 파라미터에 대한 기능을 확인할 수 있다.[각주:3]

if(!require("sna")) install.packages("sna")
gplot(b2.w, displaylabel = T, vertex.cex = sqrt(diag(b2)), vertex.col = "green", edge.col = "blue", boxed.labels = F, arrowhead.cex = 0.3, label.pos = 3, edge.lwd = b2.w*2)

gplot을 이용해 그래프를 확인해 보면 위와 같은 결과를 볼 수 있다. 카페, 보습학원, 은행이 같은 건물에 있는 경우가 많고 편의점, 패밀리레스토랑, 일반음식점 같은 식당이 같은 건물에 있다는 것을 볼 수 있다. 식사 후 당구장은 많이 가기 때문인지 식당과 당구장도 같은 같은 건물에 있는 것을 볼 수 있다.

이와 같이 그래프를 이용해 상관관계를 확인하면 상점간의 관계를 이해할 수 있고, 이와 같은 실제 데이터가 있다면, 내가 상점을 해야 할 경우 어떤 상점들이 관계가 있는지 확인하고 내가 입점하려는 건물에 상관관계가 높은데 아직 없는 상점이 있다면 도전해볼 수 있을 것이다.


연관글 보기

Association Analysis / Association Rule / Apriori 알고리즘 - 1 of 3

Association Analysis / Association Rule / Apriori 알고리즘 - 2 of 3

Association Analysis / Association Rule / Apriori 알고리즘 - 3 of 3

  1. https://ko.wikipedia.org/wiki/%EC%A0%84%EC%B9%98%ED%96%89%EB%A0%AC↩ [본문으로]
  2. http://rfriend.tistory.com/35↩ [본문으로]
  3. https://www.rdocumentation.org/packages/sna/versions/2.4/topics/gplot↩ [본문으로]
728x90