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$

1 Answer 1

19
+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$
3
  • $\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, 2012 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, 2016 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, 2017 at 22:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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