FP-growth算法是一种高效发现频繁集的方法。例如你在搜索引擎中搜索一个词,它会自从补全查询词项,该处用到了FP-growth算法,通过查看互联网上的用词来找出经常在一块出现的词。【FP(Frequent Pattern)】
FP-growth算法基于Apriori算法,但是比Apriori算法执行速度快,通常性能要好两个数量级以上。FP-growth算法虽然能更高效地发现频繁项集,但是不能用于发现关联规则。
FP-growth算法将数据集存储在一个特定的FP树的结构之后发现频繁项集或频繁项对,即常在一块出现的元素项的集合FP树。FP-growth算法只需要对数据库进行两次扫描,而Apriori算法对于每个潜在的频繁项集都会扫描数据集判定给定模式是否频繁,因此FP-growth算法速度比Apriori算法快。
FP-growth发现频繁项集的过程如下:
(1)构建FP树
(2)从FP树中挖掘频繁项集
一、创建FP树的数据结构
FP树要比其他数更加复杂,因此要创建一个类来保存树的每一个节点。一个元素可以在一颗FP树中出现多次,FP树会存储项集的出现频率,每个项集会以路径的方式存储在树中,存在相似元素的集合会共享树的一部分,只有当集合之间完全不同时,树才会分叉。树节点上给出集合中的单个元素及其在序列中的出现次数,路径会给出该序列的出现次数。
二、创建PF树
创建FP树,需要对原始数据集扫描两遍。
(1)创建一个头指针表(字典型),保存每类元素的总数及指向每类元素第一个元素项的指针。头指针表数据结构:(元素:元素出现次数,相似元素指针)。利用头指针表可以快速访问FP树中一个给定类型的所有元素。
(2)第一次遍历数据集,获得每个元素项的出现频率,保存到头指针表中。
(3)遍历头指针表,去掉不满足最小支持度的元素。
(4)第二次遍历数据集,只考虑那些频繁项。将每个事务的频繁项抽取出来,并对频繁项进行降序排序,用排序后的频繁项来构建FP树。一条事务一条事务的往FP树中填充。排序原因是:只有排序后才有利于对FP树填充,因为假设有集合{z,x,y}和{y,z,r},那么FP树中相同项会只表示一次,都从z开始。
(5)怎么填充树,让树生长。对于每个事务(频繁项集),看第一个元素是否作为根节点的子节点存在,存在则计数增加,不存在则新建子节点,并更新头指针表该元素的指针。
(6)怎么更新头指针表的指针。如果指针为None,说明该元素第一次出现,将指针指向该节点元素,如果指针不为None,说明该元素已经出现过在其他子节点下面,这里第一次作为根节点的子节点,那么将指针沿着链表到尾部,使尾部节点指针指向这里的新节点。
(7)每条事务处理完第一个元素后,重复(5)和(6)将后面的元素按照该方法依次加入FP树中。
(8)将每条事务按照(5)(6)(7)的方法依次添加到FP树中。
最后得到的结果为:
三、从一颗FP树中挖掘频繁项集
基于FP树抽取频繁项集的思路与Apriori算法类似,首先从单个元素项集合开始,再逐步构建更大的集合。
(1)首先从FP树中获取条件模式基(conditional pattern base)。
从单个频繁元素开始。条件模式基是以所查找元素项为结尾的路径集合。每条路径都是一条前缀路径(prefix path),即介于所查找元素项与树根节点之间的所有内容,每条前缀路径都与一个计数值关联。所以,条件模式基就是前缀路径的集合。
获取条件模式基的方法是从头指针表(保存着单个频繁元素起始指针)开始,沿着相同类型元素链表向后找,直到链表为空为止。找到每一个相同类型元素就沿着FP树向上回溯,收集所有遇到的元素项名称。最后条件模式基的结果为:
(2)针对每一个频繁项,都要创建一颗条件FP树。
以条件模式基作为输入数据,通过创建FP树的方法创建条件FP树。这里只是输入数据不同,是以频繁项的条件模式基为输入数据的。创建完条件FP树的结果是得到以查找元素为前提的频繁项FP树和频繁项头指针表,再将这些频繁项FP树中的元素(如x,y)与查找元素(如t)组合构建更大的频繁项(如(x, t)和(y, t))。再在这颗条件FP树中沿着x(或y)发现条件模式基,比如又发现了z,那么又构成更大的频繁项(z, x, t),直到条件FP树没有元素为止。
以上只是从一个单元素频繁项开始发现更多的频繁项,接着要循环其他单元素项以发现更多更大的频繁项。