11
$\begingroup$

I am using R (and the arules package) to mining transactions for association rules. What I wish to do is construct the rules and then apply them to new data.

For example, say I have many rules, one of which is the canonical {Beer=YES} -> {Diapers=YES}.

Then I have new transactional data where one of the records has purchased beer but not diapers. How can I identify a rule where the LHS is met, but not yet the RHS?

R example:

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

data("Groceries")
**#generate Rules omitting second record**

rules <- apriori(Groceries[-2],parameter = list(supp = 0.05, conf = 0.2,target = "rules"))

Rules generated are:

> inspect(rules)
  lhs                   rhs                   support confidence     lift
1 {}                 => {whole milk}       0.25554200  0.2555420 1.000000
2 {yogurt}           => {whole milk}       0.05603010  0.4018964 1.572722
3 {whole milk}       => {yogurt}           0.05603010  0.2192598 1.572722
4 {rolls/buns}       => {whole milk}       0.05664023  0.3079049 1.204909
5 {whole milk}       => {rolls/buns}       0.05664023  0.2216474 1.204909
6 {other vegetables} => {whole milk}       0.07484238  0.3867578 1.513480
7 {whole milk}       => {other vegetables} 0.07484238  0.2928770 1.513480

The second transaction shows this customer, since they have yogurt but not whole milk perhaps should be sent a coupon for milk. How can any applicable rules in "rules" be located for new transactions?

> LIST(Groceries[2])
[[1]]
[1] "tropical fruit" "yogurt"         "coffee" 
$\endgroup$
18
+50
$\begingroup$

The key is the is.subset-function in the same package

Here is the code ...

basket <- Groceries[2]
# find all rules, where the lhs is a subset of the current basket
rulesMatchLHS <- is.subset(rules@lhs,basket)
# and the rhs is NOT a subset of the current basket (so that some items are left as potential recommendation)
suitableRules <-  rulesMatchLHS & !(is.subset(rules@rhs,basket))

# here they are
inspect(rules[suitableRules])

# now extract the matching rhs ...
recommendations <- strsplit(LIST(rules[suitableRules]@rhs)[[1]],split=" ")
recommendations <- lapply(recommendations,function(x){paste(x,collapse=" ")})
recommendations <- as.character(recommendations)

# ... and remove all items which are already in the basket
recommendations <- recommendations[!sapply(recommendations,function(x){basket %in% x})]

print(recommendations)

and the generated output ...

> inspect(rules[suitableRules])
  lhs         rhs            support confidence     lift
1 {}       => {whole milk} 0.2555420  0.2555420 1.000000
2 {yogurt} => {whole milk} 0.0560301  0.4018964 1.572722

> print(recommendations)
[1] "whole milk"
$\endgroup$
  • $\begingroup$ Steffen - fabulous! Thanks very much, I did not see that function. I could see that ranking by lift (or other measure) to determine which rule to keep when several match would be quite easy. $\endgroup$ – B_Miner Jan 26 '12 at 18:42
  • $\begingroup$ I am aware that this is pretty old, but hopefully someone respond. What if I want to directly put basket <- "tropical fruit" "yogurt" "coffee"? $\endgroup$ – HonzaB Sep 24 '16 at 19:55
  • $\begingroup$ @HonzaB, I think you would need to cast it to the right type, ala: as(list(basket), "itemMatrix") $\endgroup$ – Harlan May 22 '17 at 22:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.