1993年,Agrawal等人首先提出关联规则概念,同时给出了相应的挖掘算法AIS,但是性能较差。1994年,他们建立了项目集格空间理论,并依据上述两个定理,提出了著名的Apriori算法,至今Apriori仍然作为关联规则挖掘的经典算法被广泛应用。


基于Apriori算法需要理解以下8个概念:

项集,说白了就是组成购物篮中的商品集合;


关联规则,一般记为X-->Y的形式,X表示先决条件,Y表示相应的关联结果。例如尿不湿-->啤酒表示购买了尿不湿的同时也会购买啤酒;


支持度,指所有项集中,同时购买X和Y的可能性,数学表达式可表示为:

基于R语言的关联规则实现_频繁项集

该指标可以为频繁项集指定一个阈值,从而剔除出现频率比较低的项集。这里举一个例子说明一下:

基于R语言的关联规则实现_数据_02


图中产生9表交易,其中单元格内1表示购物篮中购买了某种商品0表示没有购买某种商品,这里不妨以啤酒-->花生米为例。同时购买啤酒和花生米共有3笔,所以啤酒-->花生米的支持度为3/9=33.3%;


置信度,表示关联规则X-->Y中,发生X的前提下也出现了Y,其实就是一种条件概率,其数学表达式为:

基于R语言的关联规则实现_关联规则_03


该指标可控制哪些项集为强关联项集,即购买X的情况下有多大把握购买Y。仍以上图中的啤酒-->花生米为例,同时购买啤酒和花生米共有3笔,而交易中出现啤酒的有6笔,所以啤酒-->花生米的置信度为3/6=50%;


提升度,表示出现X的条件下同时出现Y的可能性与没有任何条件下出现Y的可能性之比,可用数学表达式表示为:

基于R语言的关联规则实现_频繁项集_04


该指标是置信度的补充,用来判断X与Y之间是否独立,不独立的话关联性有多强。一般提升度等于1时,表示X与Y之间是独立的,即X的出现对Y的出现没有派上仍然作用;提升度大于1,且值越大说明X对Y的影响越大,关联性也就越强

关于提升度的计算,以啤酒-->花生米为例,根据置信度的计算,啤酒-->花生米的置信度为50%,出现花生交易(3笔)占总交易(9笔)为33.3%,所以啤酒-->花生米的提升度为50%/33.3%=1.5;


频繁项集,如果项集I满足给定最小支持度的阈值,则项集I就为频繁项集;


闭频繁项集,首先项集X为频繁项集,其次项集X与其超项集Y(X是Y的真子集)不具有相同的支持度。为了清楚说明该概念,使用下图中的例子:

基于R语言的关联规则实现_频繁项集_05


假设频繁项集的支持数为2,即项集出现2次及以上就可以认为是频繁项集,以{a,c}为例,该项集出现4次,故为频繁项集,{a,c}的超项集有{a,b,c}、{a,c,d}和{a,b,c,d},他们分别出现了2次、1次和1次,所以X与Y没有相同的支持度,即{a,c}就为一个闭频繁项集


极大频繁项集,首先项集X为频繁项集,其次项集X的超项集Y不是频繁项集,仍以上图为例,项集{a,b,c}出现了3次,满足频繁项集的要求,其超项集{a,b,c,d}只出现了1次,故不是频繁项集,所以项集{a,b,c}就是一个极大频繁项集,而{a,c}就不是一个极大频繁项集,因为它的超项集{a,b,c}是一个频繁项集。


Apriori算法性质

Apriori算法具有一个非常重要的性质,即先验性质,说的是频繁项集的所有子集也一定是频繁的。一般在算法的实现中利用了该性质的反语,即一个项集如果不是频繁项集,其超项集也一定不是频繁项集。利用该性质可以大大减少算法对数据的遍历次数


例如一个只含有4种商品的超市,该4种商品一共可组合成15种项集,如下图所示:

基于R语言的关联规则实现_数据_06

如果发现项集{2,3}不是频繁的,则{2,3}的超项集也一定不是频繁的,所以下图中就可以不必再扫描{0,2,3}、{1,2,3}和{0,1,2,3}三种情况了,从而可以减少模型的运算次数、提高效率。

基于R语言的关联规则实现_数据_07


Apriori算法的应用

R中提供了两个专用于关联规则的软件包,即arules包和arulesViz包,前者用于产生关联规则的定量化结果,后者用于产生关联规则的可视化结果。


arules包中两个重要的函数,apriori()和eclat()函数,其函数语法和参数:

apriori(data, parameter = NULL, appearance = NULL,

control = NULL)

eclat(data, parameter = NULL, control = NULL)


data为apriori函数和eclat函数所能接受的“交易”格式数据,可以通过as()函数将常见的二元矩阵、数据框进行转换;

parameter以列表的形式存储模型所需的支持度、置信度、每个项集所含项数的最大值/最小值和输出结果类型等参数,默认情况下支持度为0.1,置信度为0.8,项集中最大项数为10,最小项数为1,输出关联规则/频繁项集类型的结果;

appearance可为先决条件X和关联结果Y指定明确的项集(一般是分析人员感兴趣的项集),默认情况下不为X和Y指定某些项集;

control用来控制函数性能,如对项集进行升序或降序,生成算法运行的报告进程等。


eclat函数相比于apriori函数,主要区别在于其无法生成关联规则,且每个项集所含项数的最大值默认为5。


下面的实例部分使用的数据为rattle包中,csv目录下的dvdtrans.csv 文件,该数据显示了DVD购买的记录。


library(arules)

file <- 'C:\\Program Files\\R\\R-3.2.1\\library\\rattle\\csv\\dvdtrans.csv'

dvdtrans <- read.csv(file,head = TRUE)

head(dvdtrans)

基于R语言的关联规则实现_关联规则_08


该数据为常见的数据框格式数据,需要将其转换为aprior()函数和eclat()函数所能接受的格式。

data <- as(split(dvdtrans[,'Item'], dvdtrans[,'ID']), 'transactions')

data

inspect(data)

基于R语言的关联规则实现_数据_09


下面就可以使用apriori()函数和eclat()函数对数据集data进行关联规则算法的运用

summary(data)

基于R语言的关联规则实现_频繁项集_10


图中第一段:总共有10条交易,10中商品,density=0.3表示稀疏矩阵中1的占比;

图中第二段:最频繁出现的商品及对应的频次,显然电影Gladiator最受欢迎,其次是电影Patriot和Sixth Sense;

图中第三段:每笔交易包含的商品数目,以及其对应的5个分位数和均值的统计信息。如3笔交易包含2个商品,5笔交易包含3个商品,两个1笔交易各包含4种和5种商品;第一个分位数是2,表示25%的交易不超过2种商品,平均值表示所有交易中,平均每笔购买3种商品;

图中第四段:如果数据集包含除了Transaction Id 和 Item之外的其他列(如,发生交易的时间,用户ID等等),会显示在这里。这个例子,其实没有新的列,labels就是item的名字。


由于交易量较少,这里不妨将参数支持度的最小值设为0.3,置信度的最小值设为0.5,其他参数暂不作修改。

res1 <- apriori(data = data, parameter = list(support = 0.3, confidence = 0.5))

res1

inspect(res1)

基于R语言的关联规则实现_数据_11


图中第一部分包括模型中指定的最小支持度、置信度、项集中最大/最小项数、输出结果形式和算法的执行细节;

图中第二部分显示该算法产生12条关联规则;

图中第三部分则显示了12种关联规则的明细,如果数据量特别大,且产生的关联规则也特别多时,直接输出结果并不能看出什么有意义的结果,可以通过sort函数对支持度support、置信度confidence和提升度lift进行排序,选出比较靠前的关联规则


对生成的关联规则进行强度控制

一般来说,对于数据量比较大的交易,可以直接使用apriori()函数的默认参数来生成规则,再根据业务情况进行调整。比如,先将阈值设置很低,再逐步提升阈值,直到达到理想的规则和强度。对于强度的控制,可以设置不同的支持度support、置信度confidence和提升度lift来实现。


#同时调整支持度和置信度进行调整

res2 <- apriori(data = data, parameter = list(support = 0.5, confidence = 0.6))

res2

产生7条关联规则


res3 <- apriori(data = data, parameter = list(support = 0.3, confidence = 0.75))

res3

产生5条关联规则


res4 <- apriori(data = data, parameter = list(support = 0.5, confidence = 0.75))

res4

产生3条关联规则


#通过支持度控制

res.sorted_sup <- sort(res1, by = 'support')

inspect(res.sorted_sup[1:5])

#通过置信度控制

res.sorted_sup <- sort(res1, by = 'confidence')

inspect(res.sorted_sup[1:5])

#通过提升度控制

res.sorted_sup <- sort(res1, by = 'lift')

inspect(res.sorted_sup[1:5])

基于R语言的关联规则实现_关联规则_12



在支持度和置信度的调整过程中,如果更关注关联项集在总体中所占比重,可以适当提高支持度;如果更注重规则本身的可靠性,可提高置信度;提升度可以说是筛选关联规则最可靠的指标,并且根据该指标还可以得到比较有趣的结论。


使用eclat()函数获取最适合进行捆绑销售的产品

res5 <- eclat(data = data, parameter = list(minlen = 2, maxlen = 3, support = 0.3, target = 'frequent itemsets'), control = list(sort = -1))

res5

inspect(res5)

基于R语言的关联规则实现_关联规则_13

关于关联规则的可视化部分可以参考《数据挖掘:R语言实战》第6.3.5部分。


参考资料

数据挖掘:概念与技术

数据挖掘:R语言实战

​http://cos.name/2013/02/association-rules-with-r-and-sas/​

​http://www.klshu.com/1202.html​


总结:文中使用到的包和函数

stats包

summary()

inspect()

read.csv()

methods包

as()

arules包

apriori()

eclat()

inspect()