Efficient recommending with the arules package

The arules package is a great R package for inferring association rules using the Apriori and Eclat algorithms, and can for example be used for recommending items to users, based on known purchases of these items by the same, or possibly different, users.

In this package, one can use the apriori() and eclat() functions to fit a model consisting of association rules. The arules documentation gives the following example:


library(arules)
data(Adult)
imat <- as(Adult, "itemMatrix")

rules <- apriori(
  imat,
  parameter = list(
    supp = 0.5,
    conf = 0.9,
    target = "rules"
  )
)

However, one thing I’ve personally missed in the arules package is a general recommend() function, analogous to a predict() function that often accompanies a fit() function in R packages, to make predictions based on a fitted model and new data. A recommend() function would predict for each combination of user and item whether that particular item would be recommended to that particular user. Such a function can be written as follows:


recommend <- function(
  rules, # object of class rules
  newdata # object of class itemMatrix
) {

  # Which transactions in newdata match
  # the LHS of which rule?
  lhs_match <- is.superset(
    newdata,
    lhs(rules),
    sparse = TRUE
  )

  # For which (item, transaction) pairs is
  # the RHS also matched?
  rec <- lhs_match %*% t(rhs(rules)@data)

  # Make sure the row/column names
  # are the same
  rownames(rec) <- rownames(newdata)
  colnames(rec) <- colnames(newdata)

  # return an itemMatrix
  as(t(rec), "itemMatrix")
}

Building on the example above, recommendations are then done as follows:


rec <- recommend(rules, imat)
# If desired, remove known values
rec@data[imat@data] <- FALSE

Note that the above recommend() function is quite efficient, as it does not do any looping, but instead uses matrix multiplication after the call to is.superset() to combine matches to the left-hand side of rules with matches to the right-hand side of rules.