Association rule mining interpretation

I am trying to create a association using apriori algorithm.The data contains around 33000 records.Below is the sample of the data

id  code
1   19
1   58
1   111
2   19
2   111
2   167
3   12
3   79
3   85
4   96
5   19
6   58
7   12
7   18
7   40
7   48
7   85
7   86
7   135


In R this data is:

structure(list(id = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7,
7, 7, 7, 7, 7, 7), code = c(19, 58, 111, 19, 111, 167, 12, 79,
85, 96, 19, 58, 12, 18, 40, 48, 85, 86, 135)), .Names = c("id",
"code"), row.names = c(NA, -19L), class = "data.frame")


Using the following code I tried to build the association

# creating a string of codes based on the id
library(dplyr)
Asso2 = Asso %>%
group_by(patient_id) %>%
summarise(hi = toString(hcc_id))
# converting into transactions
library(arules)
fact <- data.frame(lapply(Asso2,as.factor))
trans <- as(fact, 'transactions')
# Applying aprior
rules = apriori(trans, parameter = list(supp = 0.001, conf = 0.001,target = "rules"))
rules
inspect(rules)


I am getting totally 96 rules like below with empty lhs and I trying to understand whether we cannot make any rules from this data or am I missing anything here. Since I am novice in this, I would like to get some help.

#     lhs    rhs               support     confidence  lift
#  1  {}  => {hi=19, 96, 108}  0.001021696 0.001021696 1
#  2  {}  => {hi=176}          0.001021696 0.001021696 1
#  3  {}  => {hi=88, 108}      0.001021696 0.001021696 1
#  4  {}  => {hi=72}           0.001051746 0.001051746 1
#  5  {}  => {hi=88, 96}       0.001051746 0.001051746 1
#  6  {}  => {hi=108, 112}     0.001081796 0.001081796 1
#  7  {}  => {hi=84}           0.001081796 0.001081796 1
#  8  {}  => {hi=100, 103}     0.001111846 0.001111846 1
#  9  {}  => {hi=18, 108, 111} 0.001111846 0.001111846 1


Yes, this basically means that no sensible rules can be built with the constrains of support and confidence you impose. Note that your lift is always trivially one. The solution to this is given in the documentation of the package:

Note: The default value in APparameter for minlen is 1.
This means that rules with only one item (i.e., an empty
antecedent/LHS) like {} => {beer} will be created. These
rules mean that no matter what other items are involved
the item in the RHS will appear with the probability given
by the rule's confidence (which equals the support). If
you want to avoid these rules then use the argument
parameter=list(minlen=2).

• thanks for your suggestion. But when I add minlen=2, it is not creating any rules. i.e., set of 0 rules
– ssan
Jul 18, 2016 at 16:31
• Try decreasing the minimum support and confidence. The higher you set those limits, the fewer rules will be found. This was basically the reason why you found only rules with empty antecedents before. Looking at the low support values in your sample output, I think you'll have to go quite low to get rules of size two. Try starting with 1e-4 or 1e-5 and work your way up from there. Jul 19, 2016 at 7:23
• before going ahead I would like to hear one more thing. As you see the data, there are duplicate id with different codes. I want to know that before converting the data into transaction type, should I change the code variable into string as I did using dplyr function and then make the df into transactions. Because I doubt that I should convert the df directly to the transaction type and apply the algo.
– ssan
Jul 19, 2016 at 7:44
• I see. Converting your data from transactional format is a common pitfall. I'm not an expert on R, but have used dplyr before and now that you mention it your conversion does look a bit sketchy. It's a bit hard to tell though not seeing your .csv. I'd recommend you take a look at example 4 of the transaction class documentation which seems to be just what you want. The documentation of R is sometimes a bit hard to navigate which can make it scary for beginners. Hang in there! Jul 19, 2016 at 7:54

I am not completely fluent in R either and I remember I had troubles converting the data into transactions as well. What worked for me was this (I had same structure as you):

read.csv("C:/Users/ ... /data.csv", header = TRUE, sep=";")
dat <- split(dat$product, dat$ID)
trans <- as(dat, "transactions")


The package arules also contains tool from convert the .csv into transactions read.transactions(...).

As was stated in previous answers, you can play with length, support or confidence. I'd also propose to try change the sides as follows:

#What am I likely to buy BEFORE buying XY Product(rhs="XY")
rulesB <- apriori(data=trans, parameter=list(supp=0.006,conf=0.1),
appearance = list(default="lhs",rhs="22"),
control = list(verbose=F))


Or

#What am I likely to buy AFTER buying XY Product(lhs="XY")
rulesA <- apriori(data=trans, parameter=list(supp=0.006,conf=0.1),
appearance = list(default="rhs",lhs="22"),
control = list(verbose=F))


Lastly, there is great introduction to Association rules in R here.