关联规则R语言实战(Apriori算法)

浏览: 4831

  最近遇到一个业务问题需要用关联规则的算法来实现,为了解决业务问题,我又重新复习了一遍以前就学过的Apriori算法并将其运用到业务场景中。下面,我想谈一谈在具体的业务实现过程中我的一些感想。   

一.理论背景

1.1基本术语定义  

  X和Y各代表某一个项集,M代表样本中的总项集数。

1.2关联规则的三个度量  

  衡量关联规则有三个最基本也是最重要的指标,我将其称为‘三度’。这里的三度指的可不是《三傻大闹宝莱坞》里面那三个蠢萌蠢萌的印度人,而是指的度量关联规则最基础也是最核心的指标三兄弟:支持度,置信度,提升度。   

  下面我将对这三兄弟进行逐一介绍。  

  老大支持度,是‘三度’家族里最沉稳最老实的孩子。出于兄长对两个弟弟的谦让之情,关联规则家族建立的时候,老大主动表示他要来度量关联规则中最苦最累随时要给弟弟们提供理论支持的概念。关联规则家族表示老大good job,于是便给老大赐名为支持度,基本公式是

image.png

说完了基本公式,我们来说说老大支持度的基本公式代表的基本概念:老大支持度表示了X项集出现的次数在所有项集的总次数中所占的比例。  

  老二置信度,是‘三度’家族中最高调也是最不折手段的孩子。为了获得最重要的地位,老二踩着老大的肩膀往上爬,于是,他获得了赐名:置信度,基本公式是

image.png

可以明显地看到,老二置信度的公式的分子分母都靠了老大的帮助,可以说老二的身份完全是踩着老大的肩膀建立起来的,没有老大支持度的无私奉献,就没有老二置信度的今天。说完了基本公式,来说说老二置信度的基本概念:老二置信度,代表了XY这个项集出现的次数在X这个项集出现的次数中所占的比例。   

  老三提升度,是‘三度’家族中容易被人给遗忘的小可怜。从定义上来说,老三算是老大支持度和老二置信度的结合体,可由于老二置信度太醒目了,许多人在做关联规则时在没有完全吃透理论的情况下往往容易忽略老三提升度的存在。下面先给出老三提升度的公式

image.png

先给出提升度的基本概念:老三提升度,计算的是相比于从所有项集中找Y,在存在X的项集中找Y找到的可能性提升的倍数。通常在数据挖掘中,提升度大于3的关联规则才是有意义的,这是因为如果太低甚至小于1,那么说明从存在X的项集中找Y找到的可能性并不比从所有项集中找Y高多少甚至还要低,这样的话,那还不如直接从所有项集中找Y,免得费时又费力还提升不了效率,这样的规则,不要也罢。 


1.3Apriori算法理论  

  在了解了关联规则的三个度的基本定义之后,下一步则需要阐述清楚Apriori算法的基本定义。  

  在讲Apripri算法之前,我们首先要清楚两个概念:  

  1)设定最小支持度的阈值,如果一个项集的支持度大于等于最小支持度,则其为频繁项集,如果一个项集的支持度小于最小支持度,则其为非频繁项集。  

  2)对于一个项集,如果它是频繁集,则它的子集均是频繁集;如果它是非频繁集,则它的父集都是非频繁集。这是因为一个项集的所有子集的支持度都大于等于它本身,一个项集的所有父亲的支持度都小于等于它本身。  

  有了上面两个概念打底,Apriori算法就可以被定义了。Apripri算法主要分为三步:  

  1)设定最小支持度的阈值。从单项集开始,先计算所有单项集的支持度,过滤掉非频繁单项集及其父集;将剩余的单项集组合为二项集,先计算所有二项集的支持度,过滤掉非频繁二项集及其父集;不断地迭代上述过程,最后筛选出所有的频繁项集。  

  2)设定最小置信度的阈值。对频繁项集进行计算,求出满足置信度条件的强关联规则。  

  3)设定最小提升度的阈值。对第2)步进行计算,求出满足提升度条件的强关联规则,作为最后的关联规则的模型结果。  

  相比于最原始的一一计算,使用Apripor算法计算频繁项集可以大大地减少运算量,提升计算效率。  到底,理论的梳理就完全结束,下一步我将会对关联规则进行实战演练。


二.实操演练

2.1数据源  

  因为业务需要保密,所以实战演练部分我并没有用业务中的真实数据来进行记录,而是借用了arules包中和我业务数据很像的Epub数据来对我的建模过程来进行一个回顾和梳理。  

  Epub数据包含了来自维也纳大学经济与工商管理学院的电子文档平台的下载历史。

library(arules)
#导入数据
>data(Epub)
#查看数据类型
>class(Epub)
[1]"transactions"
#因为我的业务数据是从oracle数据库里面导出来的,所以我这里便把Epub数据转成data.frame格式,然后导出到数据库之后,重新从数据库导入,以便能够记录整个建模流程
>Epub<-as(Epub,"data.frame") 
#因为业务不需要,所以演示时也去掉时间字段
>Epub<-Epub[,1:2] 


 导出进数据库因为不属于建模流程,这里就不记录了。


2.2数据准备  

  上一节对数据源进行了基本的阐释下面正式进入正题,我将会从数据库导入开始一步步记录我的建模流程。  

  首先,是数据准备过程。

#引入链接数据库的RODBC包
library(RODBC)
#连接数据库
channel<-odbcConnect("数据库名",uid="orcl",pwd="orcl")
#读入数据
Epub<-sqlQuery(channel,"select * from Epub")
#查看数据前六行
head(Epub)

  此时数据应该是如下表格的data.frame结构:

image.png

  这个时候,表格是数据库存储的格式而非事务集的格式,因此首先要对数据进行格式转换。  

  首先,要对数据进行分组,一个transactionID的所有items应该在一个组里,因此,我们可以使用split函数,指定它的分组变量和目标变量:

>Epub<-split(Epub$items,Epub$transacionID)
#分组之后,将Epub数据转换成事务集形式
>Epub<-as(Epub,"transacions")
#查看Epub数据的前十行
>inspect(Epub[1:10])
items transactionID
[1] {doc_154} session_4795
[2] {doc_3d6} session_4797
[3] {doc_16f} session_479a
[4] {doc_11d,doc_1a7,doc_f4} session_47b7
[5] {doc_83} session_47bb
[6] {doc_11d} session_47c2
[7] {doc_368} session_47cb
[8] {doc_11d,doc_192} session_47d8
[9] {doc_364} session_47e2
[10] {doc_ec} session_47e7

  Eupb已经被转化成了事务集,到此,我们就已经做好数据的准备。   

2.3建模  

  数据准备好之后,就进入整个流程中最重要也是最核心的建模步骤中了。

#查看数据集统计汇总信息
>summary(Epub)
transactions as itemMatrix in sparse format with
15729 rows (elements/itemsets/transactions) and
936 columns (items) and a density of 0.001758755

most frequent items:
doc_11d doc_813 doc_4c6 doc_955 doc_698 (Other)
356 329 288 282 245 24393

element (itemset/transaction) length distribution:
sizes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
11615 2189 854 409 198 121 93 50 42 34 26 12 10 10 6 8 6 5 8
20 21 22 23 24 25 26 27 28 30 34 36 38 41 43 52 58
2 2 3 2 3 4 5 1 1 1 2 1 2 1 1 1 1

Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 1.000 1.000 1.646 2.000 58.000

includes extended item information - examples:
labels
1 doc_11d
2 doc_13d
3 doc_14c

includes extended transaction information - examples:
transactionID
10792 session_4795
10793 session_4797
10794 session_479a
#可以使用dim函数提取项集数和item数
>dim(Epub)
[1] 15729 936

  第一步,查看数据集的统计汇总信息。summary()含义的具体解释如下:  

  1)共有15729个项集和936 个item,稀疏矩阵中1的百分比为0.001758755。  

  2)most frequent items描述了最频繁出现的5个item以及其分别出现的次数。  

  3)sizes描述了项集的项的个数以及n项集共有几个,例如单项集有10个,二项集有11个,58项集有1个。sizes之后描述了sizes对应的5个分位数和均值的统计信息。

#统计每个item的支持度
>itemFreq<-itemFrequency(Epub)
#每个项集transaction包含item的个数
>Size<-size(Epub)
#每个item出现的次数
> itemCount<-(itemFreq/sum(itemFreq)*sum(Size))

  除此之外,还可以更直观地作图观测itemFrequency。

#查看支持度排行前10的图
>itemFrequencyPlot(Epub,topN=10,col="lightblue")

itemFrequencyPlottopN.png

  当对数据的基本统计信息心中有数之后,就开始最重要的建模步骤。

#最小支持度0.001,最小置信度0.6,最小项数2
>rules<-apriori(Epub,parameter=list(support=0.001,confidence=0.6,minlen=2))

  这里解释一下最小项数。minlen和maxlen表示LHS+RHS并集的元素的最小个数和最大个数。有意义的规则起码是LHS和RHS各至少包含1个元素,所以minlen为2。  

      生成模型之后,观测模型结果。

#展示生成的规则
inspect(sort(rules,by="lift"))
lhs rhs support confidence lift
[1] {doc_6e7,doc_6e8} => {doc_6e9} 0.001080806 0.8095238 454.7500
[2] {doc_6e7,doc_6e9} => {doc_6e8} 0.001080806 0.8500000 417.8016
[3] {doc_6e8,doc_6e9} => {doc_6e7} 0.001080806 0.8947368 402.0947
[4] {doc_6e9} => {doc_6e8} 0.001207960 0.6785714 333.5391
[5] {doc_6e9} => {doc_6e7} 0.001271537 0.7142857 321.0000
[6] {doc_506} => {doc_507} 0.001207960 0.6551724 303.0943
[7] {doc_6e8} => {doc_6e7} 0.001335113 0.6562500 294.9187
[8] {doc_6e7} => {doc_6e8} 0.001335113 0.6000000 294.9187
[9] {doc_87c} => {doc_882} 0.001335113 0.6000000 171.5891

  使用inspect函数,将会具体的展示生成的每一条强规则,其对应的支持度support,置信度confidence ,提升度为lift。by设置为lift,表示展示的规则将会按照提升度lift的大小进行排序。  

  除了一次性查询所有规则,还可以指定搜索条件,查看规则的子集。

>subrules<-subset(rules,items %in% c("doc_882") & lift>=3)
>inspect(sort(subrules,by="lift"))
lhs rhs support confidence lift
[1] {doc_87c} => {doc_882} 0.001335113 0.6000000 171.5891

#对于规则,我们也可单独查询它的三度,例如现在查询自规则subrules的三度:
>subrulesquality<-quality(subrules)
>subrulesquality
support confidence lift
22 0.001335113 0.6000000 171.5891
23 0.001335113 0.3818182 171.5891

   这样就得到了包含doc_882的规则。  

   到此,建模部分就梳理完毕,下面进入关联规则可视化部分。  

2.4可视化  

  在关联规则中,归纳关联规则规律比较重要的图有三个,分别是散点图,分组矩阵图和graph图。下面,我们将会对这三种图进行一一阐述。    


2.4.1散点图   

  散点图表示了求出的强关联规则里支持度support和置信度confidence的分布,每个点颜色的深浅表示了提升度lift的大小.

 #载入arulesViz画图包
library(arulesViz)
#颜色包
library(RColorBrewer)
#如果想看交互图,可以设置interactive=TRUE,默认为FALSE
>plot(rules,control=list(jitter=2,col=rev(brewer.pal(9,"BrBG"))),shading="lift")

散点图.png

  从图中可以看出,关联规则的支持度support普遍偏低,confidence分布较为均匀,提升度的位置基本上都在百级,总体都远远大于3,表示出来的强规则均是有意义的。


2.4.2分组矩阵图  

  分组矩阵图将有共同点比较相近的规则聚成类,然后展示聚类规则的大体分布。默认是20类,这里将聚类个数设置为5.

>plot(rules,method="grouped",control=list(k=5,col=rev(brewer.pal(9,"YlOrRd")[3:8])))

分组矩阵图.png

   相似的关联规则分成一组,从而能够更深入地提取出关联规则的总体规律和重要规则共性。其中,横坐标代表被聚成的8类,且均是先导,纵坐标代表先导最后可能产生的10类后继,圆圈颜色的深浅表示提升度的大小,颜色越深,提升度越大;圆圈的大小表示支持度的大小,圆圈越大,支持度越大。


2.4.3graph图  

  最后,我们做出graph图。

>plot(Rule,method = "graph",measure = "confidence",
control = list(type="items"),shading = "lift")

graph图.png

  graph图中,源头表示先导,箭头表示关系指向的方向,中间的圆圈表示此规则置信度的大小,圆圈越大,置信度越大;圆圈颜色的深度表示提升度的大小,圆圈颜色越深,该规则提升度越大;箭头指向的尽头表示该规则的后继。观察关联规则因果图,可以直观地对重要的关联规则有一个初步的认识。   

  到此,关联规则的梳理就正式完毕。


三.总结  

  关联规则最开始被用于购物篮分析,在购物篮分析中,大家关心的都是items之间的关系,而并不会去关心每个项集对应的transactionID到底是谁。可随着关联规则被用于多种场景中,总会有场景会关心最后求出的关联规则背后的transactionID到底是什么,我现在做的业务就遇到了这么个情况。  在这里,我提出一个疑问,如何求出强关联规则背后对应的transactionID。

推荐 5
本文由 婷婷糖 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

3 个评论

好文,不错。
谢谢鼓励,我会一直努力下去的~
干货好文,够专业,推荐一下!

要回复文章请先登录注册