FP-growth算法挖掘频繁项集

概述

FP-growth算法基于Apriori构建,但在完成相同任务时采用了一些不同的技术。这里的任务是将数据集存储在一个特定的称作FP树的结构之后发现频繁项集或者频繁项对,即常在一块出现的元素项的集合FP树。这种做法使得算法的执行速度要快于Apriori,通常性能要好两个数量级以上。
FP-growth算法只需要对数据库进行两次扫描,而Apriori算法对每个潜在的频繁项集都会扫描数据集判定给定模式是否频繁,因此FP-growth算法的速度要比Apiori算法要快。Apriori算法的缺点是多次扫描数据库带来了巨大的IO开销,而FP-growth算法是典型的基于内存的算法,其优点是减少扫描次数来减少IO开销。
FP-growth发现频繁项集的基本过程如下:
(1)构建FP树
(2)从FP树中挖掘频繁项集

FP树的构建

这里写图片描述
FP树是一种前缀树,有点类似于Trie树但是每个节点有三个指针,分别指向parent,children和nodeLink。此外,算法中还包含有一个头指针表,头指针表中记录每个元素出现的第一个位置(结点),结点中的nodeLink将所有相同的元素连接起来。
第一遍扫描数据库的时候统计每个元素(单项集)出现次数。
第二遍扫描数据库的时候对于原来的每个数据,将数据中支持度小于阈值的元素删除,然后将这个数据按照刚才元素出现次数排序。排序后每个项集都有一个唯一的顺序,这样可以保证后续算法找出所有不重复的频繁项集。然后将这个数据插入到FP树中,并且更新头指针表和nodelink。

挖掘频繁项集

在挖掘频繁项集的时候,类似于Apriori算法,从单项集出发每次增加一个元素。对于每一个频繁项集,我们获得这个频繁项集作为结尾的所有前缀路径(起点为根节点),这些路径的集合称为条件模式基(conditional pattern base)。这里就用到了之前的nodeLink指针,我们可以获得当前所有以某个元素结尾的结点指针。
上面说了,FP-growth类似于Apriori算法,从单项集出发每次增加一个元素。FP-growth算法对于每一个频繁项集以前缀路径构造一棵FP树,然后向当前的频繁项集中添加一个元素,然后以深度优先的策略递归的进行这个过程知道发现所有频繁项集。

例子

考虑以下数据集
这里写图片描述

为了构造FP树,首先第一遍扫描数据计算所有单项集的支持度。然后将支持度大于阈值的单项集按照降序排列{ B(6), E(5), A(4), C(4), D(4) }.。
对于第一个数据BEAD,将它插入到FP树中,如下
这里写图片描述
对于第二个数据BEC,插入到FP树中,如下
这里写图片描述
将剩下的数据做相同的操作,最后得到初始的FP树
这里写图片描述

然后开始挖掘频繁项集
第一次调用的时候利用上面构造的初始树,第一步获得频繁项集{D, C, A, E,B},用深度优先的策略,以D为后缀的前缀路径构造一棵新的FP树,然后可以得到频繁项集{DA, DE,DB},然后这样递归下去,直到找到所有频繁项集{ DAE, DAEB, DAB, DEB, CE, CEB, CB, AE, AEB, AB, EB }。流程如下图所示
这里写图片描述

Python实现代码

from numpy 
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
我们可以通过一个简单的实例来了解FP-Growth算法挖掘频繁项集的过程。 假设我们有如下的交易数据集: ``` {A, B, C, D} {A, C, D} {B, C, E} {A, B, C, E} {B, E} ``` 我们希望找出其中的频繁项集,假设最小支持为2。 1. 构建项头表和FP 首先,我们需要构建项头表和FP。项头表用于存储每个项的出现次数和指向该项在FP中第一个出现位置的指针,FP用于存储数据集中的所有项和它们之间的关系。 项头表如下: ``` Item Count Header A 3 →Node(B) B 3 →Node(C) C 4 →Node(E) D 2 →Node(NULL) E 2 →Node(NULL) ``` 其中,Count表示项在数据集中的出现次数,Header表示项在FP中第一个出现的位置。 FP如下: ``` null | A(3) - C(3) - E(2) | | B(3) D(2) ``` 我们可以看出,FP中的每个节点代表一个项,节点上的数字表示该项在数据集中的出现次数,节点之间的连线表示它们在同一条交易路径上出现的顺序。 2. 构建条件模式基和条件FP 接下来,我们需要构建条件模式基和条件FP。对于每个频繁项,我们需要遍历FP中的所有路径,找出包含该频繁项的路径,并将路径上的所有非频繁项合并成一个条件模式基。然后,我们需要对每个条件模式基构建一棵条件FP。 以频繁项B为例,我们可以找出包含B的路径如下: ``` B -> A -> C -> E B -> A -> C -> D B -> E ``` 将路径上的非频繁项合并成一个条件模式基: ``` {A, C, E} {A, C, D} {E} ``` 然后,对于每个条件模式基,我们需要构建一棵条件FP。以{A, C, E}为例,它的条件FP如下: ``` null | A(1) - C(1) - E(1) ``` 我们可以看出,条件FP中只包含频繁项A、C和E,它们的出现次数分别为1、1和1。 同样地,我们可以得到其他频繁项的条件模式基和条件FP。 3. 递归挖掘频繁项集 接下来,我们需要递归地挖掘每个条件FP中的频繁项集。具体地,我们需要先从条件FP中获取所有频繁1项集,并生成相应的频繁项集。然后,根据这些频繁1项集,在条件FP中找出对应的条件模式基,并递归地生成更大的频繁项集。 以条件FP{A(1) - C(1) - E(1)}为例,它的频繁1项集为{A}、{C}和{E},因为它们的出现次数都大于等于2。 然后,我们可以根据这些频繁1项集,在条件模式基中找出对应的条件模式基,即{A, C, E}。对于这个条件模式基,我们可以构建一棵条件FP,如下: ``` null | A(1) - C(1) | E(1) ``` 然后,我们可以递归地挖掘这个条件FP,得到更大的频繁项集。在这个例子中,我们只能得到一个频繁2项集{A, C},因为它的出现次数大于等于2。 同样地,我们可以对其他条件FP递归地挖掘频繁项集。 4. 合并频繁项集 最后,我们可以将所有生成的频繁项集合并起来,得到完整的频繁项集。在这个例子中,所有的频繁项集如下: ``` {A} (3) {B} (3) {C} (4) {D} (2) {E} (2) {A, C} (2) {B, C} (3) {C, E} (2) {A, B, C} (2) {B, E} (2) {A, C, E} (2) ``` 其中,括号中的数字表示频繁项集在数据集中的出现次数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值