琥珀色呑んだくれ備忘録

メモとか備忘録とか

(修正あり)arulesの結果をdata.frameで探索する

R標準のデータフレーム+dplyr等で、探索的にルール抽出⇔眺めるのにパッケージを作った。本家のarulesだとちょっとやりにくいなあと思っている人むけ。

使いかた

arules::inspect() の代わりに inspectDF() するだけ。

arules::DATAFRAME() でデータフレームとして出力できるとのこと。

自作する前によく探すの、大事。

require(dplyr)
require(arules)
require(inspectDF)

data(Groceries)
params <- list(confidence=0.001, support=0.001, maxlen=7, minlen=2)
glo.apriori <- apriori(Groceries, parameter = params, control = list(verbose=FALSE))
glo.inspectDF  <- inspectDF(glo.apriori)

glo.inspectDF %>% str
#> 'data.frame':    40943 obs. of  8 variables:
#>  $ rule      : chr  "Rule 1" "Rule 2" "Rule 3" "Rule 4" ...
#>  $ LHS       : chr  "whole milk" "other vegetables" "other vegetables" "rolls/buns" ...
#>  $ RHS       : chr  "sparkling wine" "artif. sweetener" "bathroom cleaner" "nuts/prunes" ...
#>  $ n.lhs     : num  1 1 1 1 1 1 1 1 1 1 ...
#>  $ support   : num  0.00102 0.00102 0.00102 0.00102 0.00102 ...
#>  $ confidence: num  0.00398 0.00525 0.00525 0.00553 0.00583 ...
#>  $ lift      : num  0.712 1.615 1.914 1.647 1.024 ...
#>  $ count     : num  10 10 10 10 10 10 10 10 10 10 ...

取り出したルールは、グラフ描画用のユーティリティ関数で眺める。

set.seed(0)
glo.inspectDF %>% 
  arrange(support, confidence) %>%
  head(60) %>% 
  plotRuleGraph()

f:id:kato-satoshi-0:20180724000155p:plain

インストール

GitHubから.

install.packages("devtools") # if you have not installed "devtools" package
devtools::install_github("katokohaku/inspectDF")

ソースコードも同じ場所。

モチベーション

本家のsubset(), sort()とかでなく、通常のdata.frameの操作としてやりたい。 本家の inspect() がコンソールに全部出力するのがツライ

print(glo.apriori)
#> set of 40943 rules

rules.lhs %>% summary()
#>      rule               LHS                RHS                  n.lhs        
#>  Length:8035        Length:8035        Length:8035        Min.   :2.000  
#>  Class :character   Class :character   Class :character   1st Qu.:2.000  
#>  Mode  :character   Mode  :character   Mode  :character   Median :3.000  
#>                                                           Mean   :2.739  
#>                                                           3rd Qu.:3.000  
#>                                                           Max.   :5.000  
#>     support           confidence           lift             count       
#>  Min.   :0.001017   Min.   :0.01815   Min.   : 0.4379   Min.   : 10.00  
#>  1st Qu.:0.001118   1st Qu.:0.14961   1st Qu.: 2.0673   1st Qu.: 11.00  
#>  Median :0.001322   Median :0.25175   Median : 2.6852   Median : 13.00  
#>  Mean   :0.001740   Mean   :0.30231   Mean   : 2.9595   Mean   : 17.11  
#>  3rd Qu.:0.001830   3rd Qu.:0.41935   3rd Qu.: 3.5531   3rd Qu.: 18.00  
#>  Max.   :0.022267   Max.   :1.00000   Max.   :22.1394   Max.   :219.00

arulesは非常によくできたパッケージですが、高度にwrapされ過ぎていて、気軽に弄ろうと思うとツライ。本家のprint()summary()も、探索的なルール分析にはちょっと不親切だと思いませんか。探索的なルール分析にはsubset(), sort()などが用意されているものの、表示はことごとく上記のそれです。ツライ。

また、本家の inspect()print()で返すため、コンソールにすべての出力が強制表示される。いつ終わるとも知れぬコンソール出力を眺めるの、ツライ。あと、標準では2番目の列名が無名なので、この後そのまま探索的に弄ろうとすると困る、というか矢印要る? ツライ。

glo.inspect  <- glo.apriori %>% head(10) %>% inspect()
#>      lhs               rhs            support     confidence  lift    
#> [1]  {honey}        => {whole milk}   0.001118454 0.733333333 2.870009
#> [2]  {whole milk}   => {honey}        0.001118454 0.004377238 2.870009
#> [3]  {soap}         => {whole milk}   0.001118454 0.423076923 1.655775
#> [4]  {whole milk}   => {soap}         0.001118454 0.004377238 1.655775
#> [5]  {tidbits}      => {soda}         0.001016777 0.434782609 2.493345
#> [6]  {soda}         => {tidbits}      0.001016777 0.005830904 2.493345
#> [7]  {tidbits}      => {rolls/buns}   0.001220132 0.521739130 2.836542
#> [8]  {rolls/buns}   => {tidbits}      0.001220132 0.006633499 2.836542
#> [9]  {cocoa drinks} => {whole milk}   0.001321810 0.590909091 2.312611
#> [10] {whole milk}   => {cocoa drinks} 0.001321810 0.005173100 2.312611
#>      count
#> [1]  11   
#> [2]  11   
#> [3]  11   
#> [4]  11   
#> [5]  10   
#> [6]  10   
#> [7]  12   
#> [8]  12   
#> [9]  13   
#> [10] 13

glo.inspect %>% str
#> 'data.frame':    10 obs. of  7 variables:
#>  $ lhs       : Factor w/ 7 levels "{cocoa drinks}",..: 2 7 4 7 6 5 6 3 1 7
#>  $           : Factor w/ 1 level "=>": 1 1 1 1 1 1 1 1 1 1
#>  $ rhs       : Factor w/ 7 levels "{cocoa drinks}",..: 7 2 7 4 5 6 3 6 7 1
#>  $ support   : num  0.00112 0.00112 0.00112 0.00112 0.00102 ...
#>  $ confidence: num  0.73333 0.00438 0.42308 0.00438 0.43478 ...
#>  $ lift      : num  2.87 2.87 1.66 1.66 2.49 ...
#>  $ count     : num  11 11 11 11 10 10 12 12 13 13

使い道

dplyrあたりと組み合わせて使うと、tidyに探索できるのではないか。

require(stringr)
rules.lhs  <- glo.inspectDF %>% 
  filter(str_detect(LHS, pattern = "yogurt|sausage")) %>%
  arrange(confidence, lift) %>%
  filter(n.lhs > 1) 

rules.lhs %>% head()
#>        rule               LHS                    RHS n     support
#> 1   Rule 97 whole milk,yogurt               UHT-milk 2 0.001016777
#> 2   Rule 98 whole milk,yogurt         red/blush wine 2 0.001016777
#> 3   Rule 99 whole milk,yogurt house keeping products 2 0.001016777
#> 4  Rule 100 whole milk,yogurt             liver loaf 2 0.001016777
#> 5 Rule 7175 whole milk,yogurt            chewing gum 2 0.001118454
#> 6 Rule 7176 whole milk,yogurt        cling film/bags 2 0.001118454
#>   confidence      lift count
#> 1 0.01814882 0.5425339    10
#> 2 0.01814882 0.9444108    10
#> 3 0.01814882 2.1767518    10
#> 4 0.01814882 3.5698730    10
#> 5 0.01996370 0.9485170    11
#> 6 0.01996370 1.7530626    11

プロットは hideaki さんのqiitaの記事をそのまま流用。エッジ上の円の面積はルールのsupport値、色の濃さはルールのconfidence値を表す。

adujust.support.sizeオプションでヒューリスティックなサイズの調整ができる。

require(stringr)
rules.lhs  <- glo.inspectDF %>% 
  filter(str_detect(RHS, pattern = "yogurt")) %>%
  arrange(confidence, lift) %>%
  filter(n.lhs > 1) %>% 
  head(15)

par(mfrow = c(1,2))
set.seed(0)
rules.lhs %>% plotRuleGraph(label = "default")
set.seed(0)
rules.lhs %>% plotRuleGraph(label = "adjusted rule size", 
                            adujust.support.size = 4000)

f:id:kato-satoshi-0:20180724000159p:plain

今後

{support, confidence, lift}{size, color}の対応は可変にして、サイズも自動調整したい。