基于关联规则的Apriori和FP-growth算法
一、算法/思路说明
1、 Apriori算法
Apriori算法:使用支持度来作为判断频繁项集的标准。
Apriori算法的目标是找到最大的K项频繁集。这里有两层意思,首先,要找到符合支持度标准的频繁集。但是这样的频繁集可能有很多。第二层意思就是我们要找到最大个数的频繁集。比如我们找到符合支持度的频繁集AB和ABE,那么我们会抛弃AB,只保留ABE,因为AB是2项频繁集,而ABE是3项频繁集。
Apriori算法采用了迭代的方法,先搜索出候选1项集及对应的支持度,剪枝去掉低于支持度的1项集,得到频繁1项集。然后对剩下的频繁1项集进行连接,得到候选的频繁2项集,筛选去掉低于支持度的候选频繁2项集,得到真正的频繁二项集,以此类推,迭代下去,直到无法找到频繁k+1项集为止,对应的频繁k项集的集合即为算法的输出结果。
算法流程:
输入:数据集合D ,支持度阈值α
输出:最大的频繁k项集
1)扫描整个数据集,得到所有出现过的数据,作为候选频繁1项集。k = 1 ,频繁0项集为空集。
2)挖掘频繁k项集
a) 扫描数据计算候选频繁k项集的支持度
b) 去除候选频繁k项集中支持度低于阈值的数据集,得到频繁k项集。如果得到的频繁k项集为空,则直接返回频繁k-1项集的集合作为算法结果,算法结束。如果得到的频繁k项集只有一项,则直接返回频繁k项集的集合作为算法结果,算法结束。
c) 基于频繁k项集,连接生成候选频繁k+1项集。
3) 令k = k + 1 k=k+1,转入步骤2。
从算法的步骤可以看出,Apriori算法每轮迭代都要扫描数据集,因此在数据集很大,数据种类很多的时候,算法效率很低。
算法总结:
Apriori算法是一个非常经典的频繁项集的挖掘算法,很多算法都是基于Apriori算法而产生的,包括FP-Tree,GSP, CBA等。这些算法利用了Apriori算法的思想,但是对算法做了改进,数据挖掘效率更好一些,因此现在一般很少直接用Apriori算法来挖掘数据了,但是理解Apriori算法是理解其它Apriori类算法的前提,同时算法本身也不复杂,因此值得好好研究一番。
2、FP算法
为了减少I/O次数,FP Tree算法引入了一些数据结构来临时存储数据。
这个数据结构包括三部分,第一部分是一个项头表。里面记录了所有的1项频繁集出现的次数,按照次数降序排列。比如上图中B在所有10组数据中出现了8次,因此排在第一位,这部分好理解。第二部分是FP Tree,它将我们的原始数据集映射到了内存中的一颗FP树,这个FP树比较难理解,它是怎么建立的呢?这个我们后面再讲。第三部分是节点链表。所有项头表里的1项频繁集都是一个节点链表的头,它依次指向FP树中该1项频繁集出现的位置。
算法流程:
FP Tree算法
1)扫描数据,得到所有频繁1项集的的计数。然后删除支持度低于阈值的项,将1项频繁集放入项头表,并按照支持度降序排列。
2)扫描数据,将读到的原始数据剔除非频繁1项集,并按照支持度降序排列。
3)读入排序后的数据集,插入FP树,插入时按照排序后的顺序,插入FP树中,排序靠前的节点是祖先节点,而靠后的是子孙节点。如果有共用的祖先,则对应的公用祖先节点计数加1。插入后,如果有新节点出现,则项头表对应的节点会通过节点链表链接上新节点。直到所有的数据都插入到FP树后,FP树的建立完成。
4)从项头表的底部项依次向上找到项头表项对应的条件模式基。从条件模式基递归挖掘得到项头表项项的频繁项集。
5)如果不限制频繁项集的项数,则返回步骤4所有的频繁项集,否则只返回满足项数要求的频繁项集。
算法总结:
FP Tree算法改进了Apriori算法的I/O瓶颈,巧妙的利用了树结构。利用内存数据结构以空间换时间是常用的提高算法运行时间瓶颈的办法。
在实践中,FP Tree算法是可以用于生产环境的关联算法,而Apriori算法则做为先驱,起着关联算法指明灯的作用。除了FP Tree,像GSP,CBA之类的算法都是Apriori派系的。
二、实验内容
如表 所示,数据库中有 7 个交易记录,设最小支持度计数为 3,分别使用 Apriori 和 FP 增长算法找出所有的频繁项集,并比较两种挖掘过程的效率。
交易 ID | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
购买商品 | {a,b,d,e} | {b,c,d} | {a,c,d,e} | {a,b,d,e} | {b,c,d,e} | {b,d,e} | {c,d} |
三、实验代码
//Apriori算法发现频繁项集
import sys
def apriori(D, minSup):
//频繁项集用keys表示,
//key表示项集中的某一项,
//cutKeys表示经过剪枝步的某k项集。
//C表示某k项集的每一项在事务数据库D中的支持计数
//:param D:
//:param minSup:
//:return:
C1 = {
}