在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1993年,Agrawal等人首先提出关联规则概念,同时给出了相应的挖掘算法AIS,但是性能较差。1994年,他们建立了项目集格空间理论,并依据上述两个定理,提出了著名的Apriori算法,至今Apriori仍然作为关联规则挖掘的经典算法被广泛应用。
基于Apriori算法需要理解以下8个概念: 项集,说白了就是组成购物篮中的商品集合;
关联规则,一般记为X-->Y的形式,X表示先决条件,Y表示相应的关联结果。例如尿不湿-->啤酒表示购买了尿不湿的同时也会购买啤酒;
支持度,指所有项集中,同时购买X和Y的可能性,数学表达式可表示为:
该指标可以为频繁项集指定一个阈值,从而剔除出现频率比较低的项集。这里举一个例子说明一下:
置信度,表示关联规则X-->Y中,发生X的前提下也出现了Y,其实就是一种条件概率,其数学表达式为:
提升度,表示出现X的条件下同时出现Y的可能性与没有任何条件下出现Y的可能性之比,可用数学表达式表示为:
关于提升度的计算,以啤酒-->花生米为例,根据置信度的计算,啤酒-->花生米的置信度为50%,出现花生交易(3笔)占总交易(9笔)为33.3%,所以啤酒-->花生米的提升度为50%/33.3%=1.5;
频繁项集,如果项集I满足给定最小支持度的阈值,则项集I就为频繁项集;
闭频繁项集,首先项集X为频繁项集,其次项集X与其超项集Y(X是Y的真子集)不具有相同的支持度。为了清楚说明该概念,使用下图中的例子:
极大频繁项集,首先项集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种项集,如下图所示:
如果发现项集{2,3}不是频繁的,则{2,3}的超项集也一定不是频繁的,所以下图中就可以不必再扫描{0,2,3}、{1,2,3}和{0,1,2,3}三种情况了,从而可以减少模型的运算次数、提高效率。
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)
该数据为常见的数据框格式数据,需要将其转换为aprior()函数和eclat()函数所能接受的格式。 data <- as(split(dvdtrans[,'Item'], dvdtrans[,'ID']), 'transactions') data inspect(data)
下面就可以使用apriori()函数和eclat()函数对数据集data进行关联规则算法的运用 summary(data)
图中第一段:总共有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)
图中第一部分包括模型中指定的最小支持度、置信度、项集中最大/最小项数、输出结果形式和算法的执行细节; 图中第二部分显示该算法产生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])
在支持度和置信度的调整过程中,如果更关注关联项集在总体中所占比重,可以适当提高支持度;如果更注重规则本身的可靠性,可提高置信度;提升度可以说是筛选关联规则最可靠的指标,并且根据该指标还可以得到比较有趣的结论。
使用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语言实战》第6.3.5部分。
参考资料 数据挖掘:概念与技术 数据挖掘:R语言实战 http://www.cnblogs.com/qwertWZ/p/4510857.html http://cos.name/2013/02/association-rules-with-r-and-sas/ http://www.klshu.com/1202.html http://blog.csdn.net/gjwang1983/article/details/45015203
总结:文中使用到的包和函数 stats包 summary() inspect() read.csv() methods包 as() arules包 apriori() eclat() inspect() |
请发表评论