Rを通じて統計学を学ぶ備忘録ブログ

SPSSからRに移行したい私のような人向けのR解説ブログ兼学習用備忘録。

大学の時にもっと勉強しておけばよかったマーケティング・リサーチ〜その11〜

アソシエーション分析(Association analysis)

今回は、アソシエーション分析について見ていきます。「おむつを買った人はビールを買う傾向がある(という伝説)」という話を、一度は聞いたことがあると思います。これは、マーケットバスケット分析の事例で、アソシエーション分析のひとつです。アソシエーション分析は、このように何と何が関連しているかを探る手法で、それを買い物カゴをもとに考えると、マーケットバスケット分析になります。また、ECサイトでよく見るレコメンドシステムは、アソシエーション分析をもとにしています。 アソシエーション分析は、POSシステムのアウトプットであるトランザクションデータの出現とともに一躍有名になりました。トランザクションデータとは、いつ、誰に、何を、何個、金額などの情報を時系列に記録したデータのことをいいます。 また、「営業効率化」の「ECサイトのレコメンドシステム」「ソフトウェア開発の障害予防」などにもアソシエーション分析が使われています。営業効率化では、売上をあげた組み合わせを明らかにしたり、ECサイトでは、「この商品を買った人は・・・」みたい形でレコメンドシステムの原理になっていますし、ソフト開発の予防では、障害が発生しやすい工程の組み合わせを明らかにするために使われています。

相関ルール

さて、アソシエーション分析が「何かと何かの組み合わせ」を探る手法であることがわかりました。また、物の組み合わせに関連がある場合に、頻出する組み合わせ規則のことを「相関ルール」と呼びます。では、何を基準に「関連する」、つまり相関ルール(アソシエーションルール)があると言えばよいのでしょうか。ここでは、共起性に基づくAprioriという手法における相関ルールを表す指標を説明するために、「Xを買うと商品Yも買う」を{X}⇒{Y}と表現します。また、相関ルールの「⇒」の左辺を条件部、右辺を結論部と呼びます。下記では個数を示す場合、σ()と表記しています。 

Support

まず、Supportという指標についてです。これは観測されたデータ全ての中で、「Xを買う時に、Yも一緒に買い物カゴに入れる」、つまり{X}⇒{Y}というルールが出現する割合を表現する指標です。従って、Supportが大きくなるほど、{X}⇒{Y}というルールが頻繁に起こっているということになります。 supp

Confidence

次にConfidenceという指標ですが、信頼度、確信度とも呼ばれています。条件部(X)の項目が出現する割合の中で、(X)と(Y)が同時に出現する割合のことです。Confidenceが大きいと、「Xを買う時に、Yも一緒に買い物カゴに入れる」割合が高いと言えます。 全部で15あり、Xを購入した人が10人、Yを購入した人が7人、XまたはYを購入した人が3人の場合、Conf=3/10=0.3ですが、XまたはYを購入した人が6人だった場合、Conf=6/10=0.6となり、「XのもとYとの関連が強い」と言えます。 conf

Lift

最後にLiftという指標ですが、「Xを買ってYも買う{X}⇒{Y}」ときに、通常にYが買われるときの何倍なのか、という感じです。例えば。全部で15あり、Xを購入した人が10人、Yを購入した人が7人、XまたはYを購入した人が3人の場合、Conf=3/10=0.3なので、Lift=0.3/{7/15}=0.6となります。Liftは「1」を越えると良い指標と言われています。 lift

どう評価すればいいのか・・・

以上のように、相関ルールは複数あります。そのため、3つの指標をトレードオフしながら、評価していきます。 daum_equation_1484543070377 Supportが低いと、その相関ルールが現れる確率が低いので、狭いような(希少な)相関ルールで評価していきたいなら Supportは小さめ、Confidence/Liftは高め、というルールを選んだりします。 浅い(頻出するかも)相関ルールで評価したいSupportが大きく、Confidence/Liftがまぁまぁなルールを選というような判断の仕方でいいかもしれません。または、以下の表を参考になれば幸いです。 名称未設定-1-01

アソシエーション分析の事例

パッケージarulesを使ってアソシエーション分析を行っていきます。arulesはAprioriアルゴリズムに基づく相関ルールを検出する関数を含むパッケージです。組み込みののデータセットにはGroceriesやIncomeなどがあります。Groceriesは、食料品屋の30日間のPOSデータ(169アイテム、9835トランザクション)です。 また、Incomeは、 6876トランザクション、50アイテムのデータセットで、サンフランシスコベイエリアのショッピングモールの9409人が回答したアンケートから、欠損値処理を行ったものです。 収入(income)、性別(sex)、結婚歴(marital status)、年齢(age)、学歴(education)、職業(occupation)、ベイエリアでの居住歴(years in Bay Area)、夫婦収入(dual income)、家族の数(number in household)、子供の数(number of children)、居住家屋状況(householder status) 、家の形態(type of home)、人種の分類(ethnic classification)、自宅での使用言語(language in home)で構成されています。

> install.packages("arules")
> library(arules)
> data(Groceries)

transactions in sparse format with
 9835 transactions (rows) and
 169 items (columns)
 
> summary(Groceries)

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           yogurt          (Other) 
            2513             1903             1809             1715             1372            34055 

element (itemset/transaction) length distribution:
sizes
   1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   26   27   28 
2159 1643 1299 1005  855  645  545  438  350  246  182  117   78   77   55   46   29   14   14    9   11    4    6    1    1    1    1 
  29   32 
   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  level2           level1
1 frankfurter sausage meat and sausage
2     sausage sausage meat and sausage
3  liver loaf sausage meat and sausage

summary関数で中を見ると、169アイテム、9835トランザクションあることがわかりますし、whole milk, other vegetables, rolls/bunsが頻出アイテムであることがわかります。また以下のようにすれば、アイテムの内容が確認できます。

> itemFrequencyPlot(Groceries[,1:20], horiz = TRUE)
Rplot06

それではapriori()関数を使って、相関ルールを抽出していきます。指標のパラメタはsupport=0.8, confidence=1というようにデフォルトできめられています。

##デフォルトのパラメタはsupport=0.8, confidence=1
> Groceries.apriori <- apriori(Groceries, parameter = list(support=0.005,confidence=0.01))

Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen maxlen target   ext
       0.01    0.1    1 none FALSE            TRUE       5   0.005      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: 49 

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

##"beef" & support > 0.2 & size(items)
##こののように指定すれば、Supportが0.2以上かつアイテム数が2以上を抽出できます。

> BeefRules <- subset(Groceries.apriori, subset= rhs %in% "beef")
> inspect(head(sort(BeefRules, by = "lift"), n = 10))

     lhs                                   rhs    support     confidence lift    
[1]  {root vegetables,other vegetables} => {beef} 0.007930859 0.1673820  3.190313
[2]  {root vegetables,whole milk}       => {beef} 0.008032537 0.1642412  3.130449
[3]  {root vegetables}                  => {beef} 0.017386884 0.1595149  3.040367
[4]  {other vegetables,rolls/buns}      => {beef} 0.005795628 0.1360382  2.592898
[5]  {pork}                             => {beef} 0.007625826 0.1322751  2.521174
[6]  {other vegetables,whole milk}      => {beef} 0.009252669 0.1236413  2.356613
[7]  {whole milk,rolls/buns}            => {beef} 0.006812405 0.1202873  2.292684
[8]  {other vegetables,yogurt}          => {beef} 0.005185562 0.1194379  2.276496
[9]  {whole milk,yogurt}                => {beef} 0.006100661 0.1088929  2.075508
[10] {margarine}                        => {beef} 0.006202339 0.1059028  2.018515

このように【writing … [2138 rule(s)] done [0.00s].】とアウトプットされ、2138のルールが検出されていることがわかります。結論部(rhs)のbeefの集合をsubset()関数で作成し、liftで高い順にソートしたところ、 {root vegetables,other vegetables} => {beef}となっていることから、「root vegetables,other vegetablesを買う人はbeefも買いやすい」ということがわかります。 また、見つけ出した相関ルールは、クラスター分析を実行することで、クラスターの特徴をみることもできます。

beef.data <- dissimilarity(BeefRules)
plot(hclust(beef.data, “ward”), hang = -1)
Rplot

Beef.cluster <- hclust(beef.data, “ward”)$order[21:26] inspect(BeefRules[Beef.cluster])

lhs                                   rhs    support     confidence lift    

[1] {whole milk} => {beef} 0.021250635 0.08316753 1.585180 [2] {root vegetables,whole milk} => {beef} 0.008032537 0.16424116 3.130449 [3] {root vegetables} => {beef} 0.017386884 0.15951493 3.040367 [4] {root vegetables,other vegetables} => {beef} 0.007930859 0.16738197 3.190313 [5] {other vegetables} => {beef} 0.019725470 0.10194430 1.943066 [6] {other vegetables,whole milk} => {beef} 0.009252669 0.12364130 2.356613

樹形図で確認してみると、4つのクラスターに分解することができ、order[21:26]で呼び出すと、「root vegetables,other vegetablesとbeef」に関するルールであることがわかる。

時系列アソシエーション分析

ここまでは、アソシエーション分析を行ってきましたが、ここからは「時系列アソシエーション分析」を見ていきます。時系列アソシエーション分析は、時系列情報を持ったデータに対して、相関ルールを抽出する分析手法です。 つまり、アソシエーション分析では、同時発生の相関ルールを抽出することになりますが、時系列アソシエーション分析では「発生順序」を考慮し、Xを購入した顧客が、次にYを購入するかという時系列的な検討を可能にします。 従って、オンライン、オフライン問わずユーザーの購買行動、ウェブページの遷移、USJなどのアトラクションの乗り順番などにおいて、有効です。

SPADE(Sequential PAttern Discovery using Equivalence classes)

SPADEは、モハメド・ザキ先生が以下の論文で提案しているGap数という概念を組み合わせアルゴリズムが作られているようです。 詳しくは以下をご確認ください。

アソシエーション分析の事例

RのarulesSequencesパッケージを使って時系列アソシエーション分析を実行していきます。使用するデータはdelicios-sequecesのデータセットです。 このデータセットは、ソーシャルブックマークサイトdelicious.comで、ユーザがWebサイトをブックマークしたときに与えたタグを保持しているデータセットです。各トランザクションが「ユーザがWebサイトをブックマークしてタグ付けを行う」という行動を表現しており、行変数は左からユーザID、イベントID、タグの数、タグリストとなっています。

> install.packages("arulesSequences")
> library(arulesSequences)
> delicious <- read_baskets(con  = "delicious.sequence.txt",info = c("sequenceID","eventID","SIZE"))
> summary(delicious)

transactions as itemMatrix in sparse format with
 7559 rows (elements/itemsets/transactions) and
 7496 columns (items) and a density of 0.0004482878 

most frequent items:
     design       tools        blog   webdesign inspiration     (Other) 
        469         301         233         229         220       23949 

element (itemset/transaction) length distribution:
sizes
   1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20 
2283 1432 1172  825  560  343  230  273  171  100   60   34   25   14    5    5    5    7    8    7 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00    1.00    3.00    3.36    4.00   20.00 

includes extended item information - examples:
  labels
1  _Misc
2 _watch
3      -

includes extended transaction information - examples:
  sequenceID eventID SIZE
1          1       1    2
2          2       1    5
3          3       1    3

> head(transactionInfo(delicious))

  sequenceID eventID SIZE
1          1       1    2
2          2       1    5
3          3       1    3
4          4       1    1
5          5       1    1
6          6       1    2

では、時系列パターンを抽出してみます。今回の相関ルールはsupportが0.001以上のもを対象にします。頻出するアイテムは、design、webdesign、inspirationが多いことがわかります。また、データフレーム型に直すと確認しやすくなります。

> delicious.sequential <- cspade(delicious, parameter = list(support = 0.001), control = list(verbose = TRUE))

parameter specification:
support : 0.001
maxsize :    10
maxlen  :    10

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

preprocessing ... 1 partition(s), 0.33 MB [0.041s]
mining transactions ... 0.06 MB [0.2s]
reading sequences ... [0.29s]

total elapsed time: 0.528s

> summary(delicious.sequential)

set of 3096 sequences with

most frequent items:
     design   webdesign inspiration       tools    software     (Other) 
        739         378         330         319         177        4277 

most frequent elements:
            {design}              {tools}        {inspiration}          {webdesign} {design,inspiration} 
                 302                  149                  139                  136                   81 
             (Other) 
                3439 

element (sequence) size distribution:
sizes
   1    2    3    4    5 
1909  926  208   50    3 

sequence length distribution:
lengths
   1    2    3    4    5    6 
 632 1395  771  239   54    5 

summary of quality measures:
    support        
 Min.   :0.001063  
 1st Qu.:0.001063  
 Median :0.001275  
 Mean   :0.002147  
 3rd Qu.:0.001913  
 Max.   :0.075027  

includes transaction ID lists: FALSE 

mining info:
      data ntransactions nsequences support
 delicious          7559       4705   0.001
 
> head(as(delicious.sequential, "data.frame"), 20)

            sequence     support
1           <{.net}> 0.004038257
2            <{2.0}> 0.001912859
3           <{2009}> 0.002550478
4             <{3d}> 0.004675877
5             <{3D}> 0.001062699
6           <{9/11}> 0.002550478
7       <{academic}> 0.001487779
8  <{accessibility}> 0.001700319
9        <{actions}> 0.002550478
10  <{actionscript}> 0.003400638
11      <{activism}> 0.003400638
12         <{adobe}> 0.001912859
13   <{advertising}> 0.004250797
14        <{advice}> 0.001912859
15        <{agency}> 0.003825717
16    <{aggregator}> 0.001700319
17         <{agile}> 0.001700319
18   <{agriculture}> 0.001275239
19          <{ajax}> 0.005951116
20       <{america}> 0.001062699

> tail(as(delicious.sequential, "data.frame"), 20)

                                  sequence     support
3077 <{design},{design,inspiration},{art}> 0.001062699
3078      <{design,inspiration,art},{art}> 0.001062699
3079             <{design,graphics},{art}> 0.001062699
3080             <{design},{design},{art}> 0.001700319
3081                 <{design,blog},{art}> 0.001062699
3082                <{design},{art},{art}> 0.001487779
3083                  <{design,art},{art}> 0.001700319
3084                <{art},{design},{art}> 0.001700319
3085         <{design,art},{design},{art}> 0.001275239
3086         <{design},{design,art},{art}> 0.001062699
3087            <{art},{design,art},{art}> 0.001062699
3088     <{design,art},{design,art},{art}> 0.001062699
3089                    <{art,blog},{art}> 0.001062699
3090                   <{art},{art},{art}> 0.002125399
3091       <{inspiration,art},{art},{art}> 0.001062699
3092            <{design,art},{art},{art}> 0.001275239
3093          <{art},{design},{art},{art}> 0.001062699
3094             <{art},{art},{art},{art}> 0.001062699
3095                 <{applications,apps}> 0.001487779
3096                   <{design},{agency}> 0.001275239

例えば、drsignが含まれている時系列パターンを抽出する場合は以下のように指定します。

> delicious.sequential.df <- as(delicious.sequential[delicious.sequential %ein% c("design")], "data.frame")
> head(delicious.sequential.df)

                          sequence     support
142                     <{design}> 0.075026567
650         <{design},{wordpress}> 0.001275239
651           <{design,wordpress}> 0.002550478
672 <{design,webdesign,wordpress}> 0.001062699
699             <{design,website}> 0.001062699
703            <{design},{webdev}> 0.001275239

次は、今回の相関ルールはconfidenceが0.01以上のものの時系列パターンを抽出し、 ruleInduction関数によりLiftが2以上のルールを抽出してみます。

> delicious.sequential <- cspade(delicious, parameter = list(support = 0.005), control = list(verbose = TRUE))

parameter specification:
support : 0.005
maxsize :    10
maxlen  :    10

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

preprocessing ... 1 partition(s), 0.29 MB [0.062s]
mining transactions ... 0 MB [0.037s]
reading sequences ... [0.041s]

total elapsed time: 0.14s

> rules <- ruleInduction(delicious.sequential, confidence=0.01)
> as(rules, "data.frame")

                                rule     support confidence     lift
1        <{design}> => <{webdesign}> 0.005100956 0.06798867 1.827924
2     <{webdesign}> => <{webdesign}> 0.006376196 0.17142857 4.608980
3             <{tools}> => <{tools}> 0.007651435 0.15254237 3.041152
4      <{design}> => <{inspiration}> 0.005526036 0.07365439 2.050556
5 <{inspiration}> => <{inspiration}> 0.006163656 0.17159763 4.777319
6           <{design}> => <{design}> 0.012964931 0.17280453 2.303245
7      <{inspiration}> => <{design}> 0.005313496 0.14792899 1.971688
8               <{blog}> => <{blog}> 0.005526036 0.14285714 3.693093

> rule.data.frame <- as(rules, "data.frame")
> rule.data.frame[rule.data.frame["lift"] >= 2.0,]
                                rule     support confidence     lift
2     <{webdesign}> => <{webdesign}> 0.006376196 0.17142857 4.608980
3             <{tools}> => <{tools}> 0.007651435 0.15254237 3.041152
4      <{design}> => <{inspiration}> 0.005526036 0.07365439 2.050556
5 <{inspiration}> => <{inspiration}> 0.006163656 0.17159763 4.777319
6           <{design}> => <{design}> 0.012964931 0.17280453 2.303245
8               <{blog}> => <{blog}> 0.005526036 0.14285714 3.693093

delicious.comのソーシャルブックマークのデータの場合、{webdesign} => {webdesign}、{design} => {inspiration}などは、時系列パターンがありそうです。