上一篇我们讲了Apriori算法,Apriori算法之所以慢是因为每一次遍历都要重新查找所以的数据集,因此是时间复杂度非常高的算法。今天我们讲的FP-Growth 算法较 Apriori有一个数量级的提升。但 FP - Growth只能查找频繁组合,不能计算组合内部的关联规则。
FP - Growth的思路
接下来,让我们看一看FP - Growth的思路。
以上是程序的运行结果,FP-Growth的思路有两步,第一通过我们的数据构造一颗树,第二通过这颗树找出频繁组合。树的每一个节点由两部分构成。比如 apple:5
,前面是项目的名称,后面的5是在所有订单中出现的次数。
我们看一下具体流程:
先来看一个订单列表,每一行代表一个订单。
如何构建这棵树
一、首先,设定我们支持度的阈值是50%,将以上订单做一个筛选,去掉订单中低于50%的项目,我们要去掉那些支持度过低的项,一共有6个订单,所以符合条件的项目至少应该出现在3个以上的订单中,去除kiwifruit
pitaya
等这些支持度过低的项目。
这是筛选后的结果:
二、统计剩余项目每一个项目的支持度,也就是在所有订单中出现的总次数。
如:orange 3次
apple 5次
等等
三、 将每一个筛选后的订单按支持度由高到低进行排序,支持度相同的先随意给一个顺序。
如第一个订单,apple 出现5次,orange 3次,所以顺序为 apple orange
为了方便表示,我们将每一个项目的首字母取出,代表该项目,如 a 代表apple,o 代表orange ,上图的组合会有以下简写:
四、 建立FP - tree, (FP: Frequent Tree 频率树)
根节点,出现频率默认0
看一下我们下面构造的最终FP - Tree,左边的那个图跟上面的并不是完全对应,为什么呢,因为b、w、d都出现了3次,所以事实上排列是不确定的,要完全确定。我们需要给一个字典ID,第一次按频率排,而后同频率的按字典ID排。所以这只是一种情况的示例。
这颗树反映两个问题:
1.反映所有的事务里面有哪些出现的序列;
2.每一个节点上的数字代表在该序列出现的次数。
如何利用这颗树找频繁组合
我们看一下右上边的那张表:
表的第一行是缩写字:
c:combination 组合
p:prefix 前缀
s:support 满足支持度的前缀
c:代表由k - 1 项集组成k项集
在Apriori算法里面,我们是先找出所有组合的一项集,FP-Growth里面一样的,我们先找出所有组合的一项集,通过一项集找二项集,依次类推,直到空集。
我们这边选择了w为例,找其他组合也是一样的。对于w来说,它的任务就是寻找它的前缀。
首先,看第一行内容,寻找w的前缀,asdb和asob(每一个出现在w序列前面的项目我们都称之为w的前缀),注意第一个watermelon后面的数字被盖住了,它是2,它们出现的次数是2和1,这里面的关系是每一个w出现几次,它的前缀序列就出现几次,接下来我们要从前缀里面剔除支持度小于50%的项目,我们有6个订单,50%的话至少应该出现3次,a5次、s3次、b共3次,d两次,o一次,所以我们剔除d和o, 而满足支持度的组合是asb[2] 和asb[1] ,我们可以看成一个组合asb[3],因为w是频繁项集,asb也是频繁项集,所以我们可以将w与asb任意组合,形成新的二项集aw[3] ,sw[3],bw[