1. Identifying frequently purchased items with association rules

마지막으로 충동구매를 했던 때를 회상해보자. 이마트나 롯데마트 같은 식료품 매장의 계산대 줄에서 기다리면서 껌이나 초코바 같은 간식을 샀을 수도 있다. 어쩌면 늦은 밤에 기저귀를 사러 나가서 컵라면이나 네 캔에 만 원짜리 맥주를 집어들었을 것이다. 쇼핑몰 홈페이지에서 원래 사려던 상품 대신에 추천 상품 때문에 마음이 변해서 샀을 수도 있다. 이런 충동 구매는 우연의 일치가 아니라 정교한 데이터 분석 기법을 이용해서 구매 행동을 유도하는 패턴을 찾았기 때문이다.

예전의 추천 시스템은 마케팅 전문가와 재고 관리자 또는 구매자의 주관적 직관을 기반으로 했다. 최근에는 바코드 스캐너, 전산화된 재고 관리 시스템, 온라인 쇼핑 경향으로 엄청난 거래(transaction) 데이터가 구축되었으며, 구매 패턴을 학습하기 위해 머신 러닝을 적용하고 있다(요즘에는 E-Commerce가 아니라 A-Commerce라고도 말한다). 이런 업무를 보통 장바구니 분석(Market Basket Analysis)이라고 하는데, 마켓 데이터에 자주 적용되기 때문이다.

이 기법은 쇼핑 데이터로 창안됐지만 다른 상황에서도 유용하다. 어떤 작업이든 자신의 작업에 장바구니 분석 기법을 적용할 수 있다. 일반적으로 작업에는 다음과 같은 것들이 포함된다.

- 간단한 성능 측정치를 이용해 거대한 데이터베이스(DB)에서 연관성 찾기
- 거래 데이터의 특이점 파악하기
- 유용하고 실행 가능한 패턴의 식별 방법 알아두기

장바구니 분석의 결과는 실행 가능한 패턴이다. 따라서 이 기법을 적용하면서 업무에 대한 응용을 발견할 수도 있다.

2. Understanding association rules (연관 규칙의 이해)

장바구니 분석의 기본 단위는 아이템(Item)이며, 어떤 거래에도 나타날 수 있다. 하나 이상의 아이템 그룹은 대괄호로 묶어서 집합, 좀 더 구체적으로 아이템 집합(Item set)을 이룬다는 것을 나타낸다. 집합은 규칙성을 갖고 데이터에 나타난다. 일반적인 매장에서 볼 수 있는 다음의 거래처럼 거래는 아이템 집합으로 명시된다.

{bread, peanut butter, jelly}

장바구니 분석의 결과는 연관 규칙(Association Rule)의 모음으로, 아이템 집합 사이의 관계에 존재하는 패턴을 명시한다. 연관 규칙은 아이템 집합의 부분집합으로 구성되며, 규칙의 좌측(LHS, Left-hand Side)에 있는 집합을 규칙의 우측(RHS, Right-hand Side)에 있는 집합과 연관시켜 표시한다. LHS는 규칙을 실행하기 위해 만족돼야 하는 조건이며, RHS는 그 조건을 만족했을 때 기대하는 결과다. 예제 거래에서 식별된 규칙은 다음과 같은 형태로 표현될 수 있다.

{peanut butter, jelly} -> {bread}

쉽게 말하면 연관 규칙은 땅콩 버터(Peanut Butter)와 젤리(Jelly)가 함께 구매되면 빵(Bread)도 구매될 가능성이 있다는 것을 말한다. 다시 말해 "땅콩 버터와 젤리는 빵을 암시한다."이다.

연관 규칙은 예측을 위해 사용되는 것이 아니라 대규모 데이터베이스(DB)에서 자율적인 지식의 발견을 위해 사용된다. 이것은 분류와 예측 알고리즘과는 다르다. 그렇긴 하지만 연관 규칙 학습자는 분류 규칙 학습자의 여러 특징과 밀접하게 관련돼 있고, 특징을 공유한다는 것을 알 수 있다.

연관 규칙 학습자는 자율적이기 때문에 알고리즘이 훈련될 필요가 없다. 다시 말해 데이터가 사전에 레이블 될 필요가 없다. 프로그램은 흥미로운 연관성이 발견되기를 바라며, 데이터 셋에서 간단히 해방된다. 물론 단점은 학습자에 대해 정성적으로 유용성을 평가하는 것(늘 그렇듯 일종의 눈대중 검사) 이외에는 규칙 학습자의 성능을 객관적으로 측정하는 쉬운 방법이 없다는 것이다.

연관 규칙은 장바구니 분석에 가장 많이 사용되긴 하지만, 다양한 종류의 데이터에서 패턴을 찾을 때에도 유용하다. 잠재적인 응용에는 다음과 같은 것들이 포함된다.

 - 암 데이터에서 흥미로우며, 빈번히 발생하는 DNA 패턴과 단백질 서열의 검색
 - 사기성 신용카드 및 보험의 이용과 결합돼 발생하는 구매 또는 의료비 청구의 패턴 발견
 - 고객이 휴대폰 서비스를 중단하거나 결합(인터넷, 통신, 전화 요금) 패키지를 업그레이드할 때 선행되는 행동의 조합 식별

연관 규칙 분석은 대량의 항목 중에서 흥미로운 연관성을 찾기 위해 사용된다. 인간은 상당히 직관적으로 그런 통찰력을 갖게 되지만, 규칙 학습자 알고리즘이 몇 분 심지어 몇 초 안에 할 수 있는 것을 인간이 하려면 전문가 수준의 지식과 수많은 경험을 필요로 한다. 또한 어떤 데이터 셋은 인간이 방대한 데이터에서 필요한 정보를 찾기에는 그야말로 너무 크고 복잡하다.

2.1. The Apriori algorithm for association rules learning (연관 규칙 학습을 위한 아프리오리 알고리즘)

연관 규칙 분석이 인간에게 어려운 일인 것처럼 거래 데이터는 기계가 연관 규칙 마이닝하기 어렵게 만든다. 일반적으로 거래 데이터셋은 모니터링되는 아이템이나 특징의 개수 뿐만 아니라 거래 횟수 측면에서도 극단적으로 크다. 문제는 잠재적인 아이템 집합의 개수가 특징의 개수에 따라 기하급수적으로 증가한다는 점이다. 집합에 나타나거나 나타나지 않을 수 있는 k개 아이템이 있다면 잠재적인 규칙이 될 수 있는 \(2^k\)개의 가능한 아이템 집합이 존재한다. 단지 100가지 아이템을 판매하는 소매업자는 알고리즘으로 평가해야 할 \(2^100 = 1.27e+30\)개의 아이템 집합을 갖는다(보기에 불가능한 작업이다).

좀 더 똑똑한 학습 알고리즘은 아이템 집합을 하나씩 평가하는 대신 많은 잠재적인 아이템 조합이 실제 드물게 발견된다는 사실을 이용한다. 예를 들어 상점에서 자동차 아이템과 여성의 화장품을 모두 판매하더라도, {motor oil, lipstick} 집합은 이례적으로 흔치 않다. 이 흔치 않은 (그리고 아마 덜 중요한) 조합을 무시함으로써 규칙의 검색 범위를 좀 더 다루기 쉬운 크기로 제한할 수 있다.

검색할 아이템 집합의 개수를 줄이기 위한 휴리스틱 알고리즘을 찾아내려는 많은 연구들이 진행돼 왔다. 큰 데이터베이스에서 규칙을 효율적으로 찾기 위해 가장 광범위하게 사용되는 방법이 아프리오리(Apriori)라고 알려져 있다. 알고리즘이 빈번한 아이템 집합의 속성에 대해 단순한 사전의 (즉, 선험적 a priori) 믿음을 이용한다는 사실에서 이름이 유래됐다.

좀 더 자세히 논의하기 전에 모든 학습 알고리즘과 마찬가지로 이 알고리즘도 장단점이 있는데 아래와 같다.

장점 단점
대규모 거래 데이터데 대해 작업할 수 있다. 작은 데이터 셋에서는 그다지 유용하지 않다.
이해하기 쉬운 규칙을 생성한다. 진정한 통찰과 상식을 분리하기 위한 노력이 필요하다.
’데이터 마이닝’과 데이터베이스에서 예상치 못한 지식을 발굴하는데 유용하다. 랜덤 패턴에서 비논리적인 결론을 도출하기 쉽다.

앞에서 언급했던 것처럼 아프리오리 알고리즘은 연관 규칙의 검색 공간을 축소하기 위해 단순한 선험적(a priori)믿음을 이용한다. 즉, 빈번한 아이템 집합의 모든 부분집합도 빈번해야만 한다. 이 휴리스틱을 아프리오리 속성(Apriori property)이라고 한다. 이 기민한 관찰을 이용해 검색될 규칙의 개수를 극적으로 제한할 수 있다. 예를 들어 {motor oil, lipstick} 집합은 {motor oil}{lipstick}이 모두 빈번하게 발생해야만 빈번해질 수 있다. 결론적으로 모터 오일(moter oil)이나 립스틱(lipstick)이 빈번하지 않다면 이 아이템을 포함하는 어떤 집합이든 검색에서 제외될 수 있다.

이 원칙이 좀 더 현실적인 환경에서 어떻게 적용될 수 있는지 확인하기 위해 간단한 거래 데이터베이스(DB)를 고려해보자. 다음 표는 가상의 병원 선물가게에서 완료된 5건의 거래내역이다.

거래번호 구매된 아이템
1 {flowers, get well card, soda}
2 {plush toy bear, flowers, ballons, candy bar}
3 {get well card, candy bar, flowers}
4 {plush toy bear, ballons, soda}
5 {flowers, get well card, soda}

구매 내역을 살펴보면 몇 가지 전형적인 구매 패턴이 있다는 것을 추론할 수 있다. 아픈 친구나 가족을 방문하는 사람은 쾌유를 비는 카드(get well card)와 꽃(flowers)을 사는 경향이 있고, 산모에게 방문할 사람은 봉제 장난감 곰(plush toy bear)과 풍선(balloons)을 사는 경향이 있다. 그런 패턴은 사람들의 관심을 끌만큼 자주 나타나기 때문에 눈에 잘 띈다. 따라서 단순히 약간의 논리와 주제와 관련도니 경험을 적용해 규칙을 설명할 수 있다.

유사한 방식으로 아프리오리 알고리즘은 대규모 거래 데이터베이스에서 연관 규칙을 찾아내기 위해 통계 척도인 아이템 집합의 ’흥미도(interestingness)’를 이용한다. 다음 절에서는 아프리오리 알고리즘이 그런 흥미 척도를 어떻게 계산하는지, 그리고 학습될 규칙의 수를 줄이기 위해 아프리오리 속성과 어떻게 결합되는지를 살펴본다.

2.2. Measuring rule interest - support and confidence (규칙 흥미 측정 : 지지도와 신뢰도)

2.2.1. Support (지지도)

연관 규칙이 흥미롭게 여겨지는지 여부는 두 통계 척도인 지지도(Support)와 신뢰도(Confidence)에 의해 결정된다. 각 척도에 대해 최소 임계치를 제공하고 아프리오리 원칙(Apriori principle)을 적용해 보고되는 규칙의 개수를 쉽게 급격히 제한할 수도 있다. 따라서 이런 기준하에 제외되는 규칙의 유형을 주의 깊게 이해하는 것이 중요하다.

아이템 집합 또는 규칙의 지지도는 데이터에 발생하는 빈도를 측정한다. 예를 들어 아이템 집합 {get well card, flowers}은 병원 선물가게 데이터에서 3 / 5 = 0.6의 지지도를 갖는다. 비슷하게 {get well card} -> {flowers}에 대한 지지도도 0.6이다. 지지도는 어떤 아이템 집합에 대해서도 계산될 수 있으며, 심지어 하나의 아이템에 대해서도 가능하다. 예를 들어 {candy bar}에 대한 지지도는 2 / 5 = 0.4인데 캔디바(candy bar)가 구매의 40%에 나타나기 때문이다. 아이템 집합 X에 대한 지지도 함수는 다음과 같이 정의될 수 있다.

\[support(x) = \frac{count(X)}{N}\]

여기서 N은 데이터베이스의 거래 건수이고, count(X)는 아이템 집합 X를 포함하는 거래 건수이다.

2.2.2. Confidence (신뢰도)

규칙의 신뢰도는 예측 능력이나 정확도의 측정치다. X와 Y를 모두 포함하는 아이템 집합의 지지도를 X만 포함하는 아이템 집합의 지지도로 나눈 값으로 정의된다.

\[confidence(X\rightarrow Y) = \frac{support(X, Y)}{support(X)}\]

기본적으로 신뢰도는 아이템 또는 아이템 집합 X의 존재가 아이템 또는 아이템 집합 Y의 존재를 유발하는 거래의 비율을 말한다. X가 Y를 유발하는 신뢰도는 Y가 X를 유발하는 신뢰도와 같지 않다는 점을 기억하자(인과관계와 상관관계는 다르다). 예를 들어 {flower} -> {get well card}의 신뢰도는 0.6 / 0.8 = 0.75이다. 비교해보면 {get well card} -> {flowers}의 신뢰도는 0.6 / 0.6 = 1.0 이다. 이것이 꽃을 구매할 때 쾌유를 비는 카드도 함께 75%로 구매하는 반면, 쾌유를 비는 카드를 구매할 때는 꽃과 100% 연관된다는 것을 의미한다. 이 정보는 선물가게 관리에 매우 유용할 수 있다.


NOTE

지지도, 신뢰도는 베이지안 확률 규칙 사이에 유사성이 있다. 실제 support(A, B)는 \(P(A\cap B)\)와 동일하며, \(confidence(A \rightarrow B)\)는 P(B|A)와 동일하다. 다른 점은 상황 뿐이다.


{get well card} -> {flowers}와 같은 규칙을 강한 규칙(Strong rules)이라고 하는데, 높은 지지도와 신뢰도를 모두 갖기 때문이다. 좀 더 강한 규칙을 찾아내는 방법 중 하나는 선물가게에 모든 가능한 아이템의 조합을 관찰하고, 지지도와 신뢰도 값을 측정하며, 특정 흥미 수준을 만족하는 그런 규칙만 보고하는 것이다. 하지만 이전에 언급했듯이 이 전략은 아주 작은 데이터셋이 아니면 일반적으로 실행 가능할 수 없다.

다음 절에서 아프리오리 알고리즘이 최소 수준의 지지도와 신뢰도를 아프리오리 원칙과 함께 이용해 규칙의 개수를 좀 더 다루기 쉬운 수준으로 줄임으로써 강한 규칙을 빠르게 찾는 방법을 확인한다.

2.3. Building a set of rules with the Apriori principle (아프리오리 원칙을 이용한 규칙 집합의 구축)

아프리오리 원칙은 빈번한 아이템 집합의 모든 부분집합 또한 빈번해야 한다는 것을 말한다. 다시 말해 {A, B}가 빈번하다면 {A}와 {B} 모두 빈번해야만 한다. 당연히 지지도는 아이템 집합이 데이터에 나타나는 빈도를 나타낸다. 그러므로 {A}가 원하는 지지도 임계치를 만족하지 않는다면 {A, B} 또는 {A}를 포함하는 어떤 아이템 집합도 고려할 이유가 없다. 즉, 빈번할 수가 없다.

아프리오리 알고리즘은 이 논리를 사용해 실제 평가하기 전에 잠재적인 연관 규칙을 제외시킨다. 규칙을 생성하는 절차는 다음과 같은 두 단계로 일어난다.

1. 최소 지지도 임계치를 만족하는 모든 아이템 집합을 식별한다.
2. 이 아이템 집합에서 최소 신뢰도 임계치를 만족하는 아이템 집합으로 규칙을 생성한다.

첫 번째 단계는 여러 번 반복된다. 연속되는 반복에서 점점 커지는 일련의 아이템 집합의 지지도를 평가한다. 예를 들어 반복1은 1-아이템 아이템 집합(1-아이템 집합)을 평가하며, 반복2는 2-아이템 집합을 평가한다. 각 반복 \(i\)의 결과는 최소 지지도 임계치를 만족하는 모든 \(i - 아이템 집합\)의 집합이다.

반복 \(i\)에서 모든 아이템 집합은 반복 \(i + 1\)에서 평가할 후보 아이템 집합을 생성하기 위해 결합된다. 하지만 아프리오리 원칙은 다음 라운드가 시작하기 전이라도 아이템 집합을 일부 제거할 수 있다. {A}, {B}, {C}가 반복1에서 빈번하고 {D}는 빈번하지 않다면 반복2는 단지 {A, B}, {A, C}, {B, C}만 고려하게 될 것이다. 따라서 알고리즘은 D를 포함하는 집합이 선험적(a priori)으로 제거되지 않는다면 평가됐을 여섯 개의 아이템집합 대신 세 개의 아이템 집합만을 평가할 필요가 있다.

이 생각을 계속해서 반복2 동안 {A, B}와 {B, C}는 빈번한데 {A, C}는 빈번하지 않다는 것을 발견했다고 가정해보자. 반복3은 {A, B, C}의 지지도를 평가하면서 정상적으로 시작하지만 이 단계가 반드시 존재해야 하는 것은 아니다. 왜 아닐까? 아프리오리 원칙은 {A, C}가 빈번하지 않기 때문에 {A, B, C}는 빈번할 수 없다는 것을 말한다. 그러므로 반복3에서 새로운 아이템 집합이 생성되지 않는다면 알고리즘은 종료될 수 있다.

현 시점에서 아프리오리 알고리즘의 두 번째 단계가 시작될 수 있다. 빈번한 아이템 집합으로 이뤄진 집합이 있다면 연관 규칙은 모든 가능한 부분집합에서 생성된다. 예를 들어 {A, B}는 \({A} \rightarrow {B}\)\({B} \rightarrow {A}\)로 후보 규칙이 만들어진다. 이 규칙들은 최소 신뢰도 임계치에 대해 평가되며, 원하는 신뢰도 수준을 만족하지 않는 규칙은 모두 제거된다.

3. Identifying frequently purchased groceries with association rules

장바구니 분석은 여러 오프라인과 온라인 소매업체에서 사용하는 추천 시스템의 이면에 사용된다. 학습된 연관 규칙은 자주 함께 구매되는 아이템의 조합을 나타낸다. 이런 패턴을 알게 되면 식료품 체인이 재고를 최적화하고, 판촉 활동을 홍보하고, 매장의 실제 배치를 구성하는 새로운 방식에 대한 통찰력이 생긴다. 예를 들어 고객이 커피나 오렌지 주스를 아침 페이스트리와 함께 자주 구매한다면 페이스트리를 커피와 주스 가까이에 재배치해 수익을 증가시킬 수 있을 것이다.

이 사용 지침에서는 식료품 매장의 거래 데이터에 대해 장바구니 분석을 수행할 예정이다. 하지만 이 기법은 영화 추천부터 연애 사이트, 약품 사이에 위험한 상호 작용을 찾는 것까지 다양한 유형의 문제에도 적용할 수 있다. 장바구니 분석을 하는 동안 아프리오리 알고리즘이 잠재적으로 엄청나게 큰 연관 규칙 집합을 효율적으로 평가할 수 있다는 것을 보게 될 것이다.

3.1. Collecting data


Note


이번 장바구니분석에서는 실제 식료품 매장을 한 달 동안 운영해 수집한 구매 데이터를 활용한다. 이 데이터는 9,835건의 거래 또는 일별 327건의 거래(12시간 영업일 시간당 약 30건 거래)를 포함하며, 이 소매업체가 특별히 크지도 작지도 않다는 것을 시사하고 있다.

일반적인 식료품 가게에서는 엄청나게 다양한 아이템을 판매한다. 그곳에는 다섯 가지 우유 브랜드, 열두 종류의 세탁 세제, 세 가지 커피 브랜드가 있을 수 있다. 중간 규모의 소매업체라는 것을 감안할 때 특정 브랜드의 우유나 세제에만 적용되는 규칙을 발견하는 것에는 별로 관심이 없다고 가정할 것이다. 이것을 염두에 두고 모든 브랜드 이름을 구매 데이터에서 제거할 수 있다. 이것으로 닭고기, 냉동식품, 마가린, 탄산음료 같이 넓은 범주를 사용해 식료품 개수를 좀 더 다루기 쉬운 169종류로 줄인다.

어떤 종류의 아이템이 함께 구매될지 추측할 수 있는가? 와인과 치즈가 평범한 한 쌍이 될 것인가? 빵과 버터는? 차와 꿀은? 이 데이터를 깊이 파헤쳐서 추측을 확인할 수 있는지 살펴보자.

3.2. Exploring and preparing the data

거래 데이터는 이전에 사용했던 형식과 약간 다르게 저장돼 있다. 이전 분석에서는 대부분 행은 예시 인스턴스를 나타내고, 열은 특징을 나타내는 행렬 형태로 데이터를 이용했다. 행렬 형식 구조인 경우 모든 예시는 정확히 동일한 특징 집합을 가져야만 한다.

이와 비교하면 거래 데이터는 좀 더 자유로운 형태다. 평소와 같이 데이터의 열은 하나의 예시(이 경우 거래)를 나타낸다. 하지만 각 레코드는 고정된 개수의 특징 대신 한 개부터 여러 개까지 쉼표로 분리된 임의의 개수의 아이템 목록으로 이뤄져 있다. 본질적으로 특징이 예시마다 다르다.

##                    V1                  V2             V3
## 1        citrus fruit semi-finished bread      margarine
## 2      tropical fruit              yogurt         coffee
## 3          whole milk                                   
## 4           pip fruit              yogurt  cream cheese 
## 5    other vegetables          whole milk condensed milk
## 6          whole milk              butter         yogurt
## 7    abrasive cleaner                                   
## 8          rolls/buns                                   
## 9    other vegetables            UHT-milk     rolls/buns
## 10 liquor (appetizer)                                   
##                          V4
## 1               ready soups
## 2                          
## 3                          
## 4              meat spreads
## 5  long life bakery product
## 6                      rice
## 7                          
## 8                          
## 9              bottled beer
## 10

이것은 식료품 매장에 10 건의 개별 거래를 나타낸다. 첫 번째 거래는 감귤류 과일(citrus fruit), 반제품 빵(semi-finished bread), 마가린(margarine), 즉석 수프(ready soups)라는 네 개의 아이템을 포함한다. 비교하면 세 번째 거래는 전유(whole milk)라는 한 아이템 만을 포함한다.

네 개의 열 형태로 데이터를 사용한다면 문제에 부딪치게 될 것이다. 첫 번째 줄이 정확히 네 개ㅑ의 쉼표로 분리된 값을 갖고 있었기 때문에 R은 생성해야할 네 개의 변수를 선택해야 했다. 하지만 식료품 구매는 네 개 이상의 아이템을 포함할 수 있다. 따라서 네 개 열로 된 설계에서 그런 거래는 행렬의 여러 행으로 나뉘게 될 것이다. 이 문제를 해결하기 위해 가장 많은 아이템을 갖는 거래를 파일 상단에 배치할 수도 있지만, 이것은 더 문제가 되는 다른 이슈를 무시하는 것이다.

R은 이런 방식으로 데이터를 구조화해 거래 아이템뿐 아니라 아이템이 나타나는 순서를 기록하는 특징 집합을 구축해왔다. 학습 알고리즘을 V1, V2, V3, V4 사이의 관계를 찾기 위한 시도로 생각한다면 V1의 우유는 V2에 나타나는 우유와 다르게 취급될 수 있다. 대신 거래를 특정 아이템으로 채우는(또는 채우지 않는) 위치 집합이 아닌 각 특정 아이템을 포함하거나 포함하지 않는 장바구니로 취급하는 데이터 셋이 필요하다.

3.2.1. Data preparation - creating a sparse matrix for transaction data

이 문제에 대한 해결책은 희소 행렬(Sparse matrix)이라고 하는 데이터 구조를 활용하는 것이다. 이전 데이터셋과 같이 희소 행렬의 각 행은 거래를 나타낸다. 하지만 희소 행렬은 어떤 사람의 쇼핑백에 나타날 가능성이 있는 모든 아이템에 대한 열(즉, 특징)을 갖는다. 식료품 매장 데이터에는 169 종류의 아이템이 있기 때문에 희소 행렬은 169개의 열을 갖게 될 것이다.

대부분의 데이터 분석에서 했던 것처럼 희소 행렬을 데이터 프레임에 저장하지 않는 이유는 무엇일까? 기존 데이터 구조는 추가 거래와 아이템이 더해지면 너무 빠르게 커져서 가용 메모리에 맞추기가 어렵기 때문이다. 여기서 사용된 거래 데이터셋은 상대적으로 작지만, 행렬은 거의 170만 개의 셀을 가지며, 대부분은 0이다(여기서 ’희소’행렬이라는 이름이 나왔다. 0이 아닌 값은 아주 적다). 모든 0값을 저장하는 것은 이점이 없기 때문에 희소 행렬은 실제 메모리에 전체 행렬을 저장하지는 않는다. 아이템이 존재하는 셀만 저장한다. 그렇기 때문에 이 구조가 대등한 크기의 행렬 또는 데이터 프레임보다 더 메모리 효율적이다. 거래 데이터에서 희소 행렬 데이터 구조를 만들기 위해 arules패키지가 제공하는 기능을 사용한다.

거래 데이터를 로딩해야 되기 때문에 단순히 앞에서 사용된 read.csv()함수를 사용할 수는 없다. 대신 arules는 read.transaction()함수를 제공하는데, 이 함수는 거래 데이터에 적합한 희소 행렬을 만든다는 점을 제외하면 read.csv()와 비슷하다. sep=“,” 파라미터는 입력 파일에서 아이템이 쉼표로 분리된다는 것을 명시한다.

## transactions as itemMatrix in sparse format with
##  9835 rows (elements/itemsets/transactions) and
##  169 columns (items) and a density of 0.02609146 
## 
## most frequent items:
##       whole milk other vegetables       rolls/buns             soda 
##             2513             1903             1809             1715 
##           yogurt          (Other) 
##             1372            34055 
## 
## element (itemset/transaction) length distribution:
## sizes
##    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15 
## 2159 1643 1299 1005  855  645  545  438  350  246  182  117   78   77   55 
##   16   17   18   19   20   21   22   23   24   26   27   28   29   32 
##   46   29   14   14    9   11    4    6    1    1    1    1    3    1 
## 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   2.000   3.000   4.409   6.000  32.000 
## 
## includes extended item information - examples:
##             labels
## 1 abrasive cleaner
## 2 artif. sweetener
## 3   baby cosmetics

Summary 1

전체 거래 건수는 9835 건이고, 아이템 종류는 169개가 있다. 행렬의 각 셀은 아이템이 해당 거래에서 구매된 것이면 1이고, 아니면 0이다.

밀도(density) 값 0.02609146(2.6%)은 행렬에서 0이 아닌 셀의 비율을 가리킨다. 행렬에서 9,835 x 169 = 1,662,115 위치가 있기 때문에 (같은 아이템이 중복 구매될 수 있다는 사실은 무시하고) 매장의 30일 영업 동안 총 1,662,115 x 0.02609146 = 43,367개의 아이템이 구매된다고 계산할 수 있다. 추가 단계로 평균 거래는 43,367 / 9,835 = 4.409개의 다른 식료품 아이템을 포함하고 있음을 알 수 있다. 물론 출력 아래로 약간 더 보면 거래별 평균 항목 개수는 이미 제공됐다는 것을 알 수 있다.

우유(whole milk)의 거래가 2,513 / 9,835 = 0.255이기 때문에 총 거래의 25.6%에서 나타났다는 것을 알 수 있다. 우유를 비롯한 (흔히 발견되는) 다른 아이템들의 거래 빈도도 같이 나와 있다.

하나의 아이템만을 포함하는 거래가 총 2,159건인 반면, 32개의 아이템을 갖는 거래는 한 건이다. 구매 크기의 1사분위와 중앙값은 각각 두 개와 세 개 아이템으로, 이것이 의미하는 것은 거래의 25%가 두 개 이하의 아이템을 포함하며, 거래는 셋보다 적은 아이템과 셋보다 큰 아이템 사이에서 반으로 나뉘었다는 것이다. 거래당 평균 아이템은 손으로 계산했던 값과 일치한다.

##     items                     
## [1] {citrus fruit,            
##      margarine,               
##      ready soups,             
##      semi-finished bread}     
## [2] {coffee,                  
##      tropical fruit,          
##      yogurt}                  
## [3] {whole milk}              
## [4] {cream cheese,            
##      meat spreads,            
##      pip fruit,               
##      yogurt}                  
## [5] {condensed milk,          
##      long life bakery product,
##      other vegetables,        
##      whole milk}

이 거래는 원래 CSV 파일에서 봤던 것과 일치한다. 특정 아이템(즉, 데이터의 열)을 관찰하기 위해서는 [row, column] 행렬 표기를 사용하는 것도 가능하다. 행렬 표기와 itemFrequency() 함수를 같이 사용하면 아이템을 포함하는 거래의 비율을 볼 수 있다. 예를 들어 식료품 데이터에서 첫 번째 세 개 아이템의 지지도 수준을 볼 수 있게 한다.

## abrasive cleaner artif. sweetener   baby cosmetics 
##     0.0035587189     0.0032536858     0.0006100661

희소 행렬에서 아이템은 열에서 알파벳 순으로 정렬된다는 점을 주목하라. 인스턴트 음식(Instant food products)은 거래의 약 0.08%, 인공 감미료(artificial sweeteners)는 거래의 약 0.3%에서 발견되는 반면, 고온 살균 우유(UHT-milk)는 거래의 약 33%에서 발견되었다.

3.2.2. Visualizing item support - item frequency plots

이런 통계를 시각적으로 보여주려면 itemFrequencyPlot() 함수를 사용한다. 이 함수는 특정 아이템들이 포함된 거래 비율을 표현하는 바 차트를 생성한다. 거래 데이터가 아주 많은 아이템을 포함하기 때문에 읽기 쉬운 차트를 생성하려면 종종 하나의 도표에 나타나는 아이템을 제한할 필요가 있다.

이 아이템을 최소 거래 비율로 나타나게 하려면 itemFrequencyPlot()을 support 파라미터와 함께 사용한다.

도표를 특정 개수의 아이템으로 제약한다면 topN 파라미터를 itemFrequencyPlot()과 함께 사용할 수 있다.

상위 20개 아이템에 대해 지지도 내림차순으로 정렬되었다.

3.2.3. Visualizing transaction data - plotting the sparse matrix

아이템을 관찰하는 것 외에 전체 희소 행렬을 시각화 하는 것도 가능하다. 그렇게 하려면 image()함수를 사용한다. 처음 다섯 거래에 대한 희소 행렬을 보여주기 위한 명령은 다음과 같다.

Summary 2

만들어진 다이어그램은 5행 169열의 행렬을 표현하며, 요청했던 5건의 거래와 169개의 가능한 아이템을 나타낸다. 행렬의 셀은 아이템(열)을 구매한 거래(행)에 대해 검정색으로 채워진다.

이 다이어그램은 작고 읽기가 조금 어려울 수 있지만 첫 번째, 네 번째, 다섯 번째 거래가 각각 네 개의 아이템을 포함하고 있다는 것을 볼 수 있는데, 거래 행이 채워진 네 개의 셀을 갖기 때문이다. 또한 3, 5, 2, 4 행이 (다이어그램의 오른쪽에서) 공통 아이템을 갖는다는 것을 확인할 수 있다. 이 시각화는 데이터 탐색을 위한 유용한 툴이 된다. 하나는 잠재적인 데이터 이슈를 식별하는 데 도움이 된다. 완전히 채워진 열은 모든 거래에서 구매된 아이템을 나타낸다(소매업체의 이름과 ID 번호가 실수로 거래 데이터셋에 포함되면 이런 문제가 발생할 수 있다).

추가적으로 다이어그램의 패턴은 거래와 아이템의 실행 가능한 통찰을 밝히는 데 도움이 되며, 특히 데이터가 흥미로운 방식으로 정렬돼 있을 때 그렇다. 예를 들어 거래가 날짜로 정렬돼 있다면 검정색 점의 패턴은 구매된 아이템의 개수나 타입에 대한 계절적 영향을 보여줄 것이다. 크리스마스나 어린이날 무렵에는 장난감이 좀 더 흔해지고, 할로윈 무렵에는 사탕과 초콜릿류가 인기가 있을 것이다. 이런 종류의 시각화는 범주로 정렬돼 있을 때 특히 강력해진다. 하지만 대부분의 도표는 TV화면의 잡음처럼 아주 랜덤하게 보일 것이다.

이 시각화는 극단적으로 큰 거래 데이터베이스의 경우 셀이 파악하기에 너무 작기 때문에 유용하지 않다는 점을 유념하자. 하지만 sample()함수와 결합해 임의로 샘플링한 거래 집합에 대한 희소 행렬을 볼 수 있다. 100개 거래를 임의로 선택하는 명령은 다음과 같다.

summary 3

일부 열이 상당히 많이 밀집된 것으로 보이는데, 매장에서 아주 인기 있는 아이템을 일부 가리킨다. 하지만 전체적으로 점의 분포가 상당히 랜덤하게 보인다. 눈여겨볼 것이 더 이상 없으므로 분석을 계속해서 진행하겠다.

3.2.4. Wordcolud

3.3. Training a model on the data

데이터 준비가 완료됐으므로 이제 쇼핑 카드 아이템 간에 연관성을 찾는 작업을 할 수 있다. 식료품 데이터를 탐색하고 준비할 때 사용했던 arules 패키지의 아프리오리 알고리즘 구현을 사용할 것이다.


NOTE

- apriori algorithm Threshold
    - supp : (최소) 지지도
    - conf : (최소) 신뢰도
    - maxlen : (최대) rule에 들어가는 아이템의 갯수

연관 규칙 찾기

rules <- apriori(data = data, parameter = list(support = 0.1, confidence = 0.8, minlen = 1))
  • data는 거래 데이터를 갖고 있는 희소 아이템 행렬
  • support는 요구되는 최소 규칙 지지도
  • confidence는 요구되는 최소 규칙 신뢰도
  • minlen은 요구되는 최소 규칙 아이템
  • maxlen은 요구되는 최대 규칙 아이템

연관 규칙 검토

inspect(rules)
  • rules는 aprioiri() 함수에서 얻은 연관 규칙 집합

함수를 실행하는 것은 간단하지만, 합리적인 개수의 연관 규칙을 생성하는 support와 confidence 파라미터를 찾으려면 가끔씩 엄청난 시행착오를 겪을 수 있다. 이 파라미터의 수준을 너무 높게 하면 규칙을 찾지 못하거나 너무 포괄적이어서 유용하지 않은 규칙을 찾게 될 것이다. 한편 임계치가 너무 낮으면 규칙이 너무 많아져서 통제가 힘들거나 더 심각하게는 학습 단계를 진행할 때 너무 오래 실행하거나 메모리가 부족해질 수 있다.

이 경우 디폴트 설정인 support = 0.1과 confidence = 0.8를 사용한다면 결국 규칙이 0개인 집합으로 끝날 것이다.

## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime support minlen
##         0.8    0.1    1 none FALSE            TRUE       5     0.1      1
##  maxlen target   ext
##      10  rules FALSE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 983 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[169 item(s), 9835 transaction(s)] done [0.00s].
## sorting and recoding items ... [8 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].
## set of 0 rules

검색을 조금 넓힐 필요가 있다.


NOTE

이에 대해 생각해보면 결과가 놀랍지는 않다. 디폴트가 support = 0.1이기 때문에 규칙을 생성하려면 아이템이 최소한 0.1 x 9,385 = 983.5개의 거래에 나타나야만 한다. 데이터에서 여덟 개의 아이템 만이 이 빈도로 나타났기 때문에 어떤 규칙도 찾을 수 없었던 것은 당연하다.

최소 지지도 임계치를 설정하는 문제에 접근하는 방법 중 하나는 흥미로운 패턴을 고려하기 전에 필요한 최소 거래 건수에 대해 생각하는 것이다. 예를 들어 아이템이 하루에 두 번 구매된다면(한 달에 약 60회) 흥미로운 패턴이라고 주장할 수 있다. 거기에서 최소 그 정도 많은 거래와 연결되는 규칙만을 찾기 위해 필요한 지지도 수준을 계산할 수 있을 것이다. 9,835회 중 60회는 0.006이기 때문에 지지도를 먼저 설정해보겠다.

최소 신뢰도 설정은 섬세한 균형을 필요로 한다. 신뢰도가 너무 낮으면(보통 배터리와 함께 구매되는 아이템을 나타내는 수십 개의 규칙들과 같이) 엄청난 수의 신뢰할 수 없는 규칙에 압도될 수 있다. 그때는 광고 예산을 어디로 타겟팅할지 어떻게 알겠는가? 한편 신뢰도를 너무 높게 설정하면 (연기 탐지기는 항상 배터리와 함께 구매된다는 사실과 비슷하게) 명백하거나 반드시 예상할 수 있는 규칙으로 제한될 것이다. 이 경우 연기 탐지기를 배터리 근처로 옮긴다고 해서 추가 수익이 생길 가능성은 거의 없다. 이미 두 아이템은 거의 늘 함께 구매됐기 때문이다.


NOTE

적절한 최소 신뢰도 수준은 분석 목표에 많이 좌우된다. 보수적인 값으로 시작해서 실행 가능한 지능을 찾지 못했다면 검색을 확대하기 위해 신뢰도를 줄일 수 있다.

신뢰도 임계치를 0.25로 시작해보자. 이것은 규칙이 결과에 포함되려면 최소 25%는 정확해야 한다는 것을 의미한다. 결과적으로 신뢰하지 못하는 규칙들이 제거되면서 타겟팅된 홍보 활동을 통해 고객의 행동을 바꿀 수 있는 약간의 여지가 생길 것이다.

이제 규칙을 생성할 준비가 됐다. 최소 support와 confidence 파라미터 이외에 둘 이하의 아이템을 갖는 규칙을 없애기 위해 minlen = 2를 설정하는 것이 좋다. 이 파라미터는 예를 들어 {} \(\rightarrow whole milk\)와 같이 아이템이 자주 구매되기 때문에 흥미롭지 않은 규칙이 생성되는 것을 방지한다. 이 규칙은 우유가 25% 이상의 거래에서 구매됐기 때문에 최소 지지도와 신뢰도를 만족하지만, 매우 실행 가능한 통찰은 아니다.

아프리오리 알고리즘을 이용해 연관 규칙의 집합을 찾는 전체 명령은 다음과 같다.

## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime support minlen
##        0.25    0.1    1 none FALSE            TRUE       5   0.006      2
##  maxlen target   ext
##      10  rules FALSE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 59 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[169 item(s), 9835 transaction(s)] done [0.00s].
## sorting and recoding items ... [109 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 done [0.00s].
## writing ... [463 rule(s)] done [0.00s].
## creating S4 object  ... done [0.00s].
## set of 463 rules

Summary 4

grocery_rules 객체에는 463개의 연관 규칙이 들어있다. 그중 어떤 것이 유용한지 알아내기 위해 더 깊게 파헤쳐 볼 것이다.

3.4. Evaluating model performance

## set of 463 rules
## 
## rule length distribution (lhs + rhs):sizes
##   2   3   4 
## 150 297  16 
## 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   2.000   2.000   3.000   2.711   3.000   4.000 
## 
## summary of quality measures:
##     support           confidence          lift            count      
##  Min.   :0.006101   Min.   :0.2500   Min.   :0.9932   Min.   : 60.0  
##  1st Qu.:0.007117   1st Qu.:0.2971   1st Qu.:1.6229   1st Qu.: 70.0  
##  Median :0.008744   Median :0.3554   Median :1.9332   Median : 86.0  
##  Mean   :0.011539   Mean   :0.3786   Mean   :2.0351   Mean   :113.5  
##  3rd Qu.:0.012303   3rd Qu.:0.4495   3rd Qu.:2.3565   3rd Qu.:121.0  
##  Max.   :0.074835   Max.   :0.6600   Max.   :3.9565   Max.   :736.0  
## 
## mining info:
##       data ntransactions support confidence
##  groceries          9835   0.006       0.25

Summary 5

  • 150개의 규칙은 단지 두 개의 아이템을 갖는 반면, 297개의 규칙은 세 개를 갖고, 16개의 규칙은 네 개를 갖는다.

  • 규칙 품질 척도인 지지도(support), 신뢰도(confidence), 향상도(lift)의 요약통계
    • 지지도와 신뢰도 측정치는 규칙의 선택 기준으로 이미 사용했기 때문에 놀라울 게 없다.
    • 대부분 또는 모든 규칙이 최소 임계치 바로 근처에서 지지도와 신뢰도를 갖는다면 기준을 너무 높게 설정했다는 것을 의미하기 때문에 불안할 수 있다.
    • 이 경우에는 지지도와 신뢰도가 매우 높은 규칙이 많기 때문에 해당되지 않는다.
  • 세 번째 열은 지금까지 고려하지 않았던 척도다. 어떤 규칙의 향상도는 어떤 아이템 또는 아이템 집합 X가 구매됐다는 것을 안다면 다른 아이템 또는 아이템 집합 Y가 어떤 확률로 구매될 것인가를 Y의 일반적인 구매 확률과 비교해 측정한다. 향상도는 다음 방정식으로 정의된다.

\[lift(X \rightarrow Y) = \frac{confidence(X \rightarrow Y)}{support(Y)}\]


NOTE

아이템 순서가 중요한 신뢰도와 달리 $lift(X \rightarrow Y)$는 $lift(Y \rightarrow X)$와 동일하다.

예를 들어 대부분의 사람들이 우유와 빵을 구매하는 식료품 매장에 있다고 가정하자. 우유와 빵을 모두 포함한 거래가 우연히 많이 발견될 것으로 예상한다. 하지만 \(lift(milk \rightarrow bread)\)가 1보다 크면 우연이라고 예상했던 것보다 더 자주 두 아이템이 함께 발견된다는 것을 의미한다. 그러므로 큰 향상도 값은 규칙이 중요하며, 아이템 간에 실제 연관성을 반영하는 강한 지표다.

summary() 출력의 마지막 절에서 규칙이 어떻게 선택됐는지를 말해주는 마이닝 정보를 받는다. 여기서 9,835건의 거래가 포함된 groceries 데이터가 최소 지지도 0.0006와 최소 신뢰도 0.25를 갖는 규칙을 만드는 데 사용됐다는 것을 확인할 수 있다.

inspect() 함수를 사용해서 특정 규칙을 관찰해볼 수 있다. 예를 들어 grocery_rules 객체에 있는 처음 세 개의 규칙은 다음과 같이 보일 수 있다.

##     lhs             rhs               support     confidence lift    
## [1] {pot plants} => {whole milk}      0.006914082 0.4000000  1.565460
## [2] {pasta}      => {whole milk}      0.006100661 0.4054054  1.586614
## [3] {herbs}      => {root vegetables} 0.007015760 0.4312500  3.956477
##     count
## [1] 68   
## [2] 60   
## [3] 69

Summary 6

첫 번째 규칙은 쉬운 말로 “고객이 화분에 심어진 식물(poted plants)을 산다면 우유(whole milk)도 살 것이다.”로 읽을 수 있다. 지지도가 약 0.007이고 신뢰도가 0.400 이므로 규칙이 거래의 0.7%를 커버하며, 화분에 심어진 식물이 포함된 구매의 40%에서 규칙이 옳다는 것을 알 수 있다. 향상도 값은 우유를 산 평균 고객에 비해 고객이 화분에 심어진 식물을 샀다면 우유를 살 확률이 얼마나 더 높은지를 말해준다. 고객의 약 25.6%가 우유를 샀고(support) 화분에 심어진 식물을 산 고객의 40%가 우유를 샀다는 것(confidence)을 알기 때문에 향상도는 0.40 / 0.256 = 1.56으로 계산할 수 있으며, 보이는 값과 일치한다.

신뢰도와 향상도가 높다는 사실에도 불구하고, {pot plants}-> {whole milk}가 아주 유용한 규칙 같아 보이는가? 아마 아닐 것이다. 우유를 화분에 심어진 식물과 같이 살 가능성이 있는지에 대한 논리적인 이유가 없어 보이기 때문이다. 하지만 데이터는 그렇지 않다고 말한다. 이 사실을 어떻게 이해할 수 있을까?

일반적인 방법은 연관 규칙을 받아 다음 세 가지 범주로 규칙을 나누는 것이다.

- 실행 가능한 (Actionable)
- 사소한 (Trival)
- 설명하기 어려운 (Inexplicable)

분명히 장바구니 분석의 목표는 명확하고 유용한 통찰을 제공하는 실행 가능한 규칙(actionable rules)을 발견하는 것이다. 일부 규칙은 명확하고 다른 규칙은 유용하다. 이 두 요소의 조합을 찾는 것은 흔하지 않다.

소위 사소한 규칙(trival rules)은 너무 명확해서 언급할 가치가 없는 규칙을 말한다(명확하지만 유용하지 않다). 교차 홍보 아이템에 대한 새로운 기회를 찾기 위해 많은 금액의 돈을 받은 마케팅 컨설턴트라고 가정해보자. {disapers} -> {formula} 결과를 보고 한다면 다시는 다른 컨설팅 업무에 초대받지 못할 것이다.

아이템 간의 연관성이 불명확해서 정보 사용법을 알아내는 것이 불가능하거나 거의 불가능하다면 규칙이 설명하기 어려운(Inexplicable) 것이다. 이 규칙은 단순히 데이터에 있는 랜덤 패턴일 수도 있다. 예를 들어 {pickles} -> {chocolate ice cream}을 서술하는 규칙은 임신한 아내가 정기적으로 색다르게 혼합된 음식을 먹고 싶어하는 고객 때문일지도 모른다.

가장 좋은 규칙은 숨겨진 보석이다(발견되지 않은 통찰은 일단 발견되면 분명한 것 같은 패턴이 된다). 충분한 시간이 있다면 보석을 찾기 위해 규칙을 하나도 빠짐없이 평가할 수 있다. 하지만 장바구니 분석을 실행하는 사람은 규칙이 실행 가능한지, 사소한지, 설명하기 어려운지에 대한 최고의 심사위원이 아니다. 다음 절에서는 가장 흥미로운 결과가 상단에 표시되도록 학습된 규칙을 정렬하고 공유하는 방법으로 작업 효율을 향상시킨다.

3.5. Improving model performance

전문가는 유용한 규칙을 아주 빨리 식별할 수 있지만, 수백 개 또는 수천 개의 규칙을 평가하게 요청하는 것은 전문가의 시간이 비효율적으로 사용되게 만든다. 그러므로 여러 기준에 따라 규칙을 정렬하고 이를 R에서 얻어서 마케팅 팀과 공유하고 좀 더 깊이 있게 검토할 수 있는 형태로 변환할 수 있다면 유용할 것이다. 이런 방식으로 결과를 더욱 활용 가능하게 만듦으로써 규칙의 성능을 개선할 수 있다.

3.5.1. Sorting the set of association rules

장바구니 분석의 목적에 따라 가장 유용한 규칙은 가장 높은 support, confidence, lift를 갖는 규칙이 될 수 있다. arules 패키지는 sort() 함수를 포함하는데, 이 함수는 품질 측정치의 최고 또는 최저 값을 갖는 규칙이 먼저 오도록 규칙 목록을 재정렬하는 데 사용된다.

grocery_rules 객체를 재정렬하기 위해 by 파라미터에 “support”, “confidence”, “lift” 값을 지정해서 sort()를 적용할 수 있다. sort 함수를 벡터 연산자와 결합해 특정 개수의 흥미로운 규칙을 얻을 수 있다. 예를 들어 향상도 통계에 따른 최고의 다섯 개 규칙은 다음 명령으로 검토할 수 있다.

##     lhs                   rhs                      support confidence     lift count
## [1] {herbs}            => {root vegetables}    0.007015760  0.4312500 3.956477    69
## [2] {berries}          => {whipped/sour cream} 0.009049314  0.2721713 3.796886    89
## [3] {other vegetables,                                                              
##      tropical fruit,                                                                
##      whole milk}       => {root vegetables}    0.007015760  0.4107143 3.768074    69
## [4] {beef,                                                                          
##      other vegetables} => {root vegetables}    0.007930859  0.4020619 3.688692    78
## [5] {other vegetables,                                                              
##      tropical fruit}   => {pip fruit}          0.009456024  0.2634561 3.482649    93

Summary 7

이 규칙들은 이전에 봤던 것보다 좀 더 흥미로워 보인다. 약 3.96의 lift를 갖는 첫 번째 규칙은 허브(herbs)를 산 사람들이 뿌리 채소(root vegetables)를 살 가능성이 (아마도 어떤 종류의 스튜를 만들기 위해) 뿌리 채소를 산 일반 고객보다 거의 네 배 정도 높다는 것을 의미한다. 규칙2도 흥미롭다. 휘핑 크림(whipped/sour cream)이 다른 카트에 비해 베리(berries)가 있는 쇼핑 카트에서 발견될 가능성이 세 배 이상 높으며, 아마도 디저트 쌍을 이루는 것을 시사한다.

3.5.1. Taking subsets of association rules

앞의 규칙이 주어진다면 마케팅 팀은 이제 제철인 베리를 홍보하기 위해 광고를 제작할 수 있다는 것에 신이 나 있다고 가정하자. 하지만 캠페인을 마무리하기 전에 마케팅 팀은 베리가 다른 아이템과 같이 자주 구매되는지 조사를 요청한다. 이 질문에 답을 하기 위해 어떤 형태로든 베리를 포함하는 모든 규칙을 찾을 필요가 있다.

subset()함수는 거래, 아이템, 규칙의 부분집합을 찾는 방법을 제공한다. 이 함수를 berries가 나타나는 규칙을 찾는 데 이용하려면 다음 명령을 사용하면 된다. berry_rules라는 이름의 새로운 객체에 규칙을 저장할 것이다.

##     lhs          rhs                  support     confidence lift    
## [1] {berries} => {whipped/sour cream} 0.009049314 0.2721713  3.796886
## [2] {berries} => {yogurt}             0.010574479 0.3180428  2.279848
## [3] {berries} => {other vegetables}   0.010269446 0.3088685  1.596280
## [4] {berries} => {whole milk}         0.011794611 0.3547401  1.388328
##     count
## [1]  89  
## [2] 104  
## [3] 101  
## [4] 116

베리가 포함된 규칙이 네 개가 있으며, 그중 둘은 ’실행 가능한(actionable)’으로 불리기에 충분히 흥미로운 것으로 보인다. 베리는 휘핑 크림(whipped/sour cream) 외에도 요거트(yogurt)와도 자주 같이 구매된다(디저트 뿐만 아니라 아침이나 점심으로 잘 나오는 쌍이다).

부분집합을 선택하기 위한 조건

subset() 함수는 매우 강력하다. 부분집합을 선택하기 위한 조건은 몇 가지 키워드와 연산으로 정의될 수 있다.

- 앞에서 설명했던 키워드 items는 규칙의 어디서나 나타나는 아이템과 매칭한다. 좌측이나 우측에만 매칭되는 부분집합으로 제약하려면 대신 lhs와 rhs를 사용하라.
- 연산자 %in%는 아이템 중 최소 하나가 정의한 목록에서 발견돼야만 한다. 베리나 요거트 중 하나에 일치되는 어떤 규칙을 원한다면 items %in% c("berries", "yogurt")로 적을 수 있다.
- 부분 매칭(%pin%)과 완전 매칭(%ain%)을 위한 추가 연산자를 사용할 수 있다. 부분 매칭으로 한 번 검색해서 귤 종류의 과일과 열대 과일을 모두 찾을 수 있다(items %pin% "fruit"). 완전 매칭은 나열된 모든 아이템이 존재해야 한다. 예를 들어 items%ain%c("berries", "yogurt")는 berries와 yogurt를 모두 갖는 규칙만을 찾는다.
- 부분집합은 support, confidence, lift로 제약될 수 있다. 예를 들어 confidence > 0.50은 50%보다 큰 신뢰도를 갖는 규칙으로 제한한다.
- 매칭 조건은 and(&), or(|), not(!)과 같은 표준 R의 논리 연산자와 같이 결합될 수 있다.

이런 옵션을 이용해 규칙의 선택이 원하는 대로 세부적이거나 일반적이게 제약할 수 있다.

3.5.2. Saving association rules to a file or data frame

장바구니 분석 결과를 저장하기 위해 write() 함수를 이용해 규칙을 CSV 파일로 저장할 수 있다.

가끔식 규칙을 R데이터 프레임으로 변환하는 것도 편리할 수 있다. 다음과 같이 as()함수를 이용하면 쉽게 가능하다.

support, confidence, lift에 대한 수치 벡터를 생성했다.

## 'data.frame':    463 obs. of  5 variables:
##  $ rules     : Factor w/ 463 levels "{baking powder} => {other vegetables}",..: 340 302 207 206 208 341 402 21 139 140 ...
##  $ support   : num  0.00691 0.0061 0.00702 0.00773 0.00773 ...
##  $ confidence: num  0.4 0.405 0.431 0.475 0.475 ...
##  $ lift      : num  1.57 1.59 3.96 2.45 1.86 ...
##  $ count     : num  68 60 69 76 76 69 70 67 63 88 ...
##                                rules     support confidence     lift count
## 1       {pot plants} => {whole milk} 0.006914082  0.4000000 1.565460    68
## 2            {pasta} => {whole milk} 0.006100661  0.4054054 1.586614    60
## 3       {herbs} => {root vegetables} 0.007015760  0.4312500 3.956477    69
## 4      {herbs} => {other vegetables} 0.007727504  0.4750000 2.454874    76
## 5            {herbs} => {whole milk} 0.007727504  0.4750000 1.858983    76
## 6 {processed cheese} => {whole milk} 0.007015760  0.4233129 1.656698    69

규칙에 대한 추가 처리를 수행하길 원하거나 다른 데이터베이스에 규칙을 내보낼 필요가 있다면 데이터 프레임으로 변환을 선택할 수 있다.

4. Summary

연관 규칙은 큰 소매 업체의 엄청나게 큰 거래 데이터베이스에서 유용한 통찰을 발견하기 위해 자주 사용된다(특징 내에서 패턴을 찾는 방법). 자율 학습 절차로서 연관 규칙 학습자는 찾으려는 패턴에 대한 사전 지식 없이 큰 데이터베이스에서 지식을 추출할 수 있다. 주목할 점은 풍부한 정보를 더 작고 다루기 쉬운 일련의 결과들로 줄이기 위한 약간의 노력이 필요하다는 점이다. 아프리오리 알고리즘은 흥미도의 최소 임계치를 설정하고 이 기준을 충족하는 연관성을 보고함으로써 그렇게 한다.

적당한 규모의 슈퍼마켓의 한 달간 거래에 대해 장바구니 분석을 수해하는 동안 아프리오리 알고리즘을 작동시켰다. 이 작은 예에서조차 수많은 연관성이 식별됐다. 이들 중 미래의 마케팅 캠페인에 유용할지도 모르는 몇 가지 패턴에 주목했다. 적용했던 것과 동일한 방식이 좀 더 큰 소매업체의 몇 배 크기 데이터베이스에 사용된다.