一只幻想飞翔的猪
硕士毕业于北京邮电大学-网络与交换技术国家重点实验室 现供职于国内某互联网一线阵地,从事推荐系统相关领域 研究领域:数据挖掘,机器学习,深度学习,强化学习,GNN,推荐系统

声明:

  机器学习系列主要记录自己学习机器学习算法过程中的一些参考和总结,其中有部分内容是借鉴参考书籍和参考博客的。

目录:

  1. 什么是关联规则
  2. 关联规则中的必须知道的概念
  3. 关联规则的实现过程
  4. 关联规则的核心点——如何生成频繁项集(Apriori算法)
  5. 关联规则的核心点——如何生成频繁项集(FP-Growth算法)
  6. 实际使用过程中需要注意的地方
  7. 关联规则总结与课后作业
  8. 参考文献

一、什么是关联规则

  所谓数据挖掘就是以某种方式分析源数据,从中发现一些潜在的有用的信息,即数据挖掘又可以称作知识发现。而机器学习算法则是这种“某种方式”,关联规则作为十大经典机器学习算法之一,因此搞懂关联规则(虽然目前使用的不多)自然有着很重要的意义。顾名思义,关联规则就是发现数据背后存在的某种规则或者联系。

  举个简单的例子(尿布和啤酒太经典):通过调研超市顾客购买的东西,可以发现30%的顾客会同时购买床单和枕套,而在购买床单的顾客中有80%的人购买了枕套,这就存在一种隐含的关系:床单→枕套,也就是说购买床单的顾客会有很大可能购买枕套,因此商场可以将床单和枕套放在同一个购物区,方便顾客购买。

  一般,关联规则可以应用的场景有:

    • 优化货架商品摆放或者优化邮寄商品的目录
    • 交叉销售或者捆绑销售
    • 搜索词推荐或者识别异常

 

二、概念

  • 项目:交易数据库中的一个字段,对超市的交易来说一般是指一次交易中的一个物品,如:牛奶
  • 事务:某个客户在一次交易中,发生的所有项目的集合:如{牛奶,面包,啤酒}
  • 项集:包含若干个项目的集合(一次事务中的),一般会大于0个
  • 支持度:项集{X,Y}在总项集中出现的概率(见下面的例子)
  • 频繁项集:某个项集的支持度大于设定阈值(人为设定或者根据数据分布和经验来设定),即称这个项集为频繁项集。
  • 置信度:在先决条件X发生的条件下,由关联规则{X->Y }推出Y的概率(见下面的例子)
  • 提升度:表示含有X的条件下同时含有Y的概率,与无论含不含X含有Y的概率之比。

  支持度和提升度示例

  假如有一条规则:牛肉—>鸡肉,那么同时购买牛肉和鸡肉的顾客比例是3/7,而购买牛肉的顾客当中也购买了鸡肉的顾客比例是3/4。这两个比例参数是很重要的衡量指标,它们在关联规则中称作支持度(support)和置信度(confidence)。对于规则:牛肉—>鸡肉,它的支持度为3/7,表示在所有顾客当中有3/7同时购买牛肉和鸡肉,其反应了同时购买牛肉和鸡肉的顾客在所有顾客当中的覆盖范围;它的置信度为3/4,表示在买了牛肉的顾客当中有3/4的人买了鸡肉,其反应了可预测的程度,即顾客买了牛肉的话有多大可能性买鸡肉。其实可以从统计学和集合的角度去看这个问题, 假如看作是概率问题,则可以把“顾客买了牛肉之后又多大可能性买鸡肉”看作是条件概率事件,而从集合的角度去看,可以看下面这幅图:

    上面这副图可以很好地描述这个问题,S表示所有的顾客,而A表示买了牛肉的顾客,B表示买了鸡肉的顾客,C表示既买了牛肉又买了鸡肉的顾客。那么C.count/S.count=3/7,C.count/A.count=3/4。  

  提升度示例

  1000名顾客,购买年货,A组有500人购买茶叶,有450人购买咖啡;B组有0人购买茶叶,有450人购买咖啡。

  购买茶叶 购买咖啡
A组(500人) 500   450
B组(500人) 0 450

  茶叶->咖啡的支持度=450/1000=45%

  茶叶->咖啡的置信度=450/500=90%

  茶叶->咖啡的提升度=90%/90%=1  

  说明:

  (1)由于lift(茶叶X->咖啡Y)=1,所以说明X与Y相互独立,即是否有X对于Y的出现没有影响。虽然支持度和置信度都高,但它们之间没有必然的关联关系。

  (2)满足最小支持度和最小置信度的关联关系叫做强关联关系

    • 如果lift>1,叫做有效的强关联关系,
    • 如果lift<=1,叫做无效的强关联关系
    • 特别的如果lift(X->Y)=1,则称X与Y相互独立

 

三、实现过程

  从以上的分析可以得知,关联规则是从事务集合中挖掘出这样的关联规则{X->Y}:它的支持度和置信度要大于最小阈值(minSup,minConf),当然这个最小阈值是由用户指定的,可以根据数据分布和经验;同时他的提升度最好是大于1的(具体值根据实际情况设定,例如:3、5均可),即是有效强关联规则。

  使用关联规则的过程主要包含以下三个步骤:

  (1)数据筛选,首先对数据进行清洗,清洗掉那些公共的项目,比如:热门词,通用词(此步依据具体项目而定)

  (2)根据支持度(support),从事务集合中找出频繁项集(使用算法:Apriori算法,FP-Growth算法) 

  (3)根据置信度(confidence),从频繁项集中找出强关联规则(置信度阈值需要根据实验或者经验而定)

  (4)根据提升度(lift),从强关联规则中筛选出有效的强关联规则(提升度的设定需要经过多次试验确定) 

 

四、如何生成频繁项集-Apriori算法[1]

  关联规则中,比较关键的两个点是:(1)三种阈值的设定(2)如何找出频繁项集。

  本节主要讨论如何解决寻找频繁项集的问题,目前主要有两种算法:(1)Apriori算法(2)FP-Growth算法,下面分别介绍一下这两种算法。

 (1)算法原理

  它主要利用了向下封闭属性:如果一个项集是频繁项目集,那么它的非空子集必定是频繁项目集。它先生成1-频繁项目集,再利用1-频繁项目集生成2-频繁项目集。。。然后根据2-频繁项目集生成3-频繁项目集。。。依次类推,直至生成所有的频繁项目集,然后从频繁项目集中找出符合条件的关联规则。    

 (2)生成频繁项集过程

  它的原理是根据k-频繁项目集生成(k+1)-频繁项目集。因此首先要做的是找出1-频繁项目集,这个很容易得到,只要循环扫描一次事务集合统计出项目集合中每个元素的支持度,然后根据设定的支持度阈值进行筛选,即可得到1-频繁项目集。下面证明一下为何可以通过k-频繁项目集生成(k+1)-频繁项目集:(下面证明如何从K-频繁项集生成k+1频繁项集

  假设某个项目集S={s1,s2...,sn}是频繁项目集,那么它的(n-1)非空子集{s1,s2,...sn-1},{s1,s2,...sn-2,sn}...{s2,s3,...sn}必定都是频繁项目集,通过观察,任何一个含有n个元素的集合A={a1,a2,...an},它的(n-1)非空子集必行包含两项{a1,a2,...an-2,an-1}和 {a1,a2,...an-2,an},对比这两个子集可以发现,它们的前(n-2)项是相同的,它们的并集就是集合A。对于2-频繁项目集,它的所有1非空子集也必定是频繁项目集,那么根据上面的性质,对于2-频繁项目集中的任一个,在1-频繁项目集中必定存在2个集合的并集与它相同。因此在所有的1-频繁项目集中找出只有最后一项不同的集合,将其合并,即可得到所有的包含2个元素的项目集,得到的这些包含2个元素的项目集不一定都是频繁项目集,所以需要进行剪枝。剪枝的办法是看它的所有1非空子集是否在1-频繁项目集中,如果存在1非空子集不在1-频繁项目集中,则将该2项目集剔除。经过该步骤之后,剩下的则全是频繁项目集,即2-频繁项目集。依次类推,可以生成3-频繁项目集。。直至生成所有的频繁项目集。

 (3)生成强关联规则

  得到频繁项目集之后,则需要从频繁项目集中找出符合条件的关联规则。最简单的办法是:遍历所有的频繁项目集,然后从每个项目集中依次取1、2、...k个元素作为后件,该项目集中的其他元素作为前件,计算该规则的置信度进行筛选即可。这样的穷举效率显然很低。假如对于一个频繁项目集f,可以生成下面这样的关联规则:(f-β)—>β,那么这条规则的置信度=f.count/(f-β).count

  (下面证明如何生成强关联规则,即先生成小后件的,再根据小后件依次生成大后件,因为假设该规则是强关联规则,则(f-βsub)—>βsub也是强关联规则

  根据这个置信度计算公式可知,对于一个频繁项目集f.count是不变的,而假设该规则是强关联规则,则(f-βsub)—>βsub也是强关联规则,其中βsub是β的子集,因为(f-βsub).count肯定小于(f-β).count。即给定一个频繁项目集f,如果一条强关联规则的后件为β,那么以β的非空子集为后件的关联规则都是强关联规则。所以可以先生成所有的1-后件(后件只有一项)强关联规则,然后再生成2-后件强关联规则,依次类推,直至生成所有的强关联规则。

 (4)举例说明

  下面举例说明Apiori算法的具体流程:

  假如有项目集合I={1,2,3,4,5},有事务集T:

1,2,3
1,2,4
1,3,4
1,2,3,5
1,3,5
2,4,5
1,2,3,4

  设定minsup=3/7,misconf=5/7。

  首先:生成频繁项目集:

  1-频繁项目集:{1},{2},{3},{4},{5}

  2-频繁项目集:

    根据1-频繁项目集生成所有的包含2个元素的项目集:任意取两个只有最后一个元素不同的1-频繁项目集,求其并集,由于每个1-频繁项目集元素只有一个,所以生成的项目集如下:

      {1,2},{1,3},{1,4},{1,5}

      {2,3},{2,4},{2,5}

      {3,4},{3,5}

      {4,5}

    计算它们的支持度,发现只有{1,2},{1,3},{1,4},{2,3},{2,4},{2,5}的支持度满足要求,因此求得2-频繁项目集:

      {1,2},{1,3},{1,4},{2,3},{2,4}

  3-频繁项目集:

    因为{1,2},{1,3},{1,4}除了最后一个元素以外都相同,所以求{1,2},{1,3}的并集得到{1,2,3}, {1,2}和{1,4}的并集得到{1,2,4},{1,3}和{1,4}的并集得到{1,3,4}。但是由于{1,3,4}的子集{3,4}不在2-频繁项目集中,所以需要把{1,3,4}剔除掉。然后再来计算{1,2,3}和{1,2,4}的支持度,发现{1,2,3}的支持度为3/7 ,{1,2,4}的支持度为2/7,所以需要把{1,2,4}剔除。同理可以对{2,3},{2,4}求并集得到{2,3,4} ,但是{2,3,4}的支持度不满足要求,所以需要剔除掉。

    因此得到3-频繁项目集:{1,2,3}。

    到此频繁项目集生成过程结束。注意生成频繁项目集的时候,频繁项目集中的元素个数最大值为事务集中事务中含有的最大元素个数,即若事务集中事务包含的最大元素个数为k,那么最多能生成k-频繁项目集,这个原因很简单,因为事务集合中的所有事务都不包含(k+1)个元素,所以不可能存在(k+1)-频繁项目集。在生成过程中,若得到的频繁项目集个数小于2,生成过程也可以结束了。

  现在需要生成强关联规则

  这里只说明3-频繁项目集生成关联规则的过程:对于集合{1,2,3}

  1-后件的关联规则:

      (1,2)—>3,   置信度=3/4

      (1,3)—>2, 置信度=3/5(置信度不满足要求,所以剔除掉)

      (2,3)—>1      置信度=3/3

       因此得到1后件的集合{1},{3}

  2-后件的关联规则(根据1-后件集合) 

    2—>1,3       置信度=3/5不满足要求,所以对于3-频繁项目集生成的强关联规则为:(1,2)—>3和(2,3)—>1。

  至此,Apriori算法完成

  (当然实际项目中还需要去验证生成的强关联规则是否满足提升度要求,即是否是有效强关联规则)。

 

五、如何生成频繁项集-FP-Growth算法[4]

  Apriori算法是关联规则的基本算法,很多用于发现关联规则的算法都是基于Apriori算法,但Apriori算法需要多次访问数据库,具有严重的性能问题。FP-Growth算法只需要两次扫描数据库,相比于Apriori减少了I/O操作,克服了Apriori算法需要多次扫描数据库的问题。本文采用如下的样例数据

 

        A;B;E;
	B;D;
	B;C;
	A;B;D
	A;C;
	B;C;
	A;C;
	A;B;C;E;
	A;B;C;    

 

 (1)FP-Growth生成FP-Tree

 

  FP-Growth算法将数据库中的频繁项集压缩到一颗频繁模式树中,同时保持了频繁项集之间的关联关系。通过对该频繁模式树挖掘,得到频繁项集。其过程如下:

 

  1. 第一次扫描数据库,产生频繁1项集,并对产生的频繁项集按照频数降序排列,并剪枝支持数低于阀值的元素。处理后得到L集合,
  2. 第二次扫描数据库,对数据库的每个交易事务中的项按照L集合中项出现的顺序排序,生成FP-Tree(图5.1)。

 

image图5.1 FT-Tree

image

图5.2  生成fp-tree的步骤

 

(2)从FP-Tree挖掘频繁项集

 

  从FP-Tree重可以挖掘出频繁项集,其过程如下:

 

image

 图5.3  频繁项集挖掘过程

  从频繁1项集链表中按照逆序开始,链表可以追溯到每个具有相同项的节点。

  1. 从链表中找到项“E”,追溯出FP-Tree中有两个带“E”的节点,由这两个节点分别向上(parent)追溯,形成两条模式:<E,C,A,B;1>,<E,A,B;1>.
  2. 由这两条模式得到项“E”的条件模式<A,B;2>.
  3. 根据条件模式,得到项“E”的频繁项集(不包含频繁1项集):<E,A;2>,<E,B;2>,<E,A,B;2>
  4. 然后一次得到项“D”,“C”,“A”。

(3)找出强关联规则

  同第四节

(4)找出有效的强关联规则

  同第四节

 

  至此,FP-Growth算法生成频繁项集已经结束。

 

 

六、注意点

  (1)三个阈值点需要经过对此实验或者经验才能找到合适的阈值

  (2)关联规则与word2vec在哪些场景有着共性和不同需要验证(需要研究word2vec实现原理后再下结论)

  (3)数据集需要某些处理后,也许效果会有提升(同事的经验)

 

七、总结

  第一次,“摘抄”整理别人的博客来放在自己的博客,算是一个小小的开始的,其实很多东西只有自己去真正的学习,思考,整理才有收获。

  机器学习算法与模型是一个很有意思的东西,很多东西不去看自己完全想象不到还能这么玩,然而看了就是看了,跟用了还是有很大差别,希望以后能够在工作中将自己看的一些东西用上去,多整理,这样效果会比较好。

  虽然我是一个从网络方向转过来的“出家”人,但是这都不是事。我觉得看的多了,整理的多了,其实学起来还是有套路可以遵循的。

 

八、参考文献

[1]http://www.cnblogs.com/dolphin0520/archive/2012/10/29/2733356.html

[2]http://blog.sina.com.cn/s/blog_4d8d6303010009kb.html

[3]http://www.360doc.com/content/15/0611/19/25802092_477451393.shtml

[4]http://westerly-lzh.github.io/cn/2015/08/DM002-FP-Tree/

[5]http://www.bjt.name/2013/09/association-rules

[6]http://blog.csdn.net/rav009/article/details/8985322

[7]http://blog.csdn.net/rav009/article/details/8979249

posted on 2016-10-22 16:39  Pindy  阅读(12192)  评论(0编辑  收藏  举报