지난 포스팅에서는 시간/순서를 고려한 순차 패턴 분석 (sequence pattern analysis)에 대해서 알아보았습니다.

 

이번 포스팅에서는 연관규칙 분석의 대상이 되는 항목의 분류체계 (Taxonomy)와 가상 항목 (Virtual Item)에 대해서 알아보겠습니다. 

 

이번 포스팅에서 다루려는 주제는 1~2시간 짜리 연관규칙 교육 프로그램에서는 시간이 부족한 관계로 잘 안다루는 내용입니다만, 매우 중요한 부분입니다.  실전 프로젝트에서 보면 "써먹을 수 있는 규칙"이 나오느냐, 안나오느냐에 상당히 관련이 있는 부분이구요, 사실 순서상으로 보면 지금 쓰는 이 글이 연관규칙 분석을 할 때 현업(業 전문가, domain expert)과 함께 프로젝트 초반에 분석 시나리오 잡을 때 의사결정을 해야만 하는 매우 중요한 부분입니다.

 

 

 

1) 항목 분류 체계 (Taxonomy)

 

상품 구매 연관규칙을 분석한다고 가정했을 때, 상품 분류 체계를 예로 생각하시면 됩니다.  백화점, 마트, 홈쇼핑, 인터넷쇼핑몰, 슈퍼마켓 등... 유통업체는 아래와 같은 형태의 대/중/소/세/세부속성별로 계층(Hierarchy)을 가진 상품 분류 체계를 가지고 있습니다.

 


 * Reference: "Data Mining Techniques", by Michael J.A.Berry, Gordon S.Linoff 



소분류 -> 중분류 -> 대분류 방향으로 올라갈 수록 일반화(generalization), 추상화 되며, 소분류 -> 세분류 -> 세부속성 방향으로 내려갈 수록 구체적(detail)인 항목이 됩니다.

 

이게 연관규칙 도출에 왜 중요한지에 대해서 예를 들어서 설명해보겠습니다.

 

너무 상위 항목 (대분류, 혹은 중분류)을 가지고 연관규칙을 분석하면 "실행 가능한 수준의 규칙"이 아닌 경우가 많습니다.  한마디로 업무에 적용하기가 애매한 경우입니다.  가령, 대분류를 가지고 분석을 해서 "{냉동식품} → {아동의류} 라는 연관규칙이 나왔다고 해봅시다.  '냉동식품'이나 '아동의류' 담당 매니저, 마케터에게 이 규칙을 가져가면 아마 "so what?", "나보고 뭘 어쩌라고요?" 소리 듣기 십상입니다.

 

반면에, 너무 하위 항목 (가령, 세부속성의 '브랜드')을 가지고 연관규칙 분석을 수행하면 당장 실행가능한 규칙이 나올 여지는 있습니다만, 단점으로는 일단 연산 시간이 무척 많이 걸립니다.  그리고 빈도수가 너무 작은 다수의 '브랜드'들의 경우 비빈방항목 pruning 원칙에 의해 규칙에 안나타날 수 있습니다. 

 

결국 너무 상위 level이어도 안되고, 너무 하위 level이어도 안좋고 해서, 적당한(?) 수준을 찾아서 분석을 수행해야 합니다. 그리고 여기서 '적당한(?)'은 "분석 목적이 무엇인가?", "어디에 써 먹을려고 연관규칙 분석을 하는 것인가?", "최종 사용자는 누구이며 그 사용자가 만족하는 수준은 어느 level인가?" 등의 질문에 답하는 과정에서 결정이 된다고 보면 됩니다.  이런 질문에 답하려면 현업(domain expert)이 꼭 필요하겠지요?  業은 잘 모르는 분석전문가가 현업 참여없이 단독으로 taxonomy 분석 level 정해놓고 '연관규칙이 이렇게 나왔네요'하고 가져가면 그 규칙을 사용할 현업한테서 한 소리 (가령, '이거 왜 하셨어요?', '이걸로는 암것도 못하겠는걸요...') 듣고 분석을 처음부터 다시 수행해야할 수도 있습니다. 

 

사실, 더 큰 문제는 상품분류체계(taxonomy) 관리가 잘 안되는 경우가 매우 많다는 점입니다.  MD 담당자가 새로 바뀌면 기존의 상품분류체계와 align을 안시키고 이상한 상품코드를 새로 추가하는 경우도 있구요, 단종된 상품코드는 그때 그때 정리를 해줘야 하는데요, 그대로 두고 있는 경우도 있습니다. 이거 교통정리하는게 참 고역인데요, 자칫 연관규칙 분석하는 업무량보다 상품분류체계 정비하는게 더 시간을 많이 잡아먹는, 배보다 배꼽이 더 큰 웃긴 일이 생길 수도 있습니다. -_-;

 

또 하나 문제는요, 상품분류체계가 마케텅의 입맛에 딱 안맞을 수 있다는 점입니다. 보통은 MD가 상품분류체계를 기획하고, 정보를 입력하고, 관리를 합니다.  그러다 보니 '마케팅' 부서의 활용 관점은 안들어가 있다고 보면 됩니다.  바로 여기서 가상항목(virtual item)에 대한 필요성이 생깁니다.

 

 

 

2) 가상 항목 (Virtual Item)

 

가상 항목 (virtual item) 이란 원래의 항목분류체계(taxonomy)에는 없는 가상의 항목을 새로 만들어 사용하는 것입니다. 가령, 아래의 예처럼 원래의 항목분류체계에는 'Handbag'과 'Watch'의 카테고리에 각 각 속해있던 상품(item)들을 '브랜드'라는 새로운 관점을 가지고 묶어서 'GUCCI handbag'과 'GUCCI watch'를 'GUCCI Products'라는 새로운 가상의(기존에는 없었던) 항목(virtual item)으로 만들고, 'DKNY handbag'과 'DKNY watch'를 'DKNY products'라는 새로운 가상의 항목(virtual item)으로 만들어서 연관규칙 분석에 사용하게 됩니다.

 

 

 

위의 예에서는 상품 카테고리 간 동일한 브랜드별로 virtual item을 만들어보았습니다. 

 

이 외에도 분석해서 사용하려는 목적에 따라서 다양한 아이디어를 생각해볼 수 있습니다.

가령, 식품을 수입품과 국산품으로 구분하는 virtual item 이라든지, 유아식품 중 아토피 관련 식품이나 유기농 식품 여부 virtual item도 생각해볼 수 있습니다.  상품구매 요일(평일, 공휴일)이나 시즌, 아니면 event 성 (생일, 기념일, 00day 관련 등) 상품에 대한 virtual item도 생각해 볼 수 있겠습니다. 

 

비빈발항목을 묶어서 빈발항목으로 만든 다음에 이에 적당한 naming을 해서 가상항목으로 만들어서 분석을 하는 것도 재치있는 분석요령입니다.  

 

 

 

3) Segmented multiple sets mining

 

마지막으로, 실무 분석할 때 요긴하게 써먹곤 했던 것 하나 더 말씀드리자면, 연관규칙 도출에 영향이 클 것으로 예상되는 특정 기준, 관점이 있다면 이를 가지고 사전에 데이터셋을 나누어서 연관규칙 분석을 하라는 것입니다.

 

가령, 아래의 예처럼 상품 연관구매 규칙을 분석한다고 했을 때, 성(gender)과 연령(age)에 따라서 상품 구매 패턴이 큰 차이를 보일 것이라고 예상을 한다면 성별과 연령대별로 segments를 나누어서 각 segment별로 나누어서 연관구매규칙을 분석하면 된다는 뜻입니다.

 

 

 

물론 지지난번에 포스팅했던 '범주형 및 연속형 데이터의 연관규칙 분석' 방법을 활용해서 연령대, 성별을 이항변수화(binarization)하여 연관규칙 분석을 수행해도 되긴 합니다.  편한 방법을 사용하시면 되겠습니다.

 

다음 포스팅에서는 군집분석(Clustering)에 대해서 알아보도록 하겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾸욱 눌러주세요. ^^

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 최유정 2016.06.08 15:01  댓글주소  수정/삭제  댓글쓰기

    기계학습 책 몇권보는것 보다 포스팅된 글 한번보는게 훨씬 더 많은 도움이됩니다! 특히 실무에서의 팁?은 책에선 알려주지 않는 내용이라 너무 좋아요ㅠㅠ

  2. 2016.07.15 10:06  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • R Friend R_Friend 2016.07.16 00:12 신고  댓글주소  수정/삭제

      제가 여행업에 대해 잘 모르다 보니 일반 소비자로서 여행에 대한 상식에 입각해서 답글을 달아봅니다. 아래 답글 보시고서 쓸만한 것이 있으면 사용해보시구요, 혹시 말도 안되는 소리이거나 아니면 업계종사자라면 상식적으로 알고 있고 이미 적용하고 있는 것들이라면 제가 업계종사자가 아니라 잘 몰라서 그런거라고 이해해주시기 바랍니다. ^^'

      (1) 말씀하신 분석하신 방법대로 하니 뻔한 규칙만 나온다고 하셨는데요, 혹시 여행 상품이라는 것이 1년에 한두번밖에 구매 안하고, 특히 고관여 목적성(!) 온라인 방문이 많다보니 필요한 정보만 확인하고 웹을 이탈하는 고객이 많기 때문이 아닌가 싶습니다(가설). 만약 이렇다면 연관규칙이 잘 안나올거 같습니다.

      대신에 장기(3-5년) 여행상품 구매 데이터를 활용해서 순차분석(sequence analysis)를 해보시면 어떨까하고 권해봅니다. 상품 texonomy & virtual item 아이디어 내서 다양하게 시도해보시면 좋겠습니다.

      고객을 Life-stage와 여행상품 구매빈도, 여행상품 특성에 따라서 세분화한 후에 => 세분집단별로 여행 재구매 주기(3~5년 기간 동안의 data로 분석), 여행 순차 패턴 분석해보시면 유의미한 패턴이 나올 수도 있을거 같습니다.


      (2) 고객 identification이 가능하고 contact 정보가 있는 온라인 로그인 고객의 클릭스트림, 모바일앱 사용자의 클릭스트림 데이터를 가지고
      => 클릭 상품명, 페이지 노출 지속 시간(오래 봤을수록 관여도 높다고 가정), 클릭 일시 정보를 저장/가공해서
      => event rule 설정 : if 관심상품등록 or 클릭&지속노출시간xx분 이상 & 클릭후 xx일 이내 미구매 then SMS 메시징 & 여행상품정보 링크 제공 & 프로모션 오퍼 제공

      의 event-based automated marketing을 시스템에 걸어놓고 성과를 살펴보는 것도 유의미할 것 같습니다. 단, 고객이 '내가 이거 관심있는줄 어떻게 알고 연락을 했지?'하고 너무 티나게 하면 깜놀할 수 있으므로 고객의 부정적 반응이 없는지 초반에는 좀 살펴봐야 할거 같습니다.


      (3) 온라인, 모바일은 클릭한 발자취가 고스란히 남으므로, 온라인, 모바일 UX 개선을 위한 분석 거리를 찾아보는 것도 재미있을거 같아요.

      예 : 페이지 메뉴간 클릭스트림 분석을 통해 메뉴 구성/분류가 잘못된것 찾기(클릭을 한번이라도 덜하고 쉽게 찾을수 있게)
      예 : 배치, 색상, 디자인...등 별 AB test


      (4) 분석을 위한 분석, 분석에만 그치고 매출에 영향을 끼치는 ,action 이 없는 분석 지양한다는 취지에서요, outbound campaign test marketing 을 다양하게 시도해보는 것도 의미가 있을것 같습니다. 분석하면 보통 타케팅 정교화에만 목을 매는 경향이 있는데요, 타케팅 말고도 outbound campaign에 영향을 미치는 것으로 오퍼, 채널, 메시지, 타이밍 등 다양합니다. 가설 기반 실험설계, 테스트, 성과평가(!!! 데이터 기반 의사결정/피드백!!!), 개선...등의 다양한 시도를 다수 해보는게 중요하고 꼭 필요합니다.


      (5) 여행 많이 가는 충성고객 선별, 고객 보상 프로그램, 고객 참여 프로그램 설계 :

      예) 로열티프로그램,
      모바일 LBS, 동영상, 사진 활용 여행후기, 내가 추천하는 여행지...
      지인 추천 보상 program...


      6) 현장CRM : 여행상품 판매 매장, 대리점, agent 가 세일즈하는 것을 지원할 수 있는 툴/시스템, 고객정보 제공(통합 profile, 파생변수)에 대해서 고민해보는것도 필요해 보입니다. 1차 고객 end user 말고 대리점, agent도 2차 고객이니깐요.


      7) online buzz crawling 해서 => text mining 해보는 것도 재미있을 것 같습니다.

      예: 여행사별 연관어 년도별 시계열 변화 비교, 감성분석,
      여행관련 핫한 키워드(예: 속초 포캣몬고 사냥 여행)


      8) 고객 이벤트 파악 가능한 제휴사(예: 청첩장 회사 결혼할 고객 파악 가능), 고객 니즈 파악가능한 회사(예: 온라인서점에서 '스페인 여행' 책 구매고객 => 스페인 여행상품 추천)와 제휴마케팅

      9) 여행 앱을 만들어서 고객정보도 획득하고, contact point/channel 도 확보하고, 고객이 여행 contents 를 생산해서 공유할 수 있도록 플랫폼을 제공하고, 여행상품 상담/판매도 하는 것도 생각해볼 수 있겠네요. (이미 하고 있을것도 같습니다만....)

      아래에 구글링해서 찾은 "The Best Travel Apps of 2015" 링클 걸어놓습니다. 잘된 여행 앱을 벤치마킹하면 좋은 추가 아이디어가 있을수도 있으니깐요.
      => http://www.pcmag.com/article2/0,2817,2422244,00.asp

  3. ass 2019.05.01 15:42  댓글주소  수정/삭제  댓글쓰기

    1) 항목 분류 체계 (Taxonomy)의 그림의 출처가 잘못된 것 같습니다. "경영을 위한 데이터마이닝 마케팅과 CRM 활용을 중심으로 2판", 313페이지, <그림 9-10>과 동일하다고 볼 수 있을 것 같습니다. 2) 가상 항목에서 사용하신 그림도 대학 강좌의 강의자료와 유사하나 별도로 언급하지는 않겠습니다.

지난번 포스팅에서는 범주형 및 연속형 데이터에 대한 연관규칙 분석에 대하여 알아보았습니다.

 

이번 포스팅에서는 시간(time), 순서(sequence)를 고려한 순차패턴분석(sequence pattern analysis)에 대하여 소개하겠습니다.

 

먼저, 연관규칙(association rule)과 순차패턴규칙의 차이점을 '분석 주안점', '활용 데이터 항목', '흥미도/유용성 평가 척도'의 관점에서 표로 비교해보면 아래와 같습니다.

 

If A then B 형식의 데이터 속에 숨겨져있는 규칙을 찾아낸다는 면에서는 같습니다만, 순차패턴분석의 경우 "What goes AFTER what?" 과 같이 시간/순서에 따른 사건의 규칙을 찾는다는 점, 데이터셋에 Identity information (Customer Identifier, or Event ID), TimeStamp (Sequence information, or Sequence ID) 변수가 있어야 한다는 점, 그리고 Support 척도만 제공할 뿐 연관규칙에서 썼던 Confidence, Lift는 없다는 점이 연관규칙과는 다릅니다.

 

 

 

 

 

순차패턴분석에서 사용하는 데이터셋은 아래처럼 고객ID (or Event ID)별로 TimeStampe (or Sequence ID)의 시간 순서로 거래 데이터가 정리된 형태(ordered by customer ID and TimeStamp)로 되어있습니다.

 

 

 

 

항목집합을 순서로 나타낸 리스트를 sequence라고 하며, 를 j번째 항목집합이라고 할 때 으로 표기합니다.

 

순차패턴분석에서 사용하는 규칙 흥미도 척도인 Support(s) = Sequence s를 포함하는 고객의 비율 입니다.

 

특정 최소 지지도(support) 이상을 가지는 sequence를 빈발 시퀀스(large sequence) 라고 합니다. 순차적 패턴 탐사 문제는 빈발 시퀀스 중에서 최대 시퀀스(maximal sequence)들을 찾는 것이라고 할 수 있습니다.

 

순차 패턴 분석 알고리즘 (Agrawal and Srikant, 1995)은 다음의 단계들로 구성되어 있습니다.

 

 

1) 정렬 단계 : Transaction database를 고객 sequence data로 전환한다.

 

2) 빈발항목집합 단계 : 고객 시퀀스의 항목집합 또는 이의 부분집합 중 최소 지지도(고객비율 사용) 이상인 것들을 빈발항목집합으로 도출한다. 편의상 각 빈발 항목집합에 일련번호를 부여한다.

 

3) 변환 단계 : 고객 시퀀스를 빈발항목집합을 사용한 시퀀스로 변환한다.

 

4) 시퀀스 단계 : 빈발 시퀀스를 도출한다.

 

5) 최대화 단계 : 빈발 시퀀스로부터 최대 시퀀스를 탐색한다.

 

 

(* 출처 : 데이터마이닝 기법과 응용, 전치혁 지음, 한나래 아카데미)

 

 

순차적 패턴 탐사 알고리즘에 대해서는 깊이 들어가지는 않겠으며, R의 arulesSequences package 사용법 중심으로 이번 포스팅을 이어가겠습니다.

 

 

1) "arulesSequences" package installation and loading

 

arulesSequences package는 M. Zaki가 개발한 cSPADE 알고리즘을 사용하여 빈발 순차 패턴을 탐색합니다. 이 알고리즘은 효율적인 격자 탐색 기법과 함께 temporal joins을 이용하며 시간 제약을 제공합니다. (Mining frequent sequential patterns with the cSPADE algorithm. This algorithm utilizes temporal joins along with efficient lattice search techniques and provides for timing constraints.  - help(arulesSequences) -)

 

> ##----------------------------------------
> ## sequence analysis
> ##----------------------------------------
> ## 'arulesSequences' package installation, loading
> install.packages("arulesSequences")
Installing package into ‘C:/Users/Owner/Documents/R/win-library/3.3’
(as ‘lib’ is unspecified)
also installing the dependency ‘arules’

trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.3/arules_1.4-1.zip'
Content type 'application/zip' length 1889108 bytes (1.8 MB)
downloaded 1.8 MB

trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.3/arulesSequences_0.2-15.zip'
Content type 'application/zip' length 4002231 bytes (3.8 MB)
downloaded 3.8 MB

package ‘arules’ successfully unpacked and MD5 sums checked
package ‘arulesSequences’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
	C:\Users\Owner\AppData\Local\Temp\RtmpOOKTl5\downloaded_packages
> library(arulesSequences)
필요한 패키지를 로딩중입니다: arules
필요한 패키지를 로딩중입니다: Matrix

다음의 패키지를 부착합니다: ‘arules’

The following objects are masked from ‘package:base’:

    abbreviate, write

 

 

 

 

2) transaction dataset 준비

 

순차분석 예제 데이터로는 package "arules"에 내장되어 있는 "zaki" transactions (3 variables : sequenceID, eventID, SIZE) dataset을 사용하겠습니다.

 

 

> ## zaki transaction Dataset
> data(zaki)
> str(zaki)
Formal class 'transactions' [package "arules"] with 3 slots
  ..@ data       :Formal class 'ngCMatrix' [package "Matrix"] with 5 slots
  .. .. ..@ i       : int [1:27] 2 3 0 1 2 0 1 5 0 2 ...
  .. .. ..@ p       : int [1:11] 0 2 5 8 12 15 16 19 22 24 ...
  .. .. ..@ Dim     : int [1:2] 8 10
  .. .. ..@ Dimnames:List of 2
  .. .. .. ..$ : NULL
  .. .. .. ..$ : NULL
  .. .. ..@ factors : list()
  ..@ itemInfo   :'data.frame':	8 obs. of  1 variable:
  .. ..$ labels: chr [1:8] "A" "B" "C" "D" ...
  ..@ itemsetInfo:'data.frame':	10 obs. of  3 variables:
  .. ..$ sequenceID: int [1:10] 1 1 1 1 2 2 3 4 4 4
  .. ..$ eventID   : int [1:10] 10 15 20 25 15 20 10 10 20 25
  .. ..$ SIZE      : int [1:10] 2 3 3 4 3 1 3 3 2 3

 

> help(zaki)
zaki {arulesSequences} R Documentation

Zaki Data Set

Description

A small example database for sequence mining provided as an object of class transactions and as a text file.

Usage

data(zaki)

Details

The data set contains the sequential database described in the paper by M. J. Zaki for illustration of the concepts of sequence mining. sequenceID and eventID denote the sequence and event (time) identifiers of the transactions.

Source

M. J. Zaki. (2001). SPADE: An Efficient Algorithm for Mining Frequent Sequences. Machine Learning Journal, 42, 31–60.

 

 

> as(zaki, "data.frame")
       items sequenceID eventID SIZE
1      {C,D}          1      10    2
2    {A,B,C}          1      15    3
3    {A,B,F}          1      20    3
4  {A,C,D,F}          1      25    4
5    {A,B,F}          2      15    3
6        {E}          2      20    1
7    {A,B,F}          3      10    3
8    {D,G,H}          4      10    3
9      {B,F}          4      20    2
10   {A,G,H}          4      25    3

 

 

 

3) 순차패턴분석

 

cspade(dataset, parameter, control) 함수를 사용하여 순차 패턴 탐사를 진행하여보겠습니다.

 

parameter

 - support : a numeric value specifying the minimum support of a sequence (default 0.1, range [0,1]).

 - maxsize : an integer value specifying the maximum number of items of an element of a sequence (default 10, range > 0)

 - maxlen : an integer value specifying the maximum number of elements of a sequence (default 10, range > 0)

 - maxwin : an integer value specifying the maximum time difference between any two elements of a sequence (default none, range >= 0)

 

> ## sequential pattern analysis : cspade()
> seq_rule_1 <- cspade(zaki, 
+                      parameter = list(support = 0.3, maxsize = 5, maxlen = 4), 
+                      control= list(verbose = TRUE))

parameter specification:
support : 0.3
maxsize :   5
maxlen  :   4

algorithmic control:
bfstype  : FALSE
verbose  :  TRUE
summary  : FALSE
tidLists : FALSE

preprocessing ... 1 partition(s), 0 MB [0.03s]
mining transactions ... 0 MB [0.03s]
reading sequences ... [0.04s]

total elapsed time: 0.1s

 

 

 

 

4) 순차 패턴 규칙 조회

 

summary(rule), as(rule, "data.frame") 함수를 이용해서 순차 패턴 규칙을 조회해보겠습니다.

 

> ## sequence pattern rule summary
> summary(seq_rule_1)
set of 18 sequences with

most frequent items:
      A       B       F       D (Other) 
     11      10      10       8      28 

most frequent elements:
    {A}     {D}     {B}     {F}   {B,F} (Other) 
      8       8       4       4       4       3 

element (sequence) size distribution:
sizes
1 2 3 
8 7 3 

sequence length distribution:
lengths
1 2 3 4 
4 8 5 1 

summary of quality measures:
    support      
 Min.   :0.5000  
 1st Qu.:0.5000  
 Median :0.5000  
 Mean   :0.6528  
 3rd Qu.:0.7500  
 Max.   :1.0000  

includes transaction ID lists: FALSE 

mining info:
 data ntransactions nsequences support
 zaki            10          4     0.3

 

> as(seq_rule_1, "data.frame")
          sequence support
1            <{A}>    1.00
2            <{B}>    1.00
3            <{D}>    0.50
4            <{F}>    1.00
5          <{A,F}>    0.75
6          <{B,F}>    1.00
7        <{D},{F}>    0.50
8      <{D},{B,F}>    0.50
9        <{A,B,F}>    0.75
10         <{A,B}>    0.75
11       <{D},{B}>    0.50
12       <{B},{A}>    0.50
13       <{D},{A}>    0.50
14       <{F},{A}>    0.50
15   <{D},{F},{A}>    0.50
16     <{B,F},{A}>    0.50
17 <{D},{B,F},{A}>    0.50
18   <{D},{B},{A}>    0.50

 



5) 순차 규칙 선별 (Subsetting sequence rule)

 

순차 규칙 내 원소의 개수(element size)가 2개 이상인 규칙만 선별해보겠습니다. 



> # making the sequence rule as a DataFrame

> seq_rule_1_df <- as(seq_rule_1, "data.frame")

> # calculate the size of the elements per each rule

> seq_rule_1_size <- size(seq_rule_1)

> # combine the element size with the sequence rule DataFrame

> seq_rule_1_df <- cbind(seq_rule_1_df, seq_rule_1_size)

> # subsetting the rules which have moer the 2 elements in the rule

> seq_rule_1_df_size_2 <- subset(seq_rule_1_df, 

+                                subset = seq_rule_1_size >= 2)

> # checking the result

> seq_rule_1_df_size_2


          sequence support seq_rule_1_size

7        <{D},{F}>     0.5               2

8      <{D},{B,F}>     0.5               2

11       <{D},{B}>     0.5               2

12       <{B},{A}>     0.5               2

13       <{D},{A}>     0.5               2

14       <{F},{A}>     0.5               2

15   <{D},{F},{A}>     0.5               3

16     <{B,F},{A}>     0.5               2

17 <{D},{B,F},{A}>     0.5               3

18   <{D},{B},{A}>     0.5               3

 




다음번 포스팅에서는 항목의 분류/계층 체계 (taxonomy), 가상 항목(virtual item)에 대해서 알아보겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾸욱 눌러주세요.

 

[ cSPADE Algorithm Reference ]

M. J. Zaki. (2001). SPADE: An Efficient Algorithm for Mining Frequent Sequences. Machine
Learning Journal, 42, 31–60.

 

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 2016.08.20 22:32  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • R Friend R_Friend 2016.08.22 11:41 신고  댓글주소  수정/삭제

      안녕하세요 Marketer 님,

      원천 transaction 데이터가 sequence ID, event ID, size, Item 의 컬럼 순서대로 준비가 되어있고, tab 으로 구분자가 되어있다고 할 경우, 불러오기 할 때 아래처럼 info = c("sequenceID", "eventID", "size") 라고 해서 Label을 명기해보시기 바랍니다.

      arulesSequences Package의 manual 을 찾아보면 아래처럼 unique한 "sequenceID"와 "eventID" Label을 반드시 명기하라고 되어 있습니다.

      "Unique event time identifiers must be provided in columns labels and eventID. Note that the latter
      is used for computation of gaps, etc."
      (* 출처 : arulesSequences Package의 manual)

      ##------------- 참고하세요.
      install.packages("arulesSequences")
      library(arulesSequences)
      tr_smaple <- read_baskets("tr_sample.txt",
      sep = "[ \t]+",
      info = c("sequenceID", "eventID", "size"))

  2. jihye 2016.10.19 14:55  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 ! 포스팅 잘 봤습니다.
    저 궁금한게 있는데요~ sequence를 학습해서 그다음 sequence를 예측하는 학습은 불가한가요?

    • R Friend R_Friend 2016.10.19 15:10 신고  댓글주소  수정/삭제

      jihye님, sequence pattern analysis는 순서 상의 패턴을 탐색하는 기법이구요(a를 구매하면 순차적으로 b를 구매하는 경향이 있다....그게 언제가 될지는 모르지만 암튼 순서상으로 a 다음에 b... 이런식이요. 만약 반복재구매, 반복재발생 사건이라면 재구매주기를 따로 분석하면 특정 시점까지 고려한 예측에 활용할수도 있겠네요),

      만약 시계열 데이터를 가지고 "특정 시점"에 값을 예측하는데는 시계열분석(예: ARIMA, 이동평균, 지수평활, 시계열분해... 등)이나 딥러닝의 RNN 이 많이 사용됩니다.

  3. niceguy1575 2017.01.20 11:39  댓글주소  수정/삭제  댓글쓰기

    궁금한게 있네요~
    what goes after? 라는 질문에
    본 알고리즘이 대답을 해줄 수 있는지에 대해서 궁금합니다.

    그러니까 여태까지 이런 순서로 상품을 샀고, 발견된 규칙들에 의해 이런 순서의 상품을 살 것이다. 라는 예측이 가능한 알고리즘인가요?

    • R Friend R_Friend 2017.01.20 11:47 신고  댓글주소  수정/삭제

      네, 그렇습니다. 상품추천에 이용가능합니다.

      구매주기(간격) 정보까지 접목하면 시점도 예측가능하겠지요.

    • niceguy1575 2017.01.20 13:01  댓글주소  수정/삭제

      말씀 감사드립니다.

      하지만, 게시글에서는 상품추천이나 시점 예측에 관한 부분이 빠진것같습니다.
      위의 코드에서 어떻게 발전시키면 상품추천 / 시점 예측이 가능한지 알 수 있을까요??

    • R Friend R_Friend 2017.01.20 13:15 신고  댓글주소  수정/삭제

      타캐팅은 별도로 진행해야 합니다.

      대상고객 타케팅은 sequence rule의 왼쪽 부분 item은 구매, 오른쪽 부분 item은 미구매한 고객 선별하면 됩니다.

      sequence rule의 왼쪽, 오른쪽 두 상품 간 구매 간격도 두 상춤을 모두 샀던 고객들의 거래데이터에서 구매간격의 분포분석을 해서 평균이나 중앙값 쓰면 됩니다.

    • 2017.01.20 15:52  댓글주소  수정/삭제

      비밀댓글입니다

    • R Friend R_Friend 2017.01.20 15:56 신고  댓글주소  수정/삭제

      예를 들면, sequence rule이 if A then B 가 나왔습니다.

      1번 고객은 A구매, B구매
      2번 고객은 A구매, B미구매,
      3번 고객은 A미구매, B미구매

      라고 했을때
      B고객을 타케팅하면 된다는 뜻입니다.

  4. ULove48 2017.01.23 12:09  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 ! 글 잘 봤습니다~
    질문이 하나 있는데요
    as(seq_rule_1, "data.frame") 를 통해 나온 결과를 어떻게 해석하죠?

    sequence열이 의미하는게 무엇인지 모르겠어요 구매의 순서를 의미하는건가..

    만약
    <{A},{B,F}> 1.00
    <{A,B,F}> 0.75
    <{A,F}> 0.5
    이면 A다음에 BF를 살 support가 제일 높다? 라고 얘기할 수 있는건가요?

    • R Friend R_Friend 2017.01.23 13:18 신고  댓글주소  수정/삭제

      가령 {A, B} 0.75 sequence rule 이라면

      if A then B 의 순서로 구매하는 거래의 구성비율(support)이 75%라는 뜻입니다.

      suppport 가 높을 수록 발생가능성이 높은 rule이라고 판단할 수 있습니다.

  5. chunb82 2017.03.15 16:44  댓글주소  수정/삭제  댓글쓰기

    안녕하세요,
    데이터 형태에서 에러가 자꾸 나서 문의드립니다.
    샘플에 나와있는 items가 어떻게 만들어진 건지 모르겠어요.
    어찌어찌 비슷한 포맷으로 데이터를 만들어봤는데 transactions데이터가 아니어서 함수가 안먹히네요. (dplyr 패키지를 활용하였고, 데이터 구조를 보면 Classes ‘tbl_df’, ‘tbl’ and 'data.frame' 입니다.)
    제가 만든 데이터로는 transactions데이터로 변환도 안된다고 에러가 뜨는데 처음 데이터 생성부터 어떻게 해야 분석을 할 수 있을까요? 답변 주시면 감사하겠습니다!!!ㅜㅜ

    • R Friend R_Friend 2017.03.15 17:14 신고  댓글주소  수정/삭제

      아래 링크포스팅 하단 참고하세요. 은 association rule 분석용 transaction 포맷으로 데이터셋 만드는 방법들 몇개 소개해놓았습니다.

      http://rfriend.tistory.com/193

      sequence analysis 용 포맷으로 만드는건 좀 찾아봐야해요.

    • chunb82 2017.03.21 18:01  댓글주소  수정/삭제

      정말 감사합니다. 마지막에 변환하는 방법이 나오네요.
      그런데 제가 가진 데이터로 돌려보니 (t.data<-as(split(data, data$prod_nm, data$sale_date, data$cust_no),"transactions"))

      "Error in asMethod(object) : can coerce list with atomic components only
      추가정보: 경고메시지(들):
      In if (drop) f <- factor(f) :
      length > 1 이라는 조건이 있고, 첫번째 요소만이 사용될 것입니다"

      라는 에러 메시지가 뜨는데 어떻게 해결해야 할까요?
      변수는 모두 팩터였습니다.

  6. khw 2017.04.25 18:04  댓글주소  수정/삭제  댓글쓰기

    안녕하세요.
    분석결과를 보고 해석이 잘 안되서요.
    마지막
    as(seq_rule_1, "data.frame")
    sequence support
    1 <{A}> 1.00
    ...
    5 <{A,F}> 0.75
    ...
    7 <{D},{F}> 0.50
    ...
    라고 나오는데 , {} 안에 있는것이 한 트랜잭션에 있는 상품인가요?
    예를 들어
    1번 A는 support가 1이면 매번 구매되는 상품이다.
    5번 A,F는 같이 구매 되는 경우가 75% 이다.
    7번 D를 구매하고 F를 구매한 경우는 전체 50% 다. 라고 해석이 가능한가요?

    마지막으로, 7번과 같이 어떤 상품을 구매하고 다른상품을 후에 구매하는 경우만
    뽑으려면 어떻게 해야할까요?

    • R Friend R_Friend 2017.04.26 23:56 신고  댓글주소  수정/삭제

      안녕하세요 khw 님,

      sequence rule 결과 해석은 댓글로 남겨주신 대로 하시면 됩니다.

      7번과 같이 rule size 가 2개 이상인 rule만 선별을 하고 싶으시면 아래 R script를 참고하세요. size 함수를 사용해서 한방에 subset하는 더 간편한 방법이 있을 것 같은데요, 자꾸 에러가 나네요. 그래서 빙 돌아가더라도 일단 그냥 DataFrame으로 바꾸어 놓고 나서, size 함수로 size 개수 구한 후에, cbind로 DataFrame에 붙이고, subset 함수 써서 선별하는 방법으로 작성해봤습니다.

      # making DataFrame
      seq_rule_1_df <- as(seq_rule_1, "data.frame")

      # counting sequence rule size
      seq_rule_1_size <- size(seq_rule_1)

      # combining seq_rule size with DataFrame
      seq_rule_1_df <- cbind(seq_rule_1_df, seq_rule_1_size)

      # subsetting rules which are equal or greater than size 2
      seq_rule_1_df_size_2 <- subset(seq_rule_1_df, subset = seq_rule_1_size >= 2)

      # check the result
      seq_rule_1_df_size_2

      sequence support seq_rule_1_size
      7 <{D},{F}> 0.5 2
      8 <{D},{B,F}> 0.5 2
      11 <{D},{B}> 0.5 2
      12 <{B},{A}> 0.5 2
      13 <{D},{A}> 0.5 2
      14 <{F},{A}> 0.5 2
      15 <{D},{F},{A}> 0.5 3
      16 <{B,F},{A}> 0.5 2
      17 <{D},{B,F},{A}> 0.5 3
      18 <{D},{B},{A}> 0.5 3

    • khw 2017.04.27 11:29  댓글주소  수정/삭제

      답변 감사합니다.
      알고리즘을 적용해 나온 분석결과와 적용하기 위한 결과가 조금 다를 수 있네요.
      개인적으로 답변을 보고 R을 좀더 유연하게 쓸 계기가 되었습니다.

  7. 노경모 2018.03.14 19:11 신고  댓글주소  수정/삭제  댓글쓰기

    zaki 데이텃을 찾을 수 없다고 하는데, 왜그런걸까요?

    --------------------------------------

    > library(arulesSequences)
    Error: package ‘arules’ 1.5.0 is loaded, but >= 1.5.1 is required by ‘arulesSequences’
    In addition: Warning message:
    패키지 ‘arulesSequences’는 R 버전 3.3.3에서 작성되었습니다
    > data(zaki)
    Warning message:
    In data(zaki) : 데이터셋 ‘zaki’을 찾을 수 없습니다
    > help(zaki)
    No documentation for ‘zaki’ in specified packages and libraries:
    you could try ‘??zaki’
    > require(arulesSequences)
    필요한 패키지를 로딩중입니다: arulesSequences
    Failed with error: ‘package ‘arules’ 1.5.0 is loaded, but >= 1.5.1 is required by ‘arulesSequences’’
    In addition: Warning message:
    패키지 ‘arulesSequences’는 R 버전 3.3.3에서 작성되었습니다
    > data(zaki)
    Warning message:
    In data(zaki) : 데이터셋 ‘zaki’을 찾을 수 없습니다
    > help(zaki)
    No documentation for ‘zaki’ in specified packages and libraries:
    you could try ‘??zaki’

    • R Friend R_Friend 2018.03.14 21:42 신고  댓글주소  수정/삭제

      안녕하세요 노경모님.

      아래의 에러 메시지에 보면 R 버전이 낮아서 arules가 1.5.0이 설치가 되고, (1.5.1 버전보다 낮다보니) arulesSequences 가 설치가 안되었기 때문에 zaki 데이터셋을 찾을 수 없는 것 같습니다.
      ------------------------------------------
      Error: package ‘arules’ 1.5.0 is loaded, but >= 1.5.1 is required by ‘arulesSequences’
      In addition: Warning message:
      패키지 ‘arulesSequences’는 R 버전 3.3.3에서 작성되었습니다
      ------------------------------------------

      다음의 https://cran.r-project.org/ 사이트에 가셔서 R 최신버전(오늘 현재 version 3.4.3)을 다운받아서 R을 재설치 하신 후에 위의 arules, arulesSequences 패키지 설치해보시면 해결 될 듯 합니다.

    • 노경모 2018.03.15 14:08 신고  댓글주소  수정/삭제

      잘 되네요, 감사합니다 ^^

지난번 포스팅에서는 거래 데이터 (transaction data)를 가지고 R을 사용하여 연관규칙 분석을 하였습니다.

 

이번 포스팅에서는 범주형 데이터와 연속형 데이터를 가지고 연관규칙을 생성(association rule mining on categorical data and continuous data)하는 방법을 소개하겠습니다. 

 

보통 연관규칙 분석을 배운다고 하면 거래 데이터(transaction data)만 가능한걸로 알고 끝내기 쉬운데요, 범주형 또는 연속형 데이터에 대해서도 연관규칙을 생성할 수 있다는 것을 알고 나면 연관규칙을 적용할 수 있는 범위가 늘어납니다.

 

가령 범주형 데이터를 가지고 연관규칙을 찾는 다면 아래와 같은 예가 있을 수 있습니다. 연속형 데이터를 범주형 데이터로 변환 (이산형화, discretization)하면 위의 예와 같은 연관규칙을 도출할 수 있습니다. 아래 예에서는 '연령'을 '연령대'로 구간을 나누었습니다.

 

 

 

[범주형 데이터 연관규칙 예]

 

{선형대수 수강 = Pass, 통계/확률 수강 = Pass}  →  {Machine Learning 수강 = Pass}

 

{성별 = 여성, 거주지역 = 분당, 연령대 = 30세~39세, 아동용품 구매경험 여부 = Yes}  →  {모바일쇼핑재구매 = Yes} 

 

 

범주형 데이터 또는 연속형 데이터를 가지고 연관규칙 분석을 하는 기본 원리는 "이항 데이터(binary data)로 변환하여 연관규칙 분석 방법을 수행"하는 것입니다.

 

아래의 가상의 데이터셋을 가지고 예를 들어보겠습니다.

성별(Gender), 아동상품구매여부(Child_Prd_YN), 모바일앱이용여부(Mobile_App_Use), 재구매여부(Re_Order) 등의 변수는 범주형 데이터(categorical data)이며, 연령(Age)은 연속형 데이터(continuous data)에 속합니다.  이를 '1', '0' 의 두개의 값만 가지는 변수로 변환하는 이항변수화(Binarization)을 하면 아래와 같습니다.

 

 

[ 범주형/연속형 데이터의 이항변수화 (Binarization) ]

 

 

 

이항변수화를 할 때 구간을 몇 개로 나눌 것인지가 중요한데요, 너무 잘게 쪼개서 구간을 많이 만들게 되면 연관규칙이 잘 안나올 수 있습니다. 왜냐하면 구간을 잘게 쪼개면 각 구간별 freqnency 가 작아져서 지지도(support) 값이 낮아지고, inqrequent item set은 pruning 되기 때문입니다.  따라서 적당한(?) 구간으로 (너무 잘게 쪼개지 않게) 나누는 것이 필요합니다.  위의 예에서는 연령(age)의 경우 20대, 30대, 40대의 3개 구간으로만 나누어보았습니다.

 

 

R을 가지고 위의 가상의 간략한 예제 데이터를 가지고 연관규칙을 생성해보겠습니다.

 

R의 as(dataset, "transactions") 함수를 이용하면 연관규칙분석을 위한 이항변수화(binirization) 작업을 별도로 안해줘도 되므로 편리합니다. 단, 연속형 변수를 범주형 변수로 만드는 이산형화(discretization)하는 작업은 아래 예처럼 코딩을 해줘야 합니다.

 

 

(1) 범주형 dataset 확보, 연속형 변수의 이산형화(discretization)

 

> ##--------------------------------------------------------------
> ## categorical data -> binarization -> association rule analysis
> ##--------------------------------------------------------------
> 
> # vector -> cbind -> data.frame
> cust_id <- c(1, 2, 3, 4, 5, 6)
> gender <- c("FEMALE", "MALE", "FEMALE", "FEMALE", "MALE", "FEMALE")
> age <- c(23, 28, 42, 34, 45, 36)
> child_prd_yn <- c("NO", "NO", "NO", "YES", "NO", "YES")
> mobile_app_use <- c("YES", "YES", "NO", "YES", "NO", "YES")
> re_order <- c("YES", "NO", "NO", "YES", "NO", "YES")
> 
> cust_mart <- cbind(cust_id, gender, age, child_prd_yn, mobile_app_use, re_order)
> cust_mart <- as.data.frame(cust_mart)
> sapply(cust_mart, class)
       cust_id         gender            age   child_prd_yn mobile_app_use       re_order 
      "factor"       "factor"       "factor"       "factor"       "factor"       "factor" 
> 
> 
> # cust_id : factor -> character
> # age : factor -> numeric
> cust_mart <- transform(cust_mart, 
+                        cust_id = as.character(cust_id),
+                        age = as.numeric(age))
> 
> sapply(cust_mart, class)
       cust_id         gender            age   child_prd_yn mobile_app_use       re_order 
   "character"       "factor"      "numeric"       "factor"       "factor"       "factor" 
> 
> 
> # age : custinuous data -> discretization
> cust_mart <- within(cust_mart, {
+   age_cd = character(0)
+   age_cd[ age <= 29 ] = "age_20"
+   age_cd[ age > 29 & age <= 39 ] = "age_30"
+   age_cd[ age > 39 ] = "age_40"
+   age_cd = factor(age_cd, level = c("age_20", "age_30", "age_40"))
+ })
> 
> 
> # dataset for assocition rule : (1) deleting 'cust_id', 'age'
> cust_mart_ar <- subset(cust_mart, select = -c(cust_id, age))
> str(cust_mart_ar)
'data.frame':	6 obs. of  5 variables:
 $ gender        : Factor w/ 2 levels "FEMALE","MALE": 1 2 1 1 2 1
 $ child_prd_yn  : Factor w/ 2 levels "NO","YES": 1 1 1 2 1 2
 $ mobile_app_use: Factor w/ 2 levels "NO","YES": 2 2 1 2 1 2
 $ re_order      : Factor w/ 2 levels "NO","YES": 2 1 1 2 1 2
 $ age_cd        : Factor w/ 3 levels "age_20","age_30",..: 1 1 1 1 1 1
> 

 

 

 

(2) 거래데이터 형식으로 데이터 변환하기 : as(dataset, "transactions")

 

> # dataset for assocition rule : (2) transaction data format
> install.packages("arules")
Installing package into ‘C:/Users/Owner/Documents/R/win-library/3.2’
(as ‘lib’ is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/arules_1.4-1.zip'
Content type 'application/zip' length 1885277 bytes (1.8 MB)
downloaded 1.8 MB

package ‘arules’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
	C:\Users\Owner\AppData\Local\Temp\Rtmp0ybsUO\downloaded_packages
> library(arules)
필요한 패키지를 로딩중입니다: Matrix

다음의 패키지를 부착합니다: ‘arules’

The following objects are masked from ‘package:base’:

    abbreviate, write

Warning message:
패키지 ‘arules’는 R 버전 3.2.5에서 작성되었습니다 
> 
> cust_mart_ar_tr <- as(cust_mart_ar, "transactions")
> str(cust_mart_ar_tr)
Formal class 'transactions' [package "arules"] with 3 slots
  ..@ data       :Formal class 'ngCMatrix' [package "Matrix"] with 5 slots
  .. .. ..@ i       : int [1:30] 0 2 5 7 8 1 2 5 6 8 ...
  .. .. ..@ p       : int [1:7] 0 5 10 15 20 25 30
  .. .. ..@ Dim     : int [1:2] 11 6
  .. .. ..@ Dimnames:List of 2
  .. .. .. ..$ : NULL
  .. .. .. ..$ : NULL
  .. .. ..@ factors : list()
  ..@ itemInfo   :'data.frame':	11 obs. of  3 variables:
  .. ..$ labels   : chr [1:11] "gender=FEMALE" "gender=MALE" "child_prd_yn=NO" "child_prd_yn=YES" ...
  .. ..$ variables: Factor w/ 5 levels "age_cd","child_prd_yn",..: 3 3 2 2 4 4 5 5 1 1 ...
  .. ..$ levels   : Factor w/ 7 levels "age_20","age_30",..: 4 5 6 7 6 7 6 7 1 2 ...
  ..@ itemsetInfo:'data.frame':	6 obs. of  1 variable:
  .. ..$ transactionID: chr [1:6] "1" "2" "3" "4" ...
> 

 

 

 

 

(3) 연관규칙 생성 (association rule generation) : arules package, apriori algorithm

 

 

> # association rule generation
> cust_mart_ar_tr_rule <- apriori(cust_mart_ar_tr, 
+                              parameter = list(support = 0.3, confidence = 0.5))
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport support minlen maxlen target   ext
        0.5    0.1    1 none FALSE            TRUE     0.3      1     10  rules FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 1 

Warning in apriori(cust_mart_ar_tr, parameter = list(support = 0.3, confidence = 0.5)) :
  You chose a very low absolute support count of 1. You might run out of memory! Increase minimum support.

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[9 item(s), 6 transaction(s)] done [0.00s].
sorting and recoding items ... [9 item(s)] done [0.00s].
creating transaction tree ... done [0.00s].
checking subsets of size 1 2 3 4 5 done [0.00s].
writing ... [135 rule(s)] done [0.00s].
creating S4 object  ... done [0.00s].

 

 

(4) 연관규칙 탐색 (inspection of association rule) : inspect(association rule)

 

 

> # association rule inspection > inspect(head(cust_mart_ar_tr_rule, 20)) # head 20 rules lhs rhs support confidence lift 1 {} => {re_order=YES} 0.5000000 0.5000000 1.0 2 {} => {re_order=NO} 0.5000000 0.5000000 1.0 3 {} => {child_prd_yn=NO} 0.6666667 0.6666667 1.0 4 {} => {mobile_app_use=YES} 0.6666667 0.6666667 1.0 5 {} => {gender=FEMALE} 0.6666667 0.6666667 1.0 6 {} => {age_cd=age_20} 1.0000000 1.0000000 1.0 7 {gender=MALE} => {re_order=NO} 0.3333333 1.0000000 2.0 8 {re_order=NO} => {gender=MALE} 0.3333333 0.6666667 2.0 9 {gender=MALE} => {child_prd_yn=NO} 0.3333333 1.0000000 1.5 10 {child_prd_yn=NO} => {gender=MALE} 0.3333333 0.5000000 1.5 11 {gender=MALE} => {age_cd=age_20} 0.3333333 1.0000000 1.0 12 {mobile_app_use=NO} => {re_order=NO} 0.3333333 1.0000000 2.0 13 {re_order=NO} => {mobile_app_use=NO} 0.3333333 0.6666667 2.0 14 {mobile_app_use=NO} => {child_prd_yn=NO} 0.3333333 1.0000000 1.5 15 {child_prd_yn=NO} => {mobile_app_use=NO} 0.3333333 0.5000000 1.5 16 {mobile_app_use=NO} => {age_cd=age_20} 0.3333333 1.0000000 1.0 17 {child_prd_yn=YES} => {re_order=YES} 0.3333333 1.0000000 2.0 18 {re_order=YES} => {child_prd_yn=YES} 0.3333333 0.6666667 2.0 19 {child_prd_yn=YES} => {mobile_app_use=YES} 0.3333333 1.0000000 1.5 20 {mobile_app_use=YES} => {child_prd_yn=YES} 0.3333333 0.5000000 1.5

 

 

 

(5) 특정 관심있는 연관규칙만 선별해서 보기 : subset()

 

  예) 연관규칙의 right-hand side 에 "재구매여부=예"를 포함하고 "lift >=2" 인 rule만 선별(subset)

 

> # subset : right-hand sied in "re_order = YES" & lift >= 2 > cust_mart_ar_tr_rule_reorder <- subset(cust_mart_ar_tr_rule, + subset = rhs %in% "re_order=YES" & lift >= 2) > > inspect(cust_mart_ar_tr_rule_reorder) lhs rhs support confidence lift 1 {child_prd_yn=YES} => {re_order=YES} 0.3333333 1 2 2 {child_prd_yn=YES, mobile_app_use=YES} => {re_order=YES} 0.3333333 1 2 3 {gender=FEMALE, child_prd_yn=YES} => {re_order=YES} 0.3333333 1 2 4 {child_prd_yn=YES, age_cd=age_20} => {re_order=YES} 0.3333333 1 2 5 {gender=FEMALE, mobile_app_use=YES} => {re_order=YES} 0.5000000 1 2 6 {gender=FEMALE, child_prd_yn=YES, mobile_app_use=YES} => {re_order=YES} 0.3333333 1 2 7 {child_prd_yn=YES, mobile_app_use=YES, age_cd=age_20} => {re_order=YES} 0.3333333 1 2 8 {gender=FEMALE, child_prd_yn=YES, age_cd=age_20} => {re_order=YES} 0.3333333 1 2 9 {gender=FEMALE, mobile_app_use=YES, age_cd=age_20} => {re_order=YES} 0.5000000 1 2 10 {gender=FEMALE, child_prd_yn=YES, mobile_app_use=YES, age_cd=age_20} => {re_order=YES} 0.3333333 1 2

 

 

 

제일 마지막 결과까지 보고 나면 '어, 저거 rule-base 규칙인데...어디서 많이 본건데...' 싶지 않으신가요?  Decision Tree랑 뭔가 모르게 비슷하다는 생각이 좀 들지요?  혹시 명확한 target을 가진 (설명력이 좋은) 분류 규칙 찾는 목적이라면 Decision Tree 를 쓰는게 더 효과적일 수 있습니다.  (가령, 재구매고객의 특성이 뭐지? 처럼요)

 

그런데 뭔지는 지금은 모르겠지만 '기존에는 잘 몰랐으면서 & insight가 담겨있고 & 설명가능하고 & 실행가능한' 연관규칙을 한번 찾아봐 줘, 그러면 내가 그 rule들을 평가해보고 쓸만한거 추려서 이용해볼게...하는 상황이면 연관규칙 분석을 사용하시면 됩니다. 

 

Decision Tree는 하햐식 방식(Top to bottom)으로 분류규칙을 만들어나가는데 반해 (즉, child node는 parent node에 종속적), 연관규칙, 순차패턴은 규칙이 서로 독립적이라는게 다릅니다.

 

이상으로 범주형, 연속형 데이터의 연관규칙 분석에 대해서 알아보았습니다.

 

다음번 포스팅에서는 순차분석(sequence analysis)에 대해서 알아보겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾸욱~ 눌러주세요.

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. Ashtray Kim 2016.09.30 10:13  댓글주소  수정/삭제  댓글쓰기

    글 잘읽었습니다~ 즉, binary 셋을 sparse format으로 변환시킨걸 arules로 분석을 하면 된다는 것이죠?
    저번에 질문드려서 글까지 작성해주신 텍스트 쪼개서 세로로 배열하는 문제(감사합니다!) 에도 AR을 적용해볼 수 있을까요?
    키워드가 엄청 많은데.. 이걸 binary로 변환시키는게 가능한 작업인지 ㅋㅋ

    • R Friend R_Friend 2016.09.30 14:55 신고  댓글주소  수정/삭제

      지난번 문의주셨던 포맷이면 read.transactions("dataset.csv") 함수를 사용해서 불러온후 arules package 바로 사용하시면 됩니다

    • Ashtray Kim 2016.09.30 15:59  댓글주소  수정/삭제

      쪼개기 전 데이터셋 말씀하시는건가요? 한 열을 transaction으로 볼 수 있기는 한데..
      그 쪼개기 전이라면 분석이 불가능한 포맷같아보여서요.
      키워드별로 다 쪼개고, transaction별 item matrix? 형태로 만들어줘야 하지 않나요?

  2. Ashtray Kim 2016.09.30 16:17  댓글주소  수정/삭제  댓글쓰기

    원 데이터 형태는

    id Keyword_Count
    203941948 연관:3^티스토리:4^컴퓨터:6
    203283192 바보:3^모니터:4^쥬스:6

    이런 형태입니다.

    • R Friend R_Friend 2016.09.30 16:23 신고  댓글주소  수정/삭제

      이런 형태 쪼갠 후에, 세로로 세우고, reshape oackage의 melt(), cast() 함수써서 재구조화해서 item별로 dummy 변수로 만들어줘야겠네요

    • Ashtray Kim 2016.09.30 17:45  댓글주소  수정/삭제

      음 좀 해봤는데요.. 아무래도 transaction 타입으로 불러오려면
      item matrix여야 하는 것 같습니다.
      약 7000*10000 크기의 matrix로 변환시켜야 하는데.. 또하나의 고비네요 ㅎㅎ

    • R Friend R_Friend 2016.09.30 18:26 신고  댓글주소  수정/삭제

      sqldf 로 항목별 빈도 구한 다음에, 일차로
      비빈발 항목(infrequent item)은 사전에 가지치기(pruning) 하시면 칼럼 숫자가 줄텐데요.

    • Ashtray Kim 2016.10.01 13:54  댓글주소  수정/삭제

      조언 감사합니다. 재구조화같은 경우, 조언해주시는 부분과 다른 방법 여러가지로 생각해보겠습니다.

      그리고, 궁금한 점이 있다면, arules 패키지가 apriori알고리즘을 사용하는지 여부입니다. apriori 알고리즘(이해하다 말았지만..ㅠㅠ)에서 비빈발 항목집합을 pruning하는 부분이 있는 걸로 알고있는데요. 사람이 직접 사전 pruning을 해줘야 할 필요가 있는지와, 해야한다면 그 기준(하위 몇퍼센트를 제외한다든지, 몇번만 출현한건 제외한다든지..)은 어떻게 정해야 하는지 궁금합니다.
      (이런 종류의 결정을 할 때, 기준이 되는 수치가 항상 어려운 것 같습니다. 정해진 것이 있는지, 경험에 따라 임의로 정하면 되는 것인지요..)

    • Ashtray Kim 2016.10.01 14:59  댓글주소  수정/삭제

      더 찾아봤는데요. read.transaction으로 불러올 수 있는 데이터가 2종류가 있네요

      1) format="basket"으로 읽어올 수 있는 데이터는 한 행이 203941948 연관,티스토리,컴퓨터 형태로,
      한 transaction에 구입한 모든 항목이 1개의 행에 다 들어간 것.

      2) format="single"로 읽어올 수 있는 데이터는 한 행에 하나의 item만 들어갈 수 있는 형태. 즉,
      203941948 연관
      203941948 티스토리
      203941948 컴퓨터

      인 것 같습니다. 실제 제 원본 데이터에 적용이 되는지는 화요일에 적용해봐야 알 것 같네요.

    • R Friend R_Friend 2016.10.01 16:07 신고  댓글주소  수정/삭제

      데이터를 구분자 가준으로 분리한 후에 세로로 세워서, format="single"로 데이터 불러온후에 arules 로 분석하면 되겠네요. min support 지정하시면 알아서 비빈발 항목 pruning 해줍니다.

      format="single"이 되는지 처음 알았네요. 좋은 정보 감사합니다.

  3. OriR 2017.02.16 13:52 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 글 잘 읽었습니다.^^ 질문이 있는데, 마지막에 cust_mart_ar_tr_rule_reorder 를 plot으로 그려봤을 때, rules은 13개지만 커다란 원 하나만 그려지더라구요
    그리고 lhs 에 +x items 라는 말이 나오는데 그게 정확히 어떤 걸 말하는지 이해가 잘 안됩니다. ㅠ
    어떤 의미로 해석해야 할까요??

    • R Friend R_Friend 2017.03.15 23:45 신고  댓글주소  수정/삭제

      포스팅 본문의 예시는 알고리즘 설명을 위해서 아주 간단하게 극소수의 transaction 을 가짜 예시로 만든거다 보니 rule이 나오긴 했지만 rule 간 차이가 별로 없습니다.

      제대로 된 데이터셋으로 rule을 한번 만들어 보시구요, 그래프 그릴 때 아래 포스팅 참고해보시지요.
      http://rfriend.tistory.com/221

      arulesViz package 로 연관규칙 네트워크 그래프를 그려보면 동그라미만 뎅그러니 있고 화살표가 그려지다 말더라구요. 왜 그런지는 잘 모르겠지만요. http://rfriend.tistory.com/193

지난번 포스팅에서는 대용량 데이터로 부터 효율적으로 연관규칙(association rules)을 도출할 수 있는 apriori algorithm 에 대하여 알아보았습니다.

 

이번 포스팅에서는 R의 arules package를 가지고 분석하는 방법을 예를 들어서 설명하도록 하겠습니다. 

(그동안 선형대수랑 기계학습 이론 내용만 포스팅하다보니 R 사용법 포스팅한지가 너무 오래된거 같아요. ^^;)

 

arules package는 Apriori algorithm으로 구현되었 있습니다.

 

 

 

1. arules package 설치 및 library(arules)로 로딩

 

aruels package는 base package가 아니므로 별도 설치 필요합니다.

 

 

 > install.packages("arules")
Installing package into ‘C:/Users/Owner/Documents/R/win-library/3.2’
(as ‘lib’ is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/3.2/arules_1.4-1.zip'
Content type 'application/zip' length 1885514 bytes (1.8 MB)
downloaded 1.8 MB

package ‘arules’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
C:\Users\Owner\AppData\Local\Temp\Rtmp4sJVWg\downloaded_packages
> library(arules)
필요한 패키지를 로딩중입니다: Matrix

다음의 패키지를 부착합니다: ‘arules’

The following objects are masked from ‘package:base’:

    abbreviate, write

Warning message:
패키지 ‘arules’는 R 버전 3.2.5에서 작성되었습니다

 

 

2. 데이터 확보 및 탐색

 

분석에 사용할 데이터는 Epub 거래 데이터셋 입니다.  Help에 'Epub' 을 검색해보면 아래와 같은 설명이 나옵니다. Vienna University of Economics and Business Administration에서의 2003~2008년까지 기간 동안 전자책 다운로드 이력/거래 데이터입니다.

 

> help(Epub)

 

 

Epub {arules}

R Documentation

Epub Data Set

Description

The Epub data set contains the download history of documents from the electronic publication platform of the Vienna University of Economics and Business Administration. The data was recorded between Jan 2003 and Dec 2008.

Usage

data(Epub)

Format

Object of class transactions with 15729 transactions and 936 items. Item labels are document IDs of the from "doc\_11d". Session IDs and time stamps for transactions are also provided.

Author(s)

Michael Hahsler

Source

Provided by Michael Hahsler from ePub-WU at http://epub.wu-wien.ac.at.

 

 

 

data(Epub)로 로딩하고 summary(Epub)로 데이터셋 요약정보를 살펴보겠습니다. 

- sparse format 형식으로 저장된 itemMatrix의 거래(transactions) 데이터셋이며,

- 15,729개의 행(즉, 거래)과 936개의 열(items)으로 구성되어 있습니다.

- 밀도(density)가 0.1758755% 라고 되어 있는데요, 전체 15729*936개의 cell 중에서 0.1758% 의 cell에 거래가 발생해서 숫자가 차 있다는 뜻입니다. (일부 책벌레 애독자가 한꺼번에 다수의 책을 사고, 대부분의 독자는 item 1개나 2개 단품 위주로 샀기 때문에 이렇게 밀도가 낮겠지요?)

- 'most frequent items' 는 거래 빈도가 가장 많은 top 5의 품목명과 거래빈도를 제시해주고 있습니다.

  (doc_11d 가 356회 거래 빈도 발생으로 1위) 

- 'element (itemset/transaction) length distribution' 은 하나의 거래 장바구니(즉, row 1개별로)에 품목(item)의 개수별로 몇 번의 거래가 있었는지를 나타냅니다.

(장바구니에 item 1개 짜리 단품만 거래한 경우가 11,615건으로서 가장 많고, item 2개 거래는 2,189건이군요)

- 마지막에 item 정보의 label 형식과 transaction ID, TimeStamp 정보의 format 예시가 나옵니다.

 

> data(Epub)
> summary(Epub)
transactions as itemMatrix in sparse format with
 15729 rows (elements/itemsets/transactions) and
 936 columns (items) and a density of 0.001758755 

most frequent items:
doc_11d doc_813 doc_4c6 doc_955 doc_698 (Other) 
    356     329     288     282     245   24393 

element (itemset/transaction) length distribution:
sizes
    1     2     3     4     5     6     7     8     9    10    11    12    13    14 
11615  2189   854   409   198   121    93    50    42    34    26    12    10    10 
   15    16    17    18    19    20    21    22    23    24    25    26    27    28 
    6     8     6     5     8     2     2     3     2     3     4     5     1     1 
   30    34    36    38    41    43    52    58 
    1     2     1     2     1     1     1     1 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.000   1.000   1.000   1.646   2.000  58.000 

includes extended item information - examples:
   labels
1 doc_11d
2 doc_13d
3 doc_14c

includes extended transaction information - examples:
    transactionID           TimeStamp
10792  session_4795 2003-01-02 10:59:00
10793  session_4797 2003-01-02 21:46:01
10794  session_479a 2003-01-03 00:50:38 

 

 

참고로, R을 분석에 많이 사용해본 분이라면 dataframe 형식의 데이터셋을 많이 사용해보셨을 텐데요, 연관규칙분석에서 사용할 itemMatrix in sparse format 형식의 데이터셋과 비교해보면 아래와 같이 차이가 있습니다.  위에서 Epub 데이터셋의 density가 0.1758%로서 item별 matrix cell의 거의 대부분이 숭숭 비어있다고 했는데요, 비어있는 cell까지 모두 저장하려면 메모리 비효율이 발생하므로 cell의 차있는 부분(즉, 거래발생 항목, nonzero elements)에 대해서만 효율적으로 데이터를 저장해놓는 방식이 itemMatrix in sparse format 형식입니다. 저장 효율이 좋아지는 대신 반대급부로 access하는 것이나 저장구조는 좀 복잡해집니다.   

(행렬의 대부분의 cell이 '0'이면 sparse matrix 라고 하며, 그 반대는 dense matrix 라고 합니다.)

 

csv 파일을 dataframe 으로 업로드할 때 read.csv() 함수를 사용하는 것처럼, transaction 데이터를 연관규칙분석을 위해 sparse format의 itemMatrix로 업로드하기 위해서는 read.transactions("dataset.csv") 함수를 사용합니다.

 

 

 

 

 

 

이번에는 inspect() 함수를 사용해서 거래 데이터 10개만 뽑아서 살펴보겠습니다.

 

 > ## check itemsets in sparse matrix

> inspect(Epub[1:10])
      items                    transactionID TimeStamp          
10792 {doc_154}                session_4795  2003-01-02 10:59:00
10793 {doc_3d6}                session_4797  2003-01-02 21:46:01
10794 {doc_16f}                session_479a  2003-01-03 00:50:38
10795 {doc_11d,doc_1a7,doc_f4} session_47b7  2003-01-03 08:55:50
10796 {doc_83}                 session_47bb  2003-01-03 11:27:44
10797 {doc_11d}                session_47c2  2003-01-04 00:18:04
10798 {doc_368}                session_47cb  2003-01-04 04:40:57
10799 {doc_11d,doc_192}        session_47d8  2003-01-04 09:00:01
10800 {doc_364}                session_47e2  2003-01-05 02:48:36
10801 {doc_ec}                 session_47e7  2003-01-05 05:58:48

 

 

 

다음으로 itemFrequency() 함수를 이용해서 거래품목(item)별로 거래에서 차지하는 비율(support)를 살펴보겠습니다. Epub[ , 1:10] 으로 앞에 10개만 indexing 해왔습니다.

 

> ## support per item: itemFrequency()
> itemFrequency(Epub[ , 1:10])
     doc_11d      doc_13d      doc_14c      doc_14e      doc_150      doc_151 
0.0226333524 0.0009536525 0.0024794965 0.0017801513 0.0015894208 0.0007629220 
     doc_153      doc_154      doc_155      doc_156 
0.0006357683 0.0013351135 0.0010808062 0.0031152648

 

 

 

itemFrequencyPlot(dataset, support = xx) 함수를 이용해서 지지도 1% 이상의 item에 대해 막대그래프를 그려보겠습니다.

 

> ## item frequency plot : itemFrequentPlot()
> itemFrequencyPlot(Epub, support = 0.01, main = "item frequency plot above support 1%")

 

 

 

이번에는 itemFrequencyPlot(dataset, topN = xx) 함수를 사용해서 support 상위 30개의 막대그래프를 그려보겠습니다. support 1등 item이 'doc_11d'이고 2~2.5% 사이로군요. 30등 tiem은 'doc_3ec'이고 support가 약 1% 이네요.

 

> ## item frequency plot top 30 : itemFrequencyPlot(,topN)
> itemFrequencyPlot(Epub, topN = 30, main = "support top 30 items")

 

 

 

 

아래는 image()함수sample()함수를 이용해서 500개의 무작위 샘플을 가지고 matrix diagram을 그려본 것입니다.  그림의 점들은 거래가 발생한 item을 의미합니다. 이 그림만 봐서는 어떤 패턴이 있는지 알기가 어렵지요? ^^' 

 

> # matrix diagram : image()
> image(sample(Epub, 500, replace = FALSE), main = "matrix diagram")

 

 

 

 

 

3. 연관규칙 분석 (association rule analysis)

 

arules 패키지의 apriori() 함수를 이용해서 연관규칙을 분석해보겠습니다.

 

parameter 에 list로 minimum support, minimum confidence, minimum length 를 지정해주면 이를 충족시키지 못하는 superset에 대해서는 pruning 을 해서 빠르게 연관규칙을 찾아줍니다.

 

그런데, 아래 예시에서는 minumum support = 0.01 로 했더니 기준이 너무 높았던지 연관규칙이 '0'개 나왔네요.

 

 

> ## association rule analysis : apriori()
> Epub_rule <- apriori(data = Epub, 
+                      parameter = list(support = 0.01, 
+                                       confidence = 0.20, 
+                                       minlen = 2))
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport support minlen maxlen target   ext
        0.2    0.1    1 none FALSE            TRUE    0.01      2     10  rules FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 157 

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[936 item(s), 15729 transaction(s)] done [0.00s].
sorting and recoding items ... [19 item(s)] done [0.00s].
creating transaction tree ... done [0.00s].
checking subsets of size 1 2 done [0.00s].
writing ... [0 rule(s)] done [0.00s].
creating S4 object  ... done [0.00s]

 

 

minumum support 기준을 0.001 로 낮추어서 다시 한번 분석을 해보겠습니다. 

아래처럼 결과가 나왔습니다.  연관규칙 분석은 기본 개념과 결과를 해석할 줄 알면 분석툴로 분석하는 것은 이처럼 매우 쉽습니다. (컴퓨터는 연산해야할 일이 엄청 많지만요...)

 

> # re-setting minimum support from 0.01 to 0.001
> Epub_rule_2 <- apriori(data = Epub, 
+                      parameter = list(support = 0.001, 
+                                       confidence = 0.20, 
+                                       minlen = 2))
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport support minlen maxlen target   ext
        0.2    0.1    1 none FALSE            TRUE   0.001      2     10  rules FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 15 

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[936 item(s), 15729 transaction(s)] done [0.00s].
sorting and recoding items ... [481 item(s)] done [0.00s].
creating transaction tree ... done [0.02s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [65 rule(s)] done [0.00s].
creating S4 object  ... done [0.00s]

 

> Epub_rule_2
set of 65 rules

 

 

 

4. 연관규칙 조회 및 평가

 

연관규칙을 Epub_rule 이라는 객체에 저장을 해두었으므로, summary() 함수를 써서 연관규칙에 대해 개략적으로 파악을 해보면 아래와 같습니다. 

 

62개 rule이 2개 item으로 이루어져 있고, 3개 rule은 3개 item으로 구성되있군요. 지지도(support), 신뢰도(confidence), 향상도(lift)에 대한 기초통계량도 같이 제시가 되었는데요, 향상도 최소값이 11.19로서 전반적으로 꽤 높군요.

 

> summary(Epub_rule_2)
set of 65 rules

rule length distribution (lhs + rhs):sizes
 2  3 
62  3 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  2.000   2.000   2.000   2.046   2.000   3.000 

summary of quality measures:
    support           confidence          lift       
 Min.   :0.001017   Min.   :0.2048   Min.   : 11.19  
 1st Qu.:0.001081   1st Qu.:0.2388   1st Qu.: 34.02  
 Median :0.001208   Median :0.2874   Median : 59.47  
 Mean   :0.001435   Mean   :0.3571   Mean   :105.16  
 3rd Qu.:0.001526   3rd Qu.:0.3696   3rd Qu.:100.71  
 Max.   :0.004069   Max.   :0.8947   Max.   :454.75  

mining info:
 data ntransactions support confidence
 Epub         15729   0.001        0.2

 

 

 

연관규칙을 평가하기 위해 개별 규칙(rule)을 inspect()함수를 사용해서 살펴보겠습니다.  아래 결과에 1~20개의 rule을 제시했는데요, lhs : Left-hand side, rhs : Right-hand side 를 의미합니다.

 

> # inspection of 1~20 association rules : inspect() > inspect(Epub_rule_2[1:20]) lhs rhs support confidence lift 1 {doc_506} => {doc_507} 0.001207960 0.6551724 303.09432 2 {doc_507} => {doc_506} 0.001207960 0.5588235 303.09432 3 {doc_470} => {doc_4c6} 0.001080806 0.2048193 11.18612 4 {doc_714} => {doc_574} 0.001080806 0.3695652 113.97826 5 {doc_574} => {doc_714} 0.001080806 0.3333333 113.97826 6 {doc_4bf} => {doc_4ac} 0.001080806 0.5000000 77.10294 7 {doc_6e9} => {doc_6e8} 0.001207960 0.6785714 333.53906 8 {doc_6e8} => {doc_6e9} 0.001207960 0.5937500 333.53906 9 {doc_6e9} => {doc_6e7} 0.001271537 0.7142857 321.00000 10 {doc_6e7} => {doc_6e9} 0.001271537 0.5714286 321.00000 11 {doc_749} => {doc_74a} 0.001017229 0.3555556 86.03897 12 {doc_74a} => {doc_749} 0.001017229 0.2461538 86.03897 13 {doc_6e8} => {doc_6e7} 0.001335113 0.6562500 294.91875 14 {doc_6e7} => {doc_6e8} 0.001335113 0.6000000 294.91875 15 {doc_3d6} => {doc_3c4} 0.001144383 0.2465753 79.15068 16 {doc_3c4} => {doc_3d6} 0.001144383 0.3673469 79.15068 17 {doc_3d6} => {doc_4b4} 0.001017229 0.2191781 51.45451 18 {doc_4b4} => {doc_3d6} 0.001017229 0.2388060 51.45451 19 {doc_3c4} => {doc_574} 0.001017229 0.3265306 100.70588 20 {doc_574} => {doc_3c4} 0.001017229 0.3137255 100.70588

 

 

 

위처럼 주욱 나열을 해놓으면 rule이 수백, 수천개가 되면 일일이 눈으로 보고 평가하기가 쉽지가 않습니다.  봐야할 rule이 많을 때는 sort() 함수를 써서 분석가가 보고자하는 기준에 맞게 by 매개변수로 정렬을 하여 우선순위를 뒤서 보면 유용합니다.  아래 예는 lift 를 기준으로 상위 20개 연관규칙을 정렬해보았습니다.  매우 유용하지요?!!

 

 

> # sorting association rules by lift : sort( , by = "lift") > inspect(sort(Epub_rule_2, by = "lift")[1:20]) lhs rhs support confidence lift 65 {doc_6e7,doc_6e8} => {doc_6e9} 0.001080806 0.8095238 454.75000 64 {doc_6e7,doc_6e9} => {doc_6e8} 0.001080806 0.8500000 417.80156 63 {doc_6e8,doc_6e9} => {doc_6e7} 0.001080806 0.8947368 402.09474 7 {doc_6e9} => {doc_6e8} 0.001207960 0.6785714 333.53906 8 {doc_6e8} => {doc_6e9} 0.001207960 0.5937500 333.53906 9 {doc_6e9} => {doc_6e7} 0.001271537 0.7142857 321.00000 10 {doc_6e7} => {doc_6e9} 0.001271537 0.5714286 321.00000 1 {doc_506} => {doc_507} 0.001207960 0.6551724 303.09432 2 {doc_507} => {doc_506} 0.001207960 0.5588235 303.09432 13 {doc_6e8} => {doc_6e7} 0.001335113 0.6562500 294.91875 14 {doc_6e7} => {doc_6e8} 0.001335113 0.6000000 294.91875 39 {doc_87c} => {doc_882} 0.001335113 0.6000000 171.58909 40 {doc_882} => {doc_87c} 0.001335113 0.3818182 171.58909 4 {doc_714} => {doc_574} 0.001080806 0.3695652 113.97826 5 {doc_574} => {doc_714} 0.001080806 0.3333333 113.97826 20 {doc_574} => {doc_3c4} 0.001017229 0.3137255 100.70588 19 {doc_3c4} => {doc_574} 0.001017229 0.3265306 100.70588 22 {doc_4b4} => {doc_3c4} 0.001207960 0.2835821 91.02985 21 {doc_3c4} => {doc_4b4} 0.001207960 0.3877551 91.02985 11 {doc_749} => {doc_74a} 0.001017229 0.3555556 86.03897

 

 

 

아래는 정렬 기준을 '지지도(support)'로 해서 top 20 연관규칙을 뽑아본 것입니다.  편하고 좋지요?!

 

> # sorting association rules by support : sort(, by = "support")
> inspect(sort(Epub_rule_2, by = "support")[1:20])
   lhs          rhs       support     confidence lift     
50 {doc_72f} => {doc_813} 0.004068917 0.3516484   16.81178
45 {doc_4ac} => {doc_16e} 0.002797381 0.4313725   53.42566
46 {doc_16e} => {doc_4ac} 0.002797381 0.3464567   53.42566
62 {doc_364} => {doc_71}  0.002733804 0.2336957   15.91255
60 {doc_60e} => {doc_6bf} 0.002670227 0.2745098   21.06227
61 {doc_6bf} => {doc_60e} 0.002670227 0.2048780   21.06227
49 {doc_972} => {doc_8f9} 0.002161612 0.2281879   18.69358
58 {doc_1a2} => {doc_4c7} 0.002098035 0.2391304   17.99657
56 {doc_424} => {doc_359} 0.001843728 0.3020833   44.40625
57 {doc_359} => {doc_424} 0.001843728 0.2710280   44.40625
47 {doc_4da} => {doc_84b} 0.001780151 0.2314050   34.01653
48 {doc_84b} => {doc_4da} 0.001780151 0.2616822   34.01653
52 {doc_8a8} => {doc_8af} 0.001716574 0.2903226   47.07715
53 {doc_8af} => {doc_8a8} 0.001716574 0.2783505   47.07715
27 {doc_803} => {doc_3fc} 0.001589421 0.3289474   59.47142
28 {doc_3fc} => {doc_803} 0.001589421 0.2873563   59.47142
55 {doc_466} => {doc_19f} 0.001525844 0.2264151   25.80640
59 {doc_359} => {doc_4c7} 0.001398690 0.2056075   15.47368
13 {doc_6e8} => {doc_6e7} 0.001335113 0.6562500  294.91875
14 {doc_6e7} => {doc_6e8} 0.001335113 0.6000000  294.91875

 

 

 

 

또 하나 유용한 tip이 있다면 subset() 함수를 써서 관심이 있는 item이 포함된 연관규칙만 선별해서 보는 방법입니다.  subset()함수를 이용해 연관규칙에서 "doc_72f"나 "doc_4ac"를 포함하는 규칙을 선별하는 방법은 아래와 같습니다.

 

 

> # subset of association rules : subset()
> rule_interest <- subset(Epub_rule_2, items %in% c("doc_72f", "doc_4ac"))
> inspect(rule_interest)
   lhs          rhs       support     confidence lift    
6  {doc_4bf} => {doc_4ac} 0.001080806 0.5000000  77.10294
45 {doc_4ac} => {doc_16e} 0.002797381 0.4313725  53.42566
46 {doc_16e} => {doc_4ac} 0.002797381 0.3464567  53.42566
50 {doc_72f} => {doc_813} 0.004068917 0.3516484  16.81178

 

 

 

연관규칙을 찾을 때 왼쪽(lhs : Left-hand side)이나 오른쪽(rhs: Right-hand side)을 기준으로 원하는 항목(item)이 포함된 규칙만 찾고 싶을 때는 아래와 같이 lhs 나 rhs 조건을 주면 됩니다.

 

> # subset with left-hand side item : subset(lhs %in% "item")
> rule_interest_lhs <- subset(Epub_rule_2, lhs %in% c("doc_72f", "doc_4ac"))
> inspect(rule_interest_lhs)
   lhs          rhs       support     confidence lift    
45 {doc_4ac} => {doc_16e} 0.002797381 0.4313725  53.42566
50 {doc_72f} => {doc_813} 0.004068917 0.3516484  16.81178 

 

 

 

위에서는 사용한 %in% (select itemsets matching any given item) 조건은 적어도 하나의 제품이라도 존재하면 연관규칙을 indexing해온다는 뜻입니다.  이에 반해 %pin% (partial matching) 는 부분 일치만 하더라도, %ain% (select only itemsets matching all given item) 는 완전한 일치를 할 때만 indexing을 하게 됩니다. 

 

아래에 item 이름에 부분적으로라도 "60e"라는 철자가 들어가 있는 item이 들어가 있는 연관규칙을 부분집합으로 indexing해오는 예를 들어보겠습니다.  이 기능도 꽤 유용하겠지요?

 

> # partial subset : %pin%
> rule_interest_pin <- subset(Epub_rule_2, items %pin% c("60e"))
> inspect(rule_interest_pin)
   lhs          rhs       support     confidence lift    
60 {doc_60e} => {doc_6bf} 0.002670227 0.2745098  21.06227
61 {doc_6bf} => {doc_60e} 0.002670227 0.2048780  21.06227

 

 

 

 

Rule의 왼쪽에 "doc_6e8"과 "doc_6e9" item을 동시에 정확히 가지고 있는 rule을 "ain" 을 사용해서 선별해보면 아래와 같습니다.

 

> rule_interest_lhs_ain <- subset(Epub_rule_2, lhs %ain% c("doc_6e8", "doc_6e9"))
> inspect(rule_interest_lhs_ain)
    lhs                  rhs       support     confidence lift    
[1] {doc_6e8,doc_6e9} => {doc_6e7} 0.001080806 0.8947368  402.094

 

 

 

 

support, confidence, lift 조건을 추가해서 부분집합(subset)을 취할 수도 있습니다.  아래 예는 신뢰도(confidence) 0.25 초과하는 rule 을 선별하라는 조건을 추가하였습니다.  참 편하지요?!

 

> # partial subset with confidence condition : %pin%, confidence
> rule_interest_pin_conf <- subset(Epub_rule_2, items %pin% c("60e") & confidence > 0.25)
> inspect(rule_interest_pin_conf)
   lhs          rhs       support     confidence lift    
60 {doc_60e} => {doc_6bf} 0.002670227 0.2745098  21.06227 

 

 

 

 

5. 연관규칙의 시각화 : arulesViz package

 

arulesViz package를 사용해서 연관규칙을 시각화해보겠습니다.

 

 

  • Scatter plot for association rules 

> install.packages("arulesViz")
> library(arulesViz)

>

> # scatter plot of association rules
> plot(Epub_rule_2)

 

 

 

 

  • Grouped matrix for assocation rules

> # grouped matrix for association rules
> plot(sort(Epub_rule_2, by = "support")[1:20], method = "grouped")

 

* 65개 rule을 모두 그리니깐 너무 작게 나와서 support 기준 상위 20개만 선별해서 그렸음

 

 

  • Network Graph for assocation rules

참고로 아래 그래프의 원은 item element가 아니라 {item} → {item} 연관규칙의 지지도(support)를 나타냅니다. 지지도에 따라 원의 크기가 비례합니다. 색깔은 향상도(Lift)를 나타냅니다. 색깔이 진할수록 향상도가 높습니다. 그런데 화살표(from lhs to rhs)가 그려지다 말아서 그래프가 영... 어색합니다. -_-???

 

 

> # Graph for association rules
> plot(Epub_rule_2, method = "graph", control = list(type="items"))

 

 

 


위의 65개 연관규칙 그래프의 라벨 글자 크기(label font size, default = 1)를 줄이고, 화살표 크기(arrow size, default = 1)도 조금 잘게 해보겠습니다.   네트워크 그래프 그릴 때 사용하는 igraph 패키지의 파라미터 설정 방법 사용하면 됩니다. 위의 그래프보다는 아주 조금 더 나은거 같기는 한데요, 많이 좋아보인다는 느낌은 안드네요. ^^;; (그래프 그릴 때마다 위치가 조금씩 달라지므로 제가 화면 캡쳐해놓은 거랑은 아마 다르게 그려질 거예요)



> # changing font size(vertex.label.cex), arrow 

> plot(Epub_rule_2, method = "graph", 

+      control = list(type="items"), 

+      vertex.label.cex = 0.7, 

+      edge.arrow.size = 0.3,

+      edge.arrow.width = 2)

 


Edge : 선 관련 파라미터

 Vertex : 점 관련 파라미터

- edge.color : 지정 (default = "darkgrey")

- edge.width :

- edge.arrow.size : 화살 크기

- edge.arrow.width : 화살

- edge.arrow.mode : 화살 머리 유형 (0 : 없음,  1 : 역방향,  2 : 순방향,   3 : 양방향)

(무방향 네트워크의 경우 default = 0)

 

- edge.lty : 유형 ("solid", "dashed", "dotted", "dotdash", "longdash", "twodash")

- edge.label : 레이블

- edge.label.family : 레이블 종류 ("serif", "sans", "mono" )

- edge.label.font : 레이블 글자형 (1 : plain text, 2 : bold, 3 : italic, 4 : bold italic)

- edge.label.cex : 레이블 크기 (default = 1)

- edge.label.color : 레이블 (default = "navy") 

 - vertex.size : 크기, vector 가능 (default = 15)

- vertex.color : (default = "SkyBlue2")

- vertex.frame.color : 윤곡의 (default = "black")

- vertex.shape : 형태 ("circle", "square", "rectangle", "none", default = "circle")

 

- vertex.label : 레이블 (vector)

- vertex.label.family : 레이블 종류 ("serif", "sans", "mono" )

- vertex.label.font : 레이블 글자형 (1 : plain text, 2 : bold, 3 : italic, 4 : bold italic)

- vertex.label.cex : 레이블 크기 (default = 1)

- vertex.label.dist : 중심과 레이블 거리 (default = 0)

- vertex.label.degree : 레이블 방향(radian) ( : 0, : pi, : -pi/2, : pi/2)

- vertex.label.color : 레이블 (default = "navy")

* igraph 참고 : http://rfriend.tistory.com/221





Network graph for association rules 그래프 해석을 좀더 쉽게 할 수 있도록 아래 그래프의 몇 개의 item 간 연관규칙 그래프 옆에다가 association rule(left-hand => right-hand rule, support, confidence, lift) 분석 결과를 매핑해서 표시를 해보았습니다.  item 과 item 의 연관규칙 관계를 화살표로 나타내구요, 원의 크기는 지지도, 원의 색깔은 향상도를 나타냅니다. 


  • 화살표 (arrow) : left-hand => right-hand rule 의 방향(direction from left to right)을 나타냄
  • 원의 크기 (circle size) : 지지도(support)에 비례해서 커짐
  • 원의 색깔 (circle color) : 향상도(lift)에 비례해서 색이 진해짐





연관규칙 그래프 시각화를 좀더 이쁘게 하려면 연관규칙 개수를 20개 이내로 줄여주면 됩니다. 아래는 연관규칙 55~65번째 (11개 규칙) 만 선별해서 type = "items" 로 그려본 것인데요, label 글자 크기나 화살표 등이 전혀 거슬리지 않고 자연스럽지요?


[ 그림 1]  Graph-based visualization with item and rules as vertices



> plot(Epub_rule_2[55:65], method = "graph", control = list(type="items"))



 




type = "itemsets" 으로 설정을 해주면 아래의 그래프 처럼 "item-set" (가령, {doc_6e8, doc_6e9}, {doc_6e7, doc_6e9} 처럼 여러개 item 들이 들어 있는 바구니) 끼리의 연관규칙 관계를 시각화해줍니다. 

  • 화살표 두께(width) : item-set 간 연관규칙 지지도(support)에 비례하여 커짐
  • 화살표 색깔(color) : item-set 간 연관규칙 향상도(lift)에 비례하여 진해짐

type = "items" (위의 [그림1]) 일 때와 type = "itemsets" (아래의 [그림 2]) 일때의 동그라미로 표시해 둔 부분을 유심히 비교해서 살펴보시면 서로 연관규칙을 어떻게 표현하는 것인지 이해할 수 있을 것입니다. 서로 장단점이 있지요? 



[ 그림 2]  Graph-based visualization with item-sets as vertices



> plot(Epub_rule_2[55:65], method="graph", control=list(type="itemsets"))

 






 

6. 연관규칙을 CSV 파일로 저장

 

마지막으로 write() 함수를 사용해서 분석한 연관규칙을 CSV 파일로 저장해보겠습니다.  나중에 엑셀로 불러다가 후속 분석/작업하는데 필요할 수도 있겠지요?  file = "경로" 지정할 때 경로구분표시가 '\'가 아니라 '/' 로 해주어야 하는 것에 주의하시기 바랍니다. Windows 탐색기의 경로 그대로 복사해다가 붙이면 경로구분표시가 '\' 되어 있어서 오류납니다.

 

> # saving in CSV format : write() > write(Epub_rule_2, + file = "C:/Users/Owner/Documents/R/Epub_rule.csv", + sep = ",", + quote = TRUE, + row.names = FALSE)

 

 

 

마지막으로 as() 함수를 이용하여 연관규칙을 데이터프레임(dataframe) 구조로 변환해서 저장해보겠습니다.  연관규칙이 데이터프레임으로 되어있으면 다른 분석할 때 가져다 쓰기에 편하겠지요?

 

> # transforming into dataframe
> Epub_rule_df <- as(Epub_rule_2, "data.frame")

 

 

> str(Epub_rule_df)
'data.frame':	65 obs. of  4 variables:
 $ rules     : Factor w/ 65 levels "{doc_16e} => {doc_4ac}",..: 22 23 14 44 26 20 43 41 42 38 ...
 $ support   : num  0.00121 0.00121 0.00108 0.00108 0.00108 ...
 $ confidence: num  0.655 0.559 0.205 0.37 0.333 ...
 $ lift      : num  303.1 303.1 11.2 114 114 ...

 

 

 

데이터프레임으로 만들었으니 이전 포스팅에서 배웠던 IS(Interest-Support) Measure 와 교차지지도(cross support) 흥미측도를 생성할 수 있습니다.  R arules 패키지에서 자동으로 생성해주는 것은 지지도(support), 신뢰도(confidence), 향상도(lift) 3개뿐이다 보니 IS측도나 교차지지도는 직접 코딩해서 계산해줘야 합니다. 

 

아래 예시는 IS 기준으로 내림차순한 다음에 IS측도 상위 10개만 indexing한 것입니다.  (교차지지도는 최소지지도, 최대지지도 구해서 나눠줘야 하는 복잡함이 있으므로 패쓰... ^^; )

 

> # IS(Interest-Support) measure = sqrt(lift(A,B)*support(A,B))
> Epub_rule_df <- transform(Epub_rule_df, IS = sqrt(lift*support))
> Epub_rule_df[order(-Epub_rule_df$IS), ][1:10, ]
                            rules     support confidence     lift        IS
65 {doc_6e7,doc_6e8} => {doc_6e9} 0.001080806  0.8095238 454.7500 0.7010682
64 {doc_6e7,doc_6e9} => {doc_6e8} 0.001080806  0.8500000 417.8016 0.6719840
63 {doc_6e8,doc_6e9} => {doc_6e7} 0.001080806  0.8947368 402.0947 0.6592317
9          {doc_6e9} => {doc_6e7} 0.001271537  0.7142857 321.0000 0.6388766
10         {doc_6e7} => {doc_6e9} 0.001271537  0.5714286 321.0000 0.6388766
7          {doc_6e9} => {doc_6e8} 0.001207960  0.6785714 333.5391 0.6347454
8          {doc_6e8} => {doc_6e9} 0.001207960  0.5937500 333.5391 0.6347454
13         {doc_6e8} => {doc_6e7} 0.001335113  0.6562500 294.9187 0.6274950
14         {doc_6e7} => {doc_6e8} 0.001335113  0.6000000 294.9187 0.6274950
1          {doc_506} => {doc_507} 0.001207960  0.6551724 303.0943 0.6050833

 

 

 

이상으로 R arules 패키지를 사용해서 연관규칙 분석하는 방법을 마치도록 하겠습니다.

 

다음번 포스팅에서는 범주형 데이터의 연관분석에 대하여 알아보도록 하겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾸욱 눌러주세요.

 


 

 

연관규칙 분석을 위해 transactions format으로 데이터를 변환하는 방법에 대한 질문이 자주 있어서 아래와 같이 데이터 유형별로 예를 들어 정리하였습니다. 참고하세요.

 

 

##==== [참고] List를 transactons format 으로 변환하기 ====

 

 

> ##------------------------------------------
> ## List -> transactions 자료로 변환
> ##------------------------------------------
> # transaction list
> tr_list <- list(c("a", "b"), 
+                 c("a", "c"), 
+                 c("b", "c", "d"), 
+                 c("a", "e"), 
+                 c("c", "d", "e"))
> # set transaction names
> names(tr_list) <- paste("tr", c(1:5), sep = "_")
> tr_list
$tr_1
[1] "a" "b"

$tr_2
[1] "a" "c"

$tr_3
[1] "b" "c" "d"

$tr_4
[1] "a" "e"

$tr_5
[1] "c" "d" "e"

> tr <- as(tr_list, "transactions")
> tr
transactions in sparse format with
 5 transactions (rows) and
 5 items (columns)
> summary(tr)
transactions as itemMatrix in sparse format with
 5 rows (elements/itemsets/transactions) and
 5 columns (items) and a density of 0.48 

most frequent items:
      a       c       b       d       e (Other) 
      3       3       2       2       2       0 

element (itemset/transaction) length distribution:
sizes
2 3 
3 2 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    2.0     2.0     2.0     2.4     3.0     3.0 

includes extended item information - examples:
  labels
1      a
2      b
3      c

includes extended transaction information - examples:
  transactionID
1          tr_1
2          tr_2
3          tr_3

 

 

 

 

##==== [참고] Matrix를 transactions format 으로 변환하기 ====

 

 

> ##-------------------------------------------
> ## Matrix -> transactions 자료로 변환
> ##-------------------------------------------
> tr_matrix <- matrix(c(1, 1, 0, 0, 0, 
+                       1, 0, 1, 0, 0, 
+                       0, 1 , 1, 1, 0, 
+                       1, 0, 0, 0, 1, 
+                       0, 0, 1, 1, 1), 
+                     ncol = 5)
> # set dim names
> dimnames(tr_matrix) <- list(c("a", "b", "c", "d", "e"),
+ paste("tr", c(1:5), sep = "_"))
> tr_matrix
  tr_1 tr_2 tr_3 tr_4 tr_5
a    1    1    0    1    0
b    1    0    1    0    0
c    0    1    1    0    1
d    0    0    1    0    1
e    0    0    0    1    1
> # coerce into transactions
> tr2 <- as(tr_matrix, "transactions")
> tr2
transactions in sparse format with
 5 transactions (rows) and
 5 items (columns)
> summary(tr2)
transactions as itemMatrix in sparse format with
 5 rows (elements/itemsets/transactions) and
 5 columns (items) and a density of 0.48 

most frequent items:
   tr_3    tr_5    tr_1    tr_2    tr_4 (Other) 
      3       3       2       2       2       0 

element (itemset/transaction) length distribution:
sizes
2 3 
3 2 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    2.0     2.0     2.0     2.4     3.0     3.0 

includes extended item information - examples:
  labels
1   tr_1
2   tr_2
3   tr_3

includes extended transaction information - examples:
  transactionID
1             a
2             b
3             c

 

 

 

 

##==== [참고] DataFrame을 transactions format 으로 변환하기 ( 1 ) ====

 

 

> ##------------------------------------------------
> ## data.frame -> transactions 자료로 변환
> ##------------------------------------------------
> tr_dataframe <- data.frame(
+   age = as.factor(c("30대", "20대", "30대", "40대", "10대")), 
+   grade = as.factor(c("A", "B", "A", "A", "C")))
> 
> # coerce into transactions
> tr3 <- as(tr_dataframe, "transactions")
> 
> tr3
transactions in sparse format with
 5 transactions (rows) and
 7 items (columns)
> summary(tr3)
transactions as itemMatrix in sparse format with
 5 rows (elements/itemsets/transactions) and
 7 columns (items) and a density of 0.2857143 

most frequent items:
 grade=A age=30대 age=10대 age=20대 age=40대  (Other) 
       3        2        1        1        1        2 

element (itemset/transaction) length distribution:
sizes
2 
5 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      2       2       2       2       2       2 

includes extended item information - examples:
    labels variables levels
1 age=10대       age   10대
2 age=20대       age   20대
3 age=30대       age   30대

includes extended transaction information - examples:
  transactionID
1             1
2             2
3             3 

 

 

 

##==== [참고] DataFrame을 transactions format 으로 변환하기 ( 2 ) =====

 

 

> ## as(split([dadaframe[,"itemID"], dataframe[,"transactionID"]), "transactions") 함수
> ##-- making data.frame
> transactionID <- c(rep("tr1", 3), rep("tr2", 4))
> itemID <- c("item1", "item2", "item3", "item1", "item2", "item4", "item5")
> tr_df <- data.frame(transactionID, itemID)
> str(tr_df)
'data.frame': 7 obs. of  2 variables:
$ transactionID: Factor w/ 2 levels "tr1","tr2": 1 1 1 2 2 2 2
$ itemID       : Factor w/ 5 levels "item1","item2",..: 1 2 3 1 2 4 5
>
> ## converting data.frame to transactions format
> tr <- as(split(tr_df[,"itemID"], tr_df[,"transactionID"]), "transactions")
> inspect(tr)
    items                     transactionID
[1] {item1,item2,item3}       tr1         
[2] {item1,item2,item4,item5} tr2 

 

많은 도움 되었기를 바랍니다.

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. kjh 2016.08.25 23:27  댓글주소  수정/삭제  댓글쓰기

    와,,, 좋은글 감사합니다

  2. 리암 2016.09.05 17:36  댓글주소  수정/삭제  댓글쓰기

    안녕하세요? 또 질문 드립니다 ^^;
    아래와 같이 104개의 규칙이 생성되었고, support, confidence, lift 등 수치를 구했는데요. lift는 1을 기준으로, confidence는 0~1 값을 기준으로 높고 낮음 판단하면 될 것 같은데, support는 어떠한 기준으로 보통 높고 낮음을 판단하나요? 상대적인 기준으로 판단하나요?

    set of 104 rules

    rule length distribution (lhs + rhs):sizes
    2 3
    78 26

    Min. 1st Qu. Median Mean 3rd Qu. Max.
    2.00 2.00 2.00 2.25 2.25 3.00

    summary of quality measures:
    support confidence lift
    Min. :0.001244 Min. :0.2000 Min. : 2.612
    1st Qu.:0.001244 1st Qu.:0.4386 1st Qu.: 12.039
    Median :0.001244 Median :0.6250 Median :131.265
    Mean :0.002039 Mean :0.6404 Mean :233.051
    3rd Qu.:0.001555 3rd Qu.:0.8000 3rd Qu.:473.211
    Max. :0.019590 Max. :1.0000 Max. :804.000

    mining info:
    data ntransactions support confidence
    df_transaction 3216 0.001 0.2

    • R Friend R_Friend 2016.09.05 17:52 신고  댓글주소  수정/삭제

      단위 시간 당 최소 개수에 대한 의사결정/판단이 가능하다면 min support 계산할수 있습니다.

      가령 한달(30일) 총 거래건수 30,000건일때(즉, 하루 평균 1,000건 거래), 하루 최소 10건 이상은 거래가 되어야 의미가 있다고 판단했다면 한달이면 300건, min support= 300/30000=0.01

      이런식으로 대략 가늠해볼수 있습니다.

      rule이 100여개면 분석가가 quick하게 review할만한 규모네요. quick하게 보시고 min support 수준 주관적으로 설정해서 screening해서 분석해보시지요. 몇번의 trial & error 필요해요.

  3. Liam 2016.09.06 11:07 신고  댓글주소  수정/삭제  댓글쓰기

    답변 감사드립니다!

  4. noxan 2016.10.17 21:05  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. ^^;
    항상 좋은 방법론을 공유시켜주셔서 감사합니다.
    늘 도움이 되고 있습니다.

    다름이 아니라, 한가지 궁금증이 있어 여러 검색을 해도 쉽게 알 수가 없어 문의드리고 싶은 부분이 있어서요. : )

    바로 조건에 관련된 부분인데요.
    rule_interest_pin <- subset(Epub_rule_2, items %pin% c("60e"))

    위 코드에서 보신 것처럼, c("60e")를 갖고 있는 상품이 한개라도 있다면 해당 규칙을 발견하는것으로 이해했는데요,

    rule_interest_pin <- subset(Epub_rule_2, items %pin% c("60e","70e"))
    가령 70e라는 product가 있다고 가정 했을때, "60e"와 "70e"를 동시에 포함하는 조건절은 할 수 없는 것인지요.

    개인적으로 생각했던 부분으로 했을 경우
    Error in lhs %pin% c("60e", "70e") :‘60e’‘70e’ contains more than one item label pattern

    위와 같은 에러가 나오는데, 혹시 두 개이상의 조건으로 규칙을 탐색하는 방식이 있는지 여쭤보고자 합니다 ^^.

    항상 감사드리며, 소중한 댓글 부탁드립니다.

    • R Friend R_Friend 2016.10.17 21:31 신고  댓글주소  수정/삭제

      noxan님, 반갑습니다.

      %ain% 를 사용해서 rule 왼쪽에 ("doc_6e8", "doc_6e9")을 동시에 정확히 가지고 있는 rule을 선별해내는 R script 입니다. 참고하시기 바랍니다. 본문에도 update 해두었습니다.

      # select only itemsets matching all given item : subset(lhs %ain% "item")
      rule_interest_lhs_ain <- subset(Epub_rule_2, lhs %ain% c("doc_6e8", "doc_6e9"))
      inspect(rule_interest_lhs_ain)

      ###############
      %pin% 매개변수는 item 하나별로 부분만족여부를 판단하기 때문에 문의하신 목적으로는 부적합합니다. (에러 메시지 => Error in lhs %pin% c("60e", "70e") :‘60e’‘70e’ contains more than one item label pattern)

  5. noxan 2016.10.20 10:54  댓글주소  수정/삭제  댓글쓰기

    R friend님 친절한 답변 감사합니다 ^^

    덕분에 해결되었네요. 앞으로도 많은 관심을 갖고 페이지 방문하겠습니다

  6. r_kid 2016.11.22 02:49  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 좋은 포스팅 잘 보고 갑니다!!

    구글링을 아무리 해도 풀리지 않는 문제가 하나 있는데 여기서 그 실마리를 얻어서 한가지 여쭤보려고 합니다.

    제가 가지고 있는 데이터는 Item Matrix형태의 csv파일 입니다.
    즉 colname에 항목이 표시되어있고 그 아래에 0,1 로 항목의 유무를 나타내고 있습니다.

    이것을 read.Transaction 명령어로 불러올 수 있도록 Transaction data 형태로 바꾸어서 저장하고 싶은데
    여기에 도움이 될만한 내용을 알고 계신지요?

    혹시 알고 계시다면 답변 부탁드립니다ㅠㅠ

    • R Friend R_Friend 2016.11.22 11:06 신고  댓글주소  수정/삭제

      안녕하세요 r_kid님,

      item matrix 데이터프레임을 연관규칙분석을 위한 transactions format으로 변환하려면 아래처럼 한번 해보세요.

      install.packages("arules")
      library(arules)

      # transformation
      tran_form <- as(item_mat, "transactions")

      # check
      str(tran_form)

      inspect(tran_form)

  7. 노경모 2017.05.25 19:28 신고  댓글주소  수정/삭제  댓글쓰기

    plot(Epub_rule_2, method = "graph", control = list(type="items"))
    이 그래프를 그렸는데, 규칙수가 많아서 그런지 글자들이 잘 안보이네요. 혹시 글자의 사이즈를 줄일 수도 있나요? 혹시나 cex=0.8 이렇게 해봤는데 아래같은 오류가 뜨네요 ^^;

    Error in i.parse.plot.params(graph, list(...)) :
    Unknown plot parameters: cex

    • R Friend R_Friend 2017.05.26 00:02 신고  댓글주소  수정/삭제

      vertex.label.cex 파라미터로 라벨 글자 크기를 조절할 수 있습니다. 아래 R script 참고하세요.

      plot(Epub_rule_2, method = "graph", control = list(type="items"), vertex.label.cex = 0.5)

    • 노경모 2017.05.26 16:58 신고  댓글주소  수정/삭제

      igraph 함수를 사용하는거였군요! 바로 적용해보니 잘 됩니다, 감사합니다 ^^

      추가 질문 드립니다. 실제로 plot을 해보면 LHS, RHS에 해당하는 칼럼값들, 즉 중심이되는 변수들이 모든 화살표의 중심으로 모이고 주변은 원으로 연결됩니다. 그 원은 support와 lift로 연결이 되구요. 다만, plot을 해 본 결과 화살표의 중심은 알겠는데, 화살표를 둘러싼 동그라미에는 변수명이 없는 것 같아요. 특정 아이템들이 중심에 위치한 것만 이 그래프를 통해 봐야하는건가요?

      글로 쓸려니 잘 설명이 안되네요. 제가 아직 그래프 해석을 잘 못하는 것 같아 그런데, 도움 부탁 드립니다 ^^

    • R Friend R_Friend 2017.05.26 23:31 신고  댓글주소  수정/삭제

      노경모님, arulesViz package 가 igraph를 기본 뼈대로 해서 다른 시각화 패키지들을 엮어서 만든 것이다 보니 igraph 패키지의 파라미터를 사용해서 점이나 화살표 설정을 바꿀 수 있습니다.

      arulesViz 패키지의 연관규칙 시각화 해석하는 방법에 대해서 포스팅의 본문에 이미지 캡쳐해서 설명을 추가하였습니다.

      그래프 캡쳐하고 포스팅하려니 시간이 많이 걸리네요. ^^;;;

    • 노경모 2017.05.27 10:22 신고  댓글주소  수정/삭제

      감사합니다! 속이 다 시원하네요 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

  8. mch4791 2017.07.28 09:51  댓글주소  수정/삭제  댓글쓰기

    안녕하세요? 구글에서 검색하다 올려주신 글 보고 많은 도움이 되었습니다.

    개인작업하다 궁금한 점이 있어서 댓글을 적게 되었습니다.

    lhs에 조건을 넣고 있는데 위에 보니

    rule_interest_pin <- subset(Epub_rule_2, items %pin% c("60e"))

    구문이 있던데

    lhs에 조건을 아무것도 안넣을려고 하는데 어떻게 해야하는지 궁금합니다. "" null, na등 넣어보았는데 안되네요. ex) {} => 60e 이런 조건들을 검색할려고 합니다.(그러면 처음 사람들이 구매, 관심있는 데이터를 구할 수 있는것 같아서 시도중입니다.) 혹시 보시거든 답변 부탁드립니다. 감사합니다.

    • R Friend R_Friend 2017.07.31 18:30 신고  댓글주소  수정/삭제

      안녕하세요.

      문의하신 취지의 신규고객의 첫구매 상품 분석을 하시려면 연관분석 대신에 "신규고객 분석용 마트"를 별도로 만드셔서, 신규고객의 첫 거래 transaction만 가져다가 상품코드 기준으로 발생빈도만 카운트하시면 됩니다.

      좀더 아이디어를 내보면, 신규고객의 3개월후 혹은 6개월후의 고객상태(유지, 휴면, 이탈)나 등급(최우수, 우수, 일반, 휴면.이탈 등) 정보와 매핑해서 상태나 등급별로 첫 구매 상품의 차이가 있는지 카이제곱검정 해보시는것도 유용할것 같습니다.

      도움이 되었기를 바랍니다.

  9. 지나 2017.10.25 14:16  댓글주소  수정/삭제  댓글쓰기

    와 정말 자세히 설명주셔서 감사합니다. 관심가지고 자주 방문할게요!

  10. Yu 2019.01.14 16:46  댓글주소  수정/삭제  댓글쓰기

    안녕하세요.
    오늘 오전까지만해도 작성자님께 많은 도움을 받았습니다.
    다시 한 번 감사드립니다.

    혹시 정형데이터 말고 비정형데이터(논문, 소설 등..) 도 연관분석이 가능할까요?

    • R Friend R_Friend 2019.01.14 21:23 신고  댓글주소  수정/삭제

      분석 목적이 연관분석을사용하는 것이 맞는다면, 원 데이터를 연관분석을 할 수 있도록 transactions 포맷으로 전처리, 변환하해서 분석하면 됩니다.

지난번 포스팅에서는 연관규칙(association rule)의 평가척도로서 지지도(support), 신뢰도(confidence), 향상도(lift), IS측도(Interest-Support), 교차지지도(cross support) 에 대하여 알아보았습니다.

 

이번 포스팅에서는 연관규칙 (1세대) 알고리즘으로서 Apriori algorithm 에 대해 소개하도록 하겠습니다.  알고리즘을 이해하면 컴퓨터 내부에서 무슨 일이 일어나고 있는지, 컴퓨터가 어떻게 그 많은 연산을 효율적으로 수행하는지 원리를 알 수 있습니다.

 

 

 

1) 왜 효율적인 연관규칙 탐색 알고리즘이 필요한가?

 

거래에서 나타나는 모든 항목들의 집합(item set)을 이라고 할 때, 모든 가능한 부분집합의 개수는 공집합을 제외하고 개 입니다.

 

그리고 모든 가능한 연관규칙의 개수입니다.

 

이를 그래프로 나타내면 아래와 같은데요, 가능한 부분집합의 개수나 연관규칙의 개수가 item 이 증가할 때 마다 지수적으로 증가함을 알 수 있습니다.

 

item이 5개이면 subset 개수가 31개, rule 개수가 180개가 되며, => item이 10개만 되어도 subset 개수가 1023개, rule 개수가 57002 개가 됩니다.  이렇게 지수적으로 증가하는 subset과 rule들을 연필과 종이를 가지고 일일이 계산한다는 것은 미친짓입니다.  그리고 컴퓨터로 계산한다고 해도 계산복잡도와 필요 연산량이 어마무시하게 많아져서 시간이 굉~장히 오래 걸립니다.(심하면 하루를 꼬박 넘기고, 이틀, 사흘....)  이러므로 "빠르고 효율적인 연관규칙 계산 알고리즘"과 "연관규칙 평가 측도(기준)"이 필요한 것입니다.  

 

 

 

 

 

5개의 원소 항목을 가지는 I={A, B, C, D, E} 에 대하여 가능한 모든 항목집합을 예시로 풀어보면 아래와 같습니다. 

 

 

 

 

 

2) 연관규칙 생성 전략 및 Algorithm에는 무엇이 있나?

 

부분집합의 개수가 2^k - 1 개로서 지수적으로 증가하기 때문에 모든 경우의 수에 대해 지지도를 계산하는 것이 연산량이 엄청납니다. 그래서 연산량을 줄이기 위해 아래의 3가지 전략 중의 하나를 사용합니다.

 

1) 모든 가능한 항목집합의 개수(M)를 줄이는 전략 ▶ Apriori algorithm

2) Transaction 개수(N)을 줄이는 전략 ▶ DHP algorithm

3) 비교하는 수(W)를 줄이는 전략 ▶ FP-growth algorithm

 

 

 

3) 빈발항목집합을 추출하는 Apriori algorithm 의 원리, 원칙은 무엇인가?

 

위의 3개의 알고리즘 중에서 1세대 Apriori algorithm에 대해서만 예를 들어서 설명해보겠습니다.

 

최소지지도 이상을 갖는 항목집합을 빈발항목집합(frequent item set)이라고 합니다.  모든 항목집합에 대한 지지도를 계산하는 대신에 최소 지지도 이상의 빈발항목집합만을 찾아내서 연관규칙을 계산하는 것이 Apriori algorithm의 주요 내용입니다. 

 

빈발항목집합 추출의 Apriori Principle

 

1) 한 항목집합이 빈발(frequent)하다면 이 항목집합의 모든 부분집합은 역시 빈발항목집합이다.
(frequent item sets -> next step) 

 

2) 한 항목집합이 비비발(infrequent)하다면 이 항목집합을 포함하는 모든 집합은 비빈발항목집합이다. (superset -> pruning)

 

 

Apriori Pruning Principle


If there is any itemset which is infrequent, its superset should not be generated/tested
(Agrawal & Srikant @VLDB’94, Mannila, et al. @ KDD’ 94)

 

위의 Apriori Pruning Principal 을 도식화한 예시는 아래와 같습니다.  아래 예시 그림처럼 {A, B} item set이 비빈발항목(infrequent item set)이면 그 및에 {A, B}를 포함해서 줄줄이 딸린 {A, B, C}, {A, B, D}, {A, B, E}, {A, B, C, D}, {A, B, C, E}, {A, B, D, E}, {A, B, C, D, E}도 역시 비빈발항목인, 영양가 없는 superset 일 것이므로 볼 필요도 없으니 (안봐도 비디오...), 아예 처음부터 가지치기(pruning)를 하라는 것입니다. 

 

 

 

{A, B, C, D, E}의 5개 원소 항목을 가지는 4건의 transaction에서 minimum support 2건 (=2건/총4건=0.5) 기준으로 pruning 하는 예를 들어보겠습니다.

 

 

 

위의 예시를 tree 형식으로 색깔로 infrequent item set과 그의 하위 superset을 나타내보면 아래와 같습니다.  색깔 칠해진 superset 들은 가지치기(pruning) 당해서 지지도 계산을 하지 않게 됩니다.

 

 

[그림 1]

 

 

 

위에서 예와 그림으로 소개한 빈발항목집합 추출 Pseudo Aprior algorithm 은 아래와 같습니다.

 

Pseudo Apriori algorithm

 

[Reference] "Fast Algorithms for Mining Association Rules", Rakesh Agrawal, Ramakrishman Srikant, 1994

 

(위의 (3)번 apriori-gen(Lk-1) 에서 (k-1)-항목 빈발항목집합후보를 생성하고, (9)번에서 minimum support  count 보다 큰 빈발항목집합만 추출, 즉 최소지지도 미만은 pruning)

 

 

4) 빈발항목집합의 후보를 생성하고 연관규칙을 도출하는 Apriori algorithm의 원리는?

 

이후에 빈발항목집합의 후보(candidates list)를 생성하고, 연관규칙을 생성한 후에, 최소신뢰도 기준 (minimun confidence criteria)를 적용해서 최소 신뢰도에 미달하는 연관규칙은 제거(pruning)하게 됩니다. 

 

빈발항목집합 후보를 생성하기 위해, (k-1)-항목 빈발항목집합에서 처음 (k-2) 항목이 같은 항목들만 혼합하여 k-항목 빈발항목집합 후보를 생성합니다. 

아래에 2-항목 빈발항목집합 을 가지고 3항목 빈발항목후보 를 생성하는 예를 들어보겠습니다.  2-항목 빈발항목집합에서 (k-1)-항목, 즉 1-항목이 같은 항목은 노란색을 칠한 {B}항목입니다. 따라서 {B}항목이 포함된 {B, C}와 {B, E}를 혼합해서 k-항목 빈발항목집합, 즉 3-항목 빈발항목집합 후보를 만들면 {B, C, E} 가 됩니다. 나머지 {A, B}, {C, E}는 무시하게 됩니다.  실제로 위의 [그림1]에서 살아남은 3-항목 빈발항목집합이 {B, C, E} 입니다 (3-항목 빈발항목의 나머지 항목집합은 superset으로서 pruned 됨).

 

 

[그림2]

 

[Reference] "R, SAS, MS-SQL을 활용한 데이터마이닝", 이정진, 자유아카데미, 2011

 

 

빈발항목집합을 도출했으므로 이제 연관규칙을 생성해보겠습니다.  빈발항목집합 L의 항목들을 공집합이 아닌 두 개의 서로 다른 부분집합 X와 Y로 나누어 하나의 연관규칙 X → Y를 만들었다고 합시다. k-항목 빈발항목집합 L은 최대 개(공집합과 전체집합 제외)의 연관규칙을 만들수가 있으며, 이중에서 최소신뢰도(minimum confidence) 조건을 만족하는 연관규칙을 찾으면 됩니다.

 

연관규칙 생성의 Apriori principle


빈발항목집합 L에 대하여 연관규칙 X → Y 가 최소신뢰도 기준을 만족하지 않으면 X의 어떠한 부분집합 X'에 대한 연관규칙 X' → L - X' 도 최소신뢰도 기준을 만족할 수 없다

 

 

3-항목 빈발항목집합 C3 {B, C, E}를 가지고 6개 (=2^k - 2 = 2^3 -2 = 8 - 2 =6개) 의 연관규칙을 만들어보면 아래 그림과 같습니다.  이때 가령 아래 검정색으로 테두리를 친 {C, E} → {B} 연관규칙이 최소신뢰도 기준에 미달했다고 할 경우, 그 밑에 딸린 {C} → {B, E}, {E} → {B, C} 연관규칙은 제거(pruning)하게 됩니다.

 

[그림3]

 

 

[그림1]에서 처럼 비빈발항목(infrequent)에 대해서 최소지지도(minimum support) 기준 미달 항목을 가지치기(pruning)하고 -> [그림2]에서 처럼 빈발항목후보를 생성한 후에 -> [그림3]에서 처럼 최소신뢰도(minimum confidence) 기준 미달하는 연관규칙을 제거해나가는 반복(iteration) 작업을 새로운 연관규칙이 없을 때까지 하게 됩니다.

 

 

다음번 포스팅에서는 R을 가지고 연관규칙 분석하는 예를 들어보겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ♡'를 꾸욱~ 눌러주세요.

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. kjh 2016.08.25 21:53  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 오늘도 어김없이 질문입니다 ㅎㅎ

    1. 최소지지도, 최소신뢰도는 어떻게 구하는지요?
    임의로 정한다는 것을 어디서 본 적이 있는 것 같은데, 일반적으로 정하는 규칙이나 수치가 있나요?

    2. 모든 가능한 연관규칙의 개수 3^k - 2^(k+1) + 1 은 어떻게 구한 수치인가요
    -> 아 이부분은 대강 알겠네요.
    -2^k 는 선행에만 항목집합이 있는 것, -2^k는 후행에만 항목집합이 있는것
    +1은 2번 빼준 공집합을 한번 더해준 것.. 인가보네요

    • R Friend R_Friend 2016.08.26 13:13 신고  댓글주소  수정/삭제

      최소지지도, 최소신뢰도 구하는 법칙은 없습니다. 분석 목적과 대상이 무엇이냐에 따라서 달라지며, 시행착오(trial & error) 시도가 필요합이다.

      최소 기준선이 너무 높으면 아예 rule이 안나올수도 있구요, 기준이 너무 낮으면 허접한 온갖 rule이 튀어나올수 있습니다.

  2. kjh 2016.08.25 22:22  댓글주소  수정/삭제  댓글쓰기

    4) 빈발항목집합의 후보를 생성하고 연관규칙을 도출하는 Apriori algorithm의 원리는?
    이부분 잘 모르겠어요 ㅠㅠ 특히 "2-항목 빈발항목집합에서 (k-1)-항목, 즉 1-항목이 같은 항목은 노란색을 칠한 {B}항목입니다. " 이부분이 무슨말인지 잘 모르겠네요..

    • R Friend R_Friend 2016.08.26 12:45 신고  댓글주소  수정/삭제

      [그림2]를 참고하시기 바랍니다. 처음 2항목에서는 k=2이므로, k-1=1 항목의 첫번째가 같은거를 보면 'B'가 같으므로 (B, C)와 (B, E)를 묶어서 3항목(k=3) 집합 (B, C, E)를 만들고, 나머지는 pruning 했다는 뜻입니다.

      본문이랑 동어반복한거 같네요 ^^;;;

  3. curycu 2017.02.20 16:24  댓글주소  수정/삭제  댓글쓰기

    알찬 포스팅 잘보고 갑니다/ 감사합니다 :)

  4. 8dialshhu 2017.03.02 18:21  댓글주소  수정/삭제  댓글쓰기

    가능한 모든 룰의 개수가 왜 (3^k - 2^(k+1) + 1) 인지 이해가 안되는데요.
    설명해주실수 있나요??

    • R Friend R_Friend 2017.04.30 21:16 신고  댓글주소  수정/삭제

      (1) 거래에서 나타나는 모든 항목들의 집합(item set)을 I={i1, i2, ..., ik} 라고 할 때, 모든 가능한 부분집합의 개수는 공집합을 제외하고 M=2^k - 1 개입니다.

      (2) 항목집합 L의 항목들을 공집합이 아닌 두 개의 서로 다른 부분집합 X와 Y로 나누어 하나의 연관규칙 X -> Y 를 만들었다고 할 때 k-항목 집합 L은 공집합과 전체집합을 제외하고 최대 2^k -2 개의 연관규칙을 만들 수 있습니다.

      (1) 번에서 나온 '모든 가능한 부분집합의 개수 M=2^k - 1 개'에 대해서 => (2)번에서 설명한 'k-항목 집합 L은 공집합과 전체집합을 제외하고 최대 2^k -2 개의 연관규칙'을 적용하면 => '모든 가능한 연관규칙의 개수는 3^k - 2^(k+1) + 1 이 됩니다.

      수식 전개는 저도 따로 안해봤는데요, k 에 4나 5처럼 작은 숫자 적용해서 몇 개 적용해보시면 연관규칙 만드는 경우의 수가 어떻게 되는지 이해하실 수 있을거 같아요.

  5. lcg 2017.03.25 20:38  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 정말 좋은 글 잘 읽고 있습니다

    앞으로 포스팅 2개씩 인쇄하면서 앞으로 공부하려고 합니다 ㅎㅎ

    알고리즘 관련해서 위엣분과 마찬가지로 모든 룰의 개수 구하는 방법이 궁금합니다.

    수학에 대해 손 놓은지가 좀 오래되서 잘 모르겠습니다 !!

    • R Friend R_Friend 2017.04.30 21:16 신고  댓글주소  수정/삭제

      (1) 거래에서 나타나는 모든 항목들의 집합(item set)을 I={i1, i2, ..., ik} 라고 할 때, 모든 가능한 부분집합의 개수는 공집합을 제외하고 M=2^k - 1 개입니다.

      (2) 항목집합 L의 항목들을 공집합이 아닌 두 개의 서로 다른 부분집합 X와 Y로 나누어 하나의 연관규칙 X -> Y 를 만들었다고 할 때 k-항목 집합 L은 공집합과 전체집합을 제외하고 최대 2^k -2 개의 연관규칙을 만들 수 있습니다.

      (1) 번에서 나온 '모든 가능한 부분집합의 개수 M=2^k - 1 개'에 대해서 => (2)번에서 설명한 'k-항목 집합 L은 공집합과 전체집합을 제외하고 최대 2^k -2 개의 연관규칙'을 적용하면 => '모든 가능한 연관규칙의 개수는 3^k - 2^(k+1) + 1 이 됩니다.

      수식 전개는 저도 따로 안해봤는데요, k 에 4나 5처럼 작은 숫자 적용해서 몇 개 적용해보시면 연관규칙 만드는 경우의 수가 어떻게 되는지 이해하실 수 있을거 같아요.

  6. 도른자 2017.06.28 16:02  댓글주소  수정/삭제  댓글쓰기

    마지막에 {C, E} > {B} Rule은 확률이 100% 아닌가요? 왜 Pruning 되는지 이해가 안되요. 도와주세요.

    --> 자체수정
    아 그냥 예시를 드셨던 것 뿐이었군요
    제 개인적인 생각으로는
    {C, E} > {B}는 100%라서 오해할 가능성이 있는 것 같아요.
    {B,C} > {E}가 66.66%이므로 요걸로 하시고 최소신뢰도가 70%라 한다면 의미가 통할 것 같습니다.

    어쨋든 좋은 글 감사합니다.

  7. HS 2017.12.28 11:41  댓글주소  수정/삭제  댓글쓰기

    매번 눈팅으로 보다가 늦게나마 감사인사를 드립니다.

    알찬 내용 제공해주셔서 정말 감사드립니다. ^^

지난번 포스팅에서는 연관규칙분석, 장바구니분석, 순차분석의 개략적인 정의와 활용에 대해서 알아보았습니다.

 

이번 포스팅에서는 연관규칙(association rule)의 흥미를 평가할 수 있는 척도(interestingness measure) 들로서 지지도, 신뢰도, 향상도, IS측도, 교차지지도에 대해서 알아보겠습니다.

 

(참고. 연관규칙은 비지도학습으로서, Y값에 대한 label이 없는 상태에서 데이터에 숨겨진 패턴을 찾는 분석기법임.  Y값에 대한 label을 가지고 하는 지도학습인 예측이나 분류에서 하는 모델 성과평가와 Y값 label 없이 숨겨진 패턴을 찾는 연관규칙의 흥미척도는 성격이 다름)

 

이들 연관규칙 평가 척도가 중요한 이유는 연관규칙 분석을 하게 되면 수십, 수백, 수천개의 association rule 들이 쏟아지기 때문에 육안으로 일일이 보고 평가하기가 너무 힘들기 때문입니다.  (1) 모래사장에서 보석반지를 눈으로 찾는 방법과, (2) 모래를 거를 수 있는 체(screening filter)에 다가 삽으로 모래를 퍼다가 부어서 체에 걸러진 물건들 속에서 보석반지가 있나 확인하는 방법 중에서 어떤 것이 더 효율적이고 효과적일지 생각해보시면 됩니다.  (2)번  체를 사용하는 후자 방법에서 사용하는 체가 오늘 포스팅의 주제가 되겠습니다.

 

 

X와 Y를 서로 공통원소가 없는 항목들의 집합이라고 하고, X->Y 를 if X then B라는 연관규칙이라고 하며, N은 전체 거래 건수, n(X), n(Y)는 항목집합 X와 Y의 거래 건수(즉, row 개수)라고 했을 때, 지지도(Support), 신뢰도(Confidence), 향상도(Lift)의 정의는 아래와 같습니다.

 

  • 지지도 (Support)

    :
    두 항목 XY의 지지도는 전체 거래 건수 중에서 항목집합 XY를 모두 포함하는 거래 건수의 비율을 말합니다.   지지도는 좋은 규칙(빈도가 많은, 구성비가 높은)을 찾거나, 불필요한 연산을 줄일 때(prunning, 가지치기)의 기준으로 사용합니다.

지지도(support) s(X→Y) 

= X와 Y를 모두 포함하는 거래 수 / 전체 거래 수 = n(X∪Y) / N 


 

  • 신뢰도 (Confidence)

    : 항목집합 X를 포함하는 거래 중에서 항목집합 Y포함하는 거래 비율 (조건부 확률) 을 말합니다.  신뢰도가 높을 수록 유용한 규칙일 가능성 높다고 할 수 있습니다.

신뢰도(Confidence) c(X→Y) 

= X와 Y를 모두 포함하는 거래 수 / X가 포함된 거래 수 = n(X∪Y) / n(X) 

 

 

  • 향상도 (Lift)

    항목집합 X가 주어지지 않았을 때의 항목집합 Y의 확률 대비 항목집합 X가 주어졌을 대 항목집합 Y의 확률 증가 비율을 말합니다. 다른말로 표현하자면, 향상도가 1보다 크거나(+관계) 작다면(-관계) 우연적 기회(random chance)보다 우수함을 의미합니다. (X와 Y가 서로 독립이면 Lift = 1)

향상도(Lift)

= 연관규칙의 신뢰도/지지도 = c(X→Y) / s(Y)

 

 

 

연관규칙 평가 척도 : 지지도(Support), 신뢰도(Confidence), 향상도(Lift)

 

 

아래에 어떤 슈퍼마켓에서 5명의 고객에 의해서 발생한 5건의 거래(transaction N=5)을 가지고 예를 들어보았습니다.

 

 

참고로, 신뢰도(confidence)는 rule의 순서에 따라서 값이 달라집니다. 즉 신뢰도 c(X→Y)와 c(Y→X)의 값이 다르며, 이를 비대칭적 척도(asymmetric measure)라고 합니다.

 

반면에, 향상도(lift)는 Lift(X→Y) 값과 Lift(Y→X)의 값이 서로 같으며, 이런 특성을 가지는 척도를 대칭적 척도(symmetric measure)라고 합니다.  위의 예제를 가지고 한번 직접 계산해서 확인해보시기 바랍니다.

 

 

위의 3개의 rule 평가 척도를 소개하였는데요, 각각의 평가 관점이 다르기 때문에 어느 하나만을 가지고 rule을 평가하는 것이 아니라 보통은 3개의 척도를 모두 사용합니다.

 

보통 (1) 특정 지지도(Support) 와 신뢰도(Confidence) 이하의 rule 은 screening out 시키게끔 해놓고,

(minimun support, minimum confidence)

 

(2) 향상도(Lift) 내림차순(양의 관계를 찾을 때)으로 sorting을 해서 rule을 평가하는 식으로 이용하곤 합니다. 

 

그리고 관심이 있는 상품이나 item이 있으면 목적에 맞게 해당 item이 left-hand side 나 right-hand side 에 있는 rule만을 subset으로 선별해서 보기도 하구요.

 

 

분석에 oriented 된 통계전문가, 기계학습 전문가의 경우 신뢰도(confidence)와 향상도(lift)가 높은 rule을 눈에 불을 켜고 찾고, 선호하는 경향이 있습니다.  그런데 매출과 이익을 책임져야 하는 사업부 현업의 경우는 연관규칙을 보는 view가 조금 다를 수 있습니다.  "그 rule을 적용하면 기대할 수 있는 매출 증가분이 얼마나 되는데요?"라는 질문이 사업부 현업이 던지는 질문인데요, 이 질문에 만족할 만한 답을 주려면 '지지도(Support)'가 높아서 전체 거래 건수 중에서 해당 rule이 포함된 거래건수가 많아야지만이 해당 rule을 가지고 마케팅전략을 수립해서 실전에 적용했을 때 높은 매출 증가를 기대할 수 있게 됩니다.  즉, 아무리 신뢰도(confidence)와 향상도(lift)가 높아도 지지도(support)가 빈약해서 전체 거래 중에 가뭄에 콩나듯이 나오는 거래유형의 rule이라면 사업부 현업은 아마 무시할 겁니다.  현업을 빼고 분석가만 참여한 연관규칙 분석이 위험하거나 아니면 실효성이 떨어질 수 있는 이유입니다.  그리고 지지도(support)가 매우 낮으면 몇 개 소수이 관측치의 치우침만으로도 신뢰도나 향상도가 크게 영향을 받게 되어 '우연'에 의한 규칙이 잘못 선별될 위험도 있습니다.

 

 

위와 같이 지지도(support), 신뢰도(confidence), 향상도(lift)의 한계를 보완하기 위한 다양한 평가척도가 더 있는데요, 그 중에서도 IS(Interest-Support) 측도, 교차지지도(cross support) 에 대해서 간략하게 소개하겠습니다. 

 

연관규칙 A → B 에 대하여

  •  IS(Interest-Support) 측도 : 향상도(lift)와 지지도(support)의 곱에 제곱근을 취한 값

    ☞ 향상도(lift)와 지지도(support)가 모두 높을 수록 IS 측도값도 커짐. 둘 중에 하나라도 작으면 IS측도는 작아지며, 지지도는 낮고 향상도만 높은 rule이나 향상도는 낮고 지지도만 높은 rule을 screening out 시키고 둘다 높은 rule만 선별할 수 있음.

  • 교차지지도(cross support) : 최대지지도에 대한 최소지지도의 비율


    ☞ 항목집합 에 대하여 의미 없는 연관규칙의 생성을 방지하기 위하여 교차지지도 r(X)를 이용함.  분자에 지지도 중에서 최소값을, 분모에는 지지도 중에서 최대값을 가져다가 계산을 하므로 지지도의 최소값과 최대값의 차이가 클 수록 교차지지도는 낮아지게 되며, 이 비율이 매우 작으면 항목집합 X에서 생성되는 연관규칙이 의미가 없을 가능성이 높음.

 

지지도(support), 신뢰도(confidence), 향상도(lift), 이에 더해 IS측도나 교차지지도 등의 척도만을 가지고 기계적으로 연관규칙을 찾았다고 해서 끝나는 것은 아닙니다.  반드시 업 전문가(business domain expert)의 해석, 평가, 판단, 개입이 있어야지 연관규칙분석이 끝이 납니다.

 

 

연관규칙을 (1) 설명이 가능한가? (Explainable), (2) 활용이 가능한가? (Actionable) 라는 두 개의 기준을 가지고 평가를 해봐서 '설명이 가능하고 & 활용이 가능한 연관규칙 (Explainable & Actionable association rule)' 만이 최종적으로 살아남아 현장에 적용이 되고 그 효과를 검증받게 됩니다.

 

아래에 Useful rule, Trivial rule, Inexplicable rule의 예를 보면 금방 이해하실 수 있을 것입니다.  실제 연관규칙 분석을 해보면 rule이 엄청 많이 쏟아지는데 반해, 똘똘한 rule의 최종 판단/선별에 업 전문가의 개입이 필요하다는 점이 현장에서 많이 쓰이지 못하고 있는 장애 요인이 되고 있는게 아닌가 싶습니다.

 

 

 

다음번 포스팅에서는 Apriori algorithm 에 대해서 알아보도록 하겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ♡'를 꾸욱~ 눌러주세요.

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 항상 고맙습니다 2016.06.05 15:53  댓글주소  수정/삭제  댓글쓰기

    정말 짱 좋은 사이트인 것 같네요. 매번 공부할 때마다 참고하고 갑니다.

  2. 졍이 2016.07.15 16:31  댓글주소  수정/삭제  댓글쓰기

    r을 독학하는데 늘 너무너무너무 도움이되는 글들이 많습니다 ㅠㅠㅠ 정말 감사합니다!!

  3. kjh 2016.08.24 22:39  댓글주소  수정/삭제  댓글쓰기

    아직 다 꼼꼼히 읽어보지는 못했는데
    지지도랑 신뢰도 공식이 좀 잘못된듯해요
    분자가 A합B가 아니라 A교B 아닌가요?

    글 계속 열심히 읽고 공부하겠습니다~

    • R Friend R_Friend 2016.08.24 22:57 신고  댓글주소  수정/삭제

      kjh님, 반갑습니다.

      Support = n(X U Y)/N 으로 표기하는 것이 맞습니다.

      X, Y는 항목집합(item set)을 나타내며,
      n(X U Y) 는 X 항목집합과 Y 항목집합을 모두 포함하는 거래(transaction)의 개수를 나타냅니다.

      포스팅의 본문에 예제를 가지고 설명을 해보자면요, 연관규칙 X -> Y 에서 X = {계란, 맥주}, Y = {기저귀} 인 규칙이 있다고 했을 때, X U Y = {계란, 맥주, 기저귀}가 되며, 총 5개의 거래 (즉, N = 5) 중에서 X U Y = {계란, 맥주, 기저귀} 를 포함하는 거래는 2번과 4번 거래의 총 2개가 됩니다. 따라서 support(X -> Y) = n(X U Y)/N = 2/5=0.4 가 됩니다.

      제가 본문에 'X와 Y를 동시에 포함하는'이라고도 표기했다가 'X와 Y를 모두 포함하는'이라고도 했는데요, '동시에 포함하는'이 '교집합'으로 오해하기 쉬울거 같습니다. '모두 포함하는'으로 일괄되고 혼돈이 없도록 포스팅 본문 수정하였습니다.

    • arules 2019.05.06 16:29  댓글주소  수정/삭제

      R Friend R_Friends 님,

      지지도에 대하여 잘못 알고계시고, 포스팅 내용도 다시 검토해보셔야 겠네요.

      A->B일때, 지지도는 전체 거래 중에서 A와 B를 모두 포함하는 거래 수로 계산하며, 분자는 A와 B의 교집합이 맞습니다.

      또한, 본인 포스팅의 지지도, 신뢰도, 향상도 예시를 보면,
      (계란, 맥주) -> (기저귀) 일때,
      n(X U Y)이 2번, 4번이 맞나요? 합집합이라면 3번 거래도 포함이 되어야 할텐데요?

      표기는 합집합을 하시고, 계산은 교집합을 하신 이유가 있을까요?

      집합 연산이 어려우신 건지, 다른 사람의 글을 그대로 옮기신 건지 의문이 듭니다.

      추가로, 경우에 따라서 합집합으로 표시한 공식들은 잘 보시면, (X U Y)의 앞에 갯수를 의미하는 n이 아니라 support(X U Y)로 X, Y 각각의 확률 곱을 의미합니다.

      잘못된 정보는 바로 잡아야 할 것 같아 글을 남깁니다.

      댓글들에 대하여 답변해 주신 내용들을 보니 제가 말씀드린 오류를 인정하지 못하실 수도 있을 것 같아,

      불필요한 논란을 없애고자 참고하실 링크를 아래 남겨드립니다.

      https://en.wikipedia.org/wiki/Association_rule_learning#Support

      https://towardsdatascience.com/association-rules-2-aa9a77241654

    • R Friend R_Friend 2019.05.06 19:53 신고  댓글주소  수정/삭제

      arules님, 남겨주신 댓글과 링크 잘 보았습니다.

      댓글에서 "합집합일 때 3번 거래도 포함되어야 한다"고 말씀해주셨는데요, 예로 들었던 X={계란, 맥주} -> Y={기저귀} 의 합집합(XUY)는 {계란, 맥주, 기저귀} 이고, 교집합은 공집합입니다. 3번 거래에는 "계란"이 안들어있습니다.

      그리고 "표기는 합집합을 하고, 계산은 교집합을 했다"고 말씀하셨는데요, 제 생각에는 표기법에 대한 서로 간의 혼선, 오해, 이런것 때문인거 같습니다.

  4. kjh 2016.08.24 23:23  댓글주소  수정/삭제  댓글쓰기

    아.. 생각한 개념은 제대로 이해한게 맞는데, 표기법에 혼동이 있었네요.
    제가 가진 책에서는 교집합으로 나온 것도 있고, 구글에서 검색해보면 또 합집합으로 된 것도 있어서 안그래도 헷갈리고 있었거든요..

    제가 생각한 X와 Y의 개념은 event?이고 글에서의 X,Y는 item set이라서
    표기법에 대한 혼동이 있었던 것 같습니다.
    빠른 답변 감사합니다~

  5. rura6502 2016.09.01 20:43  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 포스팅한 글 잘 봤습니다.
    다름이 아니라 support와 confidence에 대해서 혼란이 와서요
    기저귀=>맥주 의 관계를 보면
    support는 전체 거래 건수 중 맥주와 기저귀가 포함되어 있는 비율
    confidence는 기저귀를 산 사람이 맥주를 살 확률
    이라고 이해를 했는데 맞나요?

    • rura6502 2016.09.01 20:48  댓글주소  수정/삭제

      아 다른데 둘러보다가 알게되었는데
      기저귀=>맥주 의 관계가
      support가 낮을 경우 "전체 거래중에 기저귀와 맥주를 산 사람의 거래가 낮으니 이 조건을 분석하는건 의미가 없다" 라는 뜻으로 해석될 수 있고
      confidence가 낮을 경우 말그대로 "기저귀를 산 사람의 거래 내역 중에 맥주를 같이 산 사람이 별로 없으니 기저귀와 맥주는 연관관계? 가 낮다" 라고 해석될수 있는거군요
      제가 이해한 것이 맞나요?

    • R Friend R_Friend 2016.09.01 20:48 신고  댓글주소  수정/삭제

      rura님, 맞게 이해하셨습니다. ^^

    • rura6502 2016.09.01 21:03  댓글주소  수정/삭제

      헉, 실시간 댓글 감사합니다.
      lift에 대해서 조금 쉽게 설명해주실수있을까요? 제가 무지해서 위의 내용으로는 난해해서요 ㅠㅠ

    • R Friend R_Friend 2016.09.01 21:08 신고  댓글주소  수정/삭제

      lift는 눈감고 무작위로 찍었을 때 대비 몇 배나 예측력(설명력)이 향상되었냐 하는 뜻으로 이해하시면 됩니다. 1 은 눈감고 찍은 것과 도찐개찐 별 차이 없다고 해석합니다.

      분모의 support(Y)는 전체 거래 중에서 Y항목을 포함한 비율이므로, 눈감고 뽑았을때 Y가 나올 확률입니다.

      분자는 X가 거래에 포함된걸 알았을때 Y도 함께 포함되어 있을 조건부확률이구요

    • rura6502 2016.09.01 21:18  댓글주소  수정/삭제

      lift는 위와 같이 예를 들면 거래 건수 중 기저귀를 샀을 때 맥주를 산 건이 100건이고 맥주를 산 건이 100건이면 보았을 때 기저귀와 맥주를 동시에 산 사람이나 맥주만 산 사람이나 100건 100건 똑같으니 구매자는 그냥 찍어서 샀구나 라고 해석될수있고 lift가 1보다 크면 위에 예시에 건수가 기저귀, 맥주가 같이 산 건이 더 많으니 두 품목은 끈끈한 관계의 정도, 1보다 작으면 관계가 없는 정도, 1이면 위에 예를 든대로 반반이므로 그냥 적당한? 관계가 있다고 해석될수 있다. 이렇게 이해했는데 맞나요?? 포스팅은 수준이 높은데 제가 너무 수준낮게 예시를 들어 설명하는거 같네요 ㅠㅠ

    • R Friend R_Friend 2016.09.01 21:24 신고  댓글주소  수정/삭제

      lift '1' 이 연관성 없음이구요, 만약 +2라면 무작위 찌끼 대비 '+(양)'의 '방향'으로 연관성이 있다는 뜻이고, 만약 '0.5'라면 if X then Y 동시구매가 잘 안일어난다고, 즉 '-'(음) 관계라고 해석할 수 있읍니다.

      '1'이 기준선입니다

    • rura6502 2016.09.01 21:27  댓글주소  수정/삭제

      답변감사합니다! 정말많은 도움이 됬습니다!

  6. Ashtray Kim 2016.10.02 12:48  댓글주소  수정/삭제  댓글쓰기

    support, confidence, lift 등을 구할 때 궁금한 점이 있는데요.
    위의 각 지표들을 구할 때, 거래 건수(X와 Y를 포함하는 거래 건수 등)를 가지고 계산을 하는 것 같은데요.
    그러면, 한 거래 내에서 동일한 item을 여러 개 구입한 경우에 대해서 차이가 없는 건가요?
    이부분을 고려한 알고리즘의 변형된 형태가 혹시 있는지 궁금합니다.

  7. Stonehead Park 2017.09.24 15:32  댓글주소  수정/삭제  댓글쓰기

    정말 좋은 포스트 잘 읽었습니다. 저절로 엄지손가락이 올라가는 글이에요!
    감사합니다. 그리고 경영을 전공하는 학생으로서 분석이 반드시 업 전문가와의
    협의가 마무리되어야 끝난다고 말씀하신 점이 와닿았습니다.

    간간히 찾아오겠습니다. 다시 한 번 감사합니다 :)

지난 포스팅에서 기계학습의 정의, 학습 및 과적합(overfitting)에 대한 큰 그림, 개략적이고 이론적인 내용을 다루었습니다.

 

이번 포스팅부터는 기계학습 분석 기법의 각론으로 들어가보겠습니다.

 

먼저, Y값(종속변수, 목표변수)이 없는 상태에서 데이터 속에 숨겨져 있는 패턴, 규칙을 찾아내는 비지도학습(unsupervised learning)의 하나인 '연관규칙분석(Association Rule Analysis)', 혹은 유통업계에서 사용하는 용어로 '장바구니분석(Market Basket Analysis)'에 대해서 알아보겠습니다.

 

보통 기계학습, 데이터마이닝 교육을 받는다고 하면 단골메뉴로 나오는 분석 기법이기도 하며, "맥주와 기저귀" 사례(이거 가짜 사례임... -_-')와 함께 많이 회자되곤 합니다.  그러다 보니 '회귀분석' 만큼이나 분석 강의 좀 들어봤다 하는 사람이면 열에 아홉은 연관규칙분석을 들어는 봤고, 그러다보니 만만하게(?) 보는 것도 좀 있는 것 같고요, rule이 엄청 많이 나오는데 그중에서 쓸모있는 것은 별로 찾지 못해서 재미를 잘 못보고 평가절하받는 기법인것도 같습니다.  

 

 

B2C 업종에 종사하는 분이라면 약방의 감초처럼 빼놓을 수 없는게 상품추천(recommendation) 일텐데요, 추천을 위해 많이 사용하는 분석 기법이 연관규칙분석, 순차분석입니다.

 

 

 

상품 추천에 사용하는 분석기법들을 아주 간략히 소개하자면,

  • 연관규칙분석, 장바구니분석 (Association Rule Analysis, Market Basket Analysis) : 고객의 대규모 거래데이터로부터 함께 구매가 발생하는 규칙(: A à 동시에 B)을 도출하여, 고객이 특정 상품 구매 시 이와 연관성 높은 상품을 추천
  • 순차분석 (Sequence Analysis)고객의 시간의 흐름에 따른 구매 패턴(A à 일정 시간 후 B)을 도출하여, 고객이 특정 상품 구매 시 일정 시간 후 적시에 상품 추천
  • Collaborative Filtering모든 고객의 상품 구매 이력을 수치화하고, 추천 대상이 되는 고객A와 다른 고객B에 대해 상관계수를 비교해서, 서로 높은 상관이 인정되는 경우 고객B가 구입 완료한 상품 중에 고객A가 미구입한 상품을 고객A에게 추천
  • Contents-based recommendation고객이 과거에 구매했던 상품들의 속성과 유사한 다른 상품 아이템 중 미구매 상품을 추천 (Collaborative Filtering유사 고객을 찾는 것과 비교됨)
  • Who-Which modeling특정 상품()을 추천하는 모형을 개발 (: 신형 G5 핸드폰 추천 스코어모형)하여 구매 가능성 높은(: 스코어 High) 고객() 대상 상품 추천

등이 있습니다. 

 

 

상품 추천은 이미 몇 십년 전부터 실전에 적용이 되어 왔고, 그 선진 업체들의 경우 효과를 톡톡히 보고 있습니다.

추천은 그 자체로 환전성이 있기 때문에 가치가 있다. 넷플릭스의 경우 대여되는 영화의 2/3가 추천을 통해 발생했으며, 구글 뉴스(Google News)의 경우 38% 이상이 추천을 통해서 조회가 발생하는 것으로 알려져 있다. 또한 아마존의 경우에도 추천을 통해 판매가 전체 매출액의 35%를 넘는다. ...

 

* 출처 : 넷플릭스의 빅데이터, 인문학적 상상력과의 접점, 조영신, KISDI 동향 Focus 

 

물론 연관규칙이나 순차분석만 가지고 상품추천하는 것은 아닙니다만, 연관규칙분석, 순차분석은 상품추천에 활용할 수 있는 가장 기본적인 분석기법임에는 틀림없습니다.  아래에 넥플릭스에서 상품추천에 이용하는 알고리즘 소개글을 보면 사용할 수 있는 데이터를 모조리 모아서, 분석기법을 여러개 조합해서 상품추천을 하고 있는것으로 보입니다.

 

넥플릭스는 이용자들이 동영상에 매긴 별점과 위치정보, 기기정보, 플레이버튼 클릭 수, 평일과 주말에 따른 선호 프로그램, 소셜 미디어 내에서 언급된 횟수 등을 분석해 알고리즘을 개발했다. 

* 출처 : 넷플릭스의 빅데이터, 인문학적 상상력과의 접점, 조영신, KISDI 동향 Focus 

 

 

암튼, 서두가 길었습니다.  연관규칙 본론으로 들어가겠습니다.

 

규칙(rule)이란 "if condition then result"  (if A --> B) 의 형식으로 표현을 합니다.

 

연관규칙(association rule)은 특정 사건이 발생하였을 때 함께 (빈번하게) 발생하는 또 다른 사건의 규칙을 말합니다. 

 

연관규칙에서 사용하는 기본 용어에 대해서 짚고 넘어가자면,

  • 항목 집합 (Item set) : 전체 Item (I) 중에서 가능한 부분 집합,
  • 항목 집합의 집합 (The set of item sets) : Item의 부분집합들로 구성된 집합,

 

연관규칙을 다시 좀 어려운 위의 용어를 사용해서 써보자면, 연관규칙이란 특정 항목 집합이 발생하였을 때 또 다른 항목 집합이 발생하는 규칙을 말합니다.

 

 

가령,

 

{맥주} --> {기저귀} 

  : 맥주를 사는 고객은 기저귀도 같이 산다

 

{남성, 금요일, 맥주} --> {기저귀}

  : 금요일에 맥주를 사는 남성 고객은
    기저귀도 같이 산다

 

같은 규칙이 연관규칙의 예가 되겠습니다.

 

 

 

 

연관규칙분석, 장바구니분석, 순차분석... 용어가 좀 헷갈릴 수 도 있는데요, 개념 이해를 위해 비교를 해보자면요,

 

연관규칙(association rule)은 "What goes WITH what?" 즉, 동시 구매품목에 관심을 가지는데 비해서, 순차분석(sequeuce analysis)은 "What goes AFTER what?" 처럼 시간의 순서에 따른 규칙에 관심을 가집니다.  연관분석할 때는 주문번호, 고객ID, 구매상품코드만 있으면 되는데요, 순차분석을 하려면 "Time-stamp" 변수가 추가로 꼭 필요합니다.

 

장바구니분석(Market basket analysis)는 연관규칙을 유통업에서 부르는 용어입니다. 도식화하자면 장바구니분석은 연관규칙의 부분집합(?)이라고도 할 수 있겠네요.

 

 

 

유통업에서 장바구니분석(연관분석)을 통해 상품 추천뿐만이 아니라 상품 진열이라든지 상품 패키징, 번들링, (홈쇼핑의 경우) 방송순서나 카달로그 배치 등 다방면에 적용을 할 수 있습니다.

 

연관규칙은 유통업말고도 여러 업종에서 사용되는데요, 의료계에서는 암 데이터 분석에서 단백질 서열과 자주 발견되는 DNA 패턴을 찾는다던지, 증상과 질병 간 연관관계 등을 찾는데 연관규칙을 사용합니다.

 

순차분석은 의료비 허위 청구 순서 패턴을 찾는다던지, 휴대폰서비스 이용 부당행위 사전 조합 식별, 불량 유발 공정/장비 패턴 탐지, 웹사이트나 모바일앱의 메뉴별 클릭 스트림 분석 등을 하는데 사용할 수 있습니다.

 

다음번 포스팅에서는 연관규칙의 평가 척도 (지지도, 신뢰도, 향상도)에 대해서 알아보도록 하겠습니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꼬옥 눌러주세요. ^^

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. 리암 2016.09.01 19:16  댓글주소  수정/삭제  댓글쓰기

    질문 하나만 드리겠습니다.
    연관성 분석을 위해 데이터셋을 추출했는데,중복값이 있어서요.
    '001 file2'가 같은 세션에서 발생했는데, 제거하는 게 맞을까요?

    > head(df)
    SessionId filename
    001 file1
    001 file2
    001 file2
    002 file3

    • R Friend R_Friend 2016.09.01 19:33 신고  댓글주소  수정/삭제

      리암님,
      만약 'Session ID' 가 'Customer ID'(identifier),
      'file name' 가이 'Purchase Product ID'(구매상품 장바구니, item set) 의 개념이라면 삭제하지않고 그대로 두고 분석합니다.

      동일 고객ID에 동일상품 품목이 빈번하게(frequently) 발생해야(질문하신 중복 상황) 연관규칙이 잘 나옵니다.

  2. 리암 2016.09.02 14:39  댓글주소  수정/삭제  댓글쓰기

    그렇군요! 답변 감사합니다

  3. 지나 2017.10.25 13:16  댓글주소  수정/삭제  댓글쓰기

    우연히 와서 보고 있습니다.
    정말 좋은 자료에요.
    감사드려요!

  4. 지나가는나그네 2019.06.03 09:05  댓글주소  수정/삭제  댓글쓰기

    연관규칙이랑 순차패턴의 차이를 명확하게 설명하는 글이 없었는데
    여기서 해결이 되네요ㅎㅎ 감사합니다