首页 > 技术文章 > 关联分析--R实现案例

YY-zhang 2021-09-08 19:03 原文

R中的实现

相关软件包

R中两个专用于关联分析的软件包-—arules arulesViz。其中,arules用于关联规则的数字化生成,提供AprioriEclat这两种快速挖掘频繁项集和关联规则算法的实现函数;arulesViz软件包作为arules 的扩展包,提供了几种实用而新颖的关联规则可视化技术,使得关联分析从算法运行到结果呈现一体化。

核心函数

Apriori是最经典的关联分析挖掘算法,原理清晰且实现方便,可以说是学习关联分析的入门算法,但效率较低;Eclat算法则在运行效率方面有所提升。

(1). apriori函数

R中实现Apriori算法,其核心函数为apriori(),来源于前面介绍数据集时提到的arules软件包。函数的基本格式为:

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

其中,parameter参数可以对支持度(support)、置信度(confidence)、每个项集所含项数的最大值/最小值(maxlen/minlen),以及输出结果(target)等重要参数进行设置。如果没有对其进行设值,函数将对各参数取默认值: support=0.1confidence=0.8maxlen=10minlen=1target=“rules""“frequent itemsets”(输出关联规则/频繁项集)

而参数 appearance可以对先决条件X(lhs)和关联结果Y(rhs)中具体包含哪些项进行限制,:设置lhs=beer,将仅输出 lhs 中含有啤酒这一项的关联规则,在默认情况下,所有项都将无限制出现。

control参数则用来控制函数性能,如可以设定对项集进行升序(sort=1)还是降序(sort=-1)排序,是否向使用者报告进程(verbose=TURE/FALSE)等。

(2). eclat函数

Eclat算法的核心函数即为eclat(),其格式为:

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

apriori()相比,我们看到参数 parametercontrol被保留,而不含有appearance参数。其中parametercontrol 的作用与apriori()中基本相同,但需要注意的是,parameter中的输出结果( target)一项不可设置为rules,即通过eclat()函数无法生成关联规则,并且maxlen 的默认值为5

数据集

我们选择使用arules软件包中的Groceries数据集进行算法演示,该数据集是某一食品杂货店一个月的真实交易数据。

library(arules)

data("Groceries")

summary(Groceries)

 

结果分析:它共包含9835条交易(transactions)以及169个项( items),也就是我们通常所说的商品;并且全脂牛奶(whole milk)是最受欢迎的商品,之后依次为蔬菜(other vegetables)、面包卷(rolls/buns)等。

现在展示数据集的前10条交易信息:

inspect(Groceries[1:10])

 

结果分析:其中每一条数据即代表一位消费者购物篮中的商品类别,如:第一位消费者购买了柑橘( citrus fruit)、半成品面包( semi-finished bread)、黄油( margarine)以及即食汤(ready soups)四种食物。

应用案例

运用R软件挖掘Groceries 数据中各商品的购买行为中所隐含的关联性。

1 数据初探

首先,我们尝试对apriori()函数以最少的限制,来观察它可以反馈给我们哪些信息,再以此决定下一步操作。这里将支持度的最小阈值(minsup)设置为0.001,置信度最小阈值(mincon)设为0.5,其他参数不进行设定取默认值,并将所得关联规则名记为rules0。

rules0<-apriori(Groceries,parameter = list(support=0.001,confidence=0.5))

 

rules0    #显示rules0中生成的关联规则条数

 

inspect(rules0[1:10])   #观测rules0中前10条规则

 

结果分析:输出包括5668条关联规则,如此大量的关联规则全部输出使没有意义的,所以需要设置具体的参数。

2 对生成规则进行强度控制

最常用的方法即是通过提高支持度和/或置信度的值来实现这一目的,而最终关联规则的规模大小,或者说强度高低,是根据使用者的需要决定的。但需要知道,如果阈值设定较高,容易丢失有用信息,若设定较低,则生成的规则数量将会很大。

一般来说,我们可以选择先不对参数进行设置,直接使用apriori()函数的默认值(支持度为0.1,置信度为0.8)来生成规则,再进一步调整。或者如上一节所示,先将阈值设定得很低,再逐步提高阈值,直至达到设想的规则规模或强度。

(1) 通过支持度、置信度共同控制

首先,我们可以考虑将支持度与置信度两个指标共同提高来实现,如下当仅将支持度提高0.004至0.005时,规则数降为120条,进而调整置信度参数至0.64后,仅余下4条规则。另外,在两参数共同调整过程中,如果更注重关联项集在总体中所占的比例,则可以适当地多提高支持度的值:若是更注重规则本身的可靠性,则可多提高一些置信度值。

rules1<-apriori(Groceries,parameter = list(support=0.005,confidence=0.5))

rules1

 

rules2<-apriori(Groceries,parameter = list(support=0.005,confidence=0.6))

rules2

 

rules3<-apriori(Groceries,parameter = list(support=0.005,confidence=0.64))

rules3

 

inspect(rules3)

 

(2) 主要通过支持度控制

另外,也可以采取对其中一个指标给予固定阈值,再按照其他指标来选择前5强的关联规则。比如当我们想要按照支持度来选择:

rules.sorted_sup<-sort(rules0,by="support")  #设置支持度阈值为0.5,按支持度排序

inspect(rules.sorted_sup[1:5])   #输出前5条强关联规则

 

(3)主要通过置信度控制

以下类似的,我们按照置信度来选出前5条强关联规则,由输出结果得到了5条置信度高达100%的关联规则,比如第一条规则:购买了米和糖的消费者,都购买了全脂牛奶。这就是一条相当有用的关联规则,正如这些食品在超市中往往摆放得很近。 

rules.sorted_sup<-sort(rules0,by="confidence")  

inspect(rules.sorted_sup[1:5])   

 

(4)主要通过提升度控制

我们按lift值进行升序排序并输出前5条:

rules.sorted_lift<-sort(rules0,by="lift")

inspect(rules.sorted_lift[1:5])

 

结果分析:由以上输出结果,我们能够清晰地看到强度最高的关联规则为{即食食品,苏打水}→{汉堡肉},其后为{苏打水,爆米花}→{垃圾食品}。

实际应用案例

相信你在逛超市时一定发现过两种商品捆绑销售的情况,这可能是因为商家想要促销其中的某种商品。比如我们现在想要促销一种比较冷门的商品——芥末(mustard),可以通过将函数 apriori)中的关联结果(rhs)参数设置为“mustard”,来搜索出rhs中仅包含mustard 的关联规则,从而有效地找到mustard 的强关联商品,来作为捆绑商品。

如下输出结果显示蛋黄酱(mayonnaise)是芥末( mustard)的强关联商品,因此我们可以考虑将它们捆绑起来摆放在货架上,并制定一个合适的共同购买价格,从而对两种商品同时产生促销效果。另外,我们还用到了参数 maxlen,这里将其设为2,控制lhs 中仅包含一种食品,这是因为在实际的情形中,我们一般仅将两种商品进行捆绑,而不是一堆商品。

rules4<-apriori(Groceries,parameter = list(maxlen=2,support=0.001,confidence=0.1),appearance = list(rhs="mustard",default="lhs"))

inspect(rules4)

 

改变输出结果形式

我们知道,apriori()和eclat()函数都可以根据需要输出频繁项集(frequent itemsets)等其他形式结果。比如当我们想知道某超市这个月销量最高的商品,或者捆绑销售策略在哪些商品簇中作用最显著等,选择输出给定条件下的频繁项集即可。

如下即是将目标参数(target)设为“frequent itemsets”后的结果:

itemsets_apr<-apriori(Groceries,parameter = list(supp=0.001,target="frequent itemsets"),control = list(sort=-1))

itemsets_apr   #显示生成频繁项集的个数

 

inspect(itemsets_apr[1:5])  #观察前5个频繁项集

 

结果分析:我们看到以sort参数对项集频率进行降序排序后,销量前5的商品分别为全脂牛奶、蔬菜、面包卷、苏打以及酸奶。

我们使用eclat()函数来获取最适合进行捆绑销售,或者说相近摆放的5对商品。比如,下面的输出结果中的全脂牛奶和蜂蜜,以及全脂牛奶与苏打作为共同出现最为频繁的两种商品,则可以考虑采取相邻摆放等营销策略。(频繁项集的产生只于支持阈值有关)

itemsets_ecl<-apriori(Groceries,parameter = list(minlen=1,maxlen=3,supp=0.001,target="frequent itemsets"),control = list(sort=-1))

itemsets_ecl

inspect(itemsets_ecl[1:5])

 

推荐阅读