关联规则挖掘的原理和过程
从关联规则(一)的分析中可知,关联规则挖掘是从事务集合中挖掘出这样的关联规则:它的支持度和置信度大于最低阈值(minsup,minconf),这个阈值是由用户指定的。根据
support=(X,Y).count/T.count
confidence=(X,Y).count/X.count
要想找出满足条件的关联规则,首先必须找出这样的集合
F=X∪Y ,它满足
F.count/T.count≥minsup,其中
F.count是
T中包含
F的事务的个数,然后再从
F中找出这样的蕴含式
X→Y,它满足
(X,Y).count/X.count≥minconf,并且
X=F−Y。我们称像
F这样的集合称为频繁项目集,假如
F中的元素个数为
k,我们称这样的频繁项目集为
k−频繁项目集,它是项目集合
I的子集。所以关联规则挖掘可以大致分为两步:
- 从事务集合中找出频繁项目集;
- 从频繁项目集合中生成满足最低置信度的关联规则。
通俗的理解:
频繁项集所依赖的支持度其实就是覆盖率。
关联规则所依赖的可信度其实就是条件概率。
用于求解关联规则频繁项集的算法较为常用的有三种:
- Apriori
- FP-Growth
- Eclat
本章节主要介绍Apriori算法。
Apriori算法
最出名的关联规则挖掘算法是Apriori算法,它主要利用了向下封闭属性:如果一个项集是频繁项目集,那么它的非空子集必定是频繁项目集。它先生成1-频繁项目集,再利用1-频繁项目集生成2-频繁项目集。。。然后根据2-频繁项目集生成3-频繁项目集…依次类推,直至生成所有的频繁项目集,然后从频繁项目集中找出符合条件的关联规则。
下面来讨论一下频繁项目集的生成过程,它的原理是根据
k−频繁项目集生成
(k+1)−频繁项目集。因此首先要做的是找出
1−频繁项目集,这个很容易得到,只要循环扫描一次事务集合统计出项目集合中每个元素的支持度,然后根据设定的支持度阈值进行筛选,即可得到
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-频繁项目集…直至生成所有的频繁项目集。
生成频繁项集
生成一个频繁集的步骤分联合和剪枝两步。
- 联合(join),伪代码如下:
其中
Lk−1为频繁集。合并只有一个元素不同的
item,如(1,2,3)、(1,3,7)和(1,4,9),就会是(1,2,3)和(1,3,7)合并成(1,2,3,7),而不会其他的合并,因为其他情况,两元素有不只一个元素不同(为确保合并后的项集元素只增加了一个)。
- 剪枝(pruning)
合并后的集合,如果有子集不在原集合中,则把该合并集合删除。例如:有2-频繁项目集
{1,2},{1,3},{1,4},{2,3},{2,4}
因为
{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、⋯k个元素作为后件,该项目集中的其他元素作为前件,计算该规则的置信度进行筛选即可。这样的穷举效率显然很低。假如对于一个频繁项目集
f,可以生成下面这样的关联规则:
(f−β)→β
那么这条规则的置信度
confidence=f.count/(f−β).count
根据这个置信度计算公式可知,对于一个频繁项目集
f.count是不变的,而假设该规则是强关联规则,则
(f−βsub)→βsub也是强关联规则,其中
βsub是
β的子集,因为
(f−βsub).count肯定小于
(f−β).count。即给定一个频繁项目集
f,如果一条强关联规则的后件为
β,那么以
β的非空子集为后件的关联规则都是强关联规则。所以可以先生成所有的1-后件(后件只有一项)强关联规则,然后再生成2-后件强关联规则,依次类推(与生成频繁项集类似),直至生成所有的强关联规则。
一个例子
下面举例说明Apiori算法的具体流程:
假如有项目集合
I={1,2,3,4,5},有事务集
T:
t1:1,2,3
t2:1,2,4
t3:1,3,4
t4:1,2,3,5
t5:1,3,5
t6:2,4,5
t7:1,2,3,4
设定minsup=3/7,minconf=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,3)→2 的置信度不满足要求,所以剔除掉。因此得到1后件的集合
{1},
{3},然后再以
{1,3}作为后件。
2→(1,3) 的置信度=3/5不满足要求,所以对于3-频繁项目集生成的强关联规则为:
(1,2)→3和
(2,3)→1。
Apriori算法的优缺点
- 优点
Apriori算法采用了逐层搜索的迭代的方法,算法简单明了,没有复杂的理论推导,也易于实现。
- 缺点
- 对数据库的扫描次数过多,导致数据量大时速度很慢。
- Apriori算法会产生大量的中间项集(候选集)。
- 采用唯一支持度。
- 算法的适应面窄。
- 减少扫描数据库的次数(Partition算法、FP-growth算法)
- 减少候选集(Aprior已经减少了一部分candidates,但还有没有更快的方法)
- 怎样数这个candiates出现次数数的更快
参考文章:http://www.cnblogs.com/dolphin0520/archive/2012/10/29/2733356.html