在用搜索引擎时,我们发现输入单词的一部分时,搜索引擎会自动补全查询词项,这里的原理其实是通过查询互联网上的词来找出经常出现在一块的词对,这需要一种高效发现频繁集的方法。
它基于Apriori构建,但在完成相同任务时采用了一些不同的技术。这里的任务是将数据集存储在一个特定的称作FP树的结构之后发现频繁项集或者频繁项对,即常在一块出现的元素项的集合FP树。这种做法使得算法的执行速度要快于Apriori,通常性能要好两个数量级以上。
注意:
这种算法虽然能更为高效地发现频繁项集,但不能用于发现关联规则。
FP-growth算法只需要对数据库进行两次扫描,而Apriori算法对于每个潜在的频繁项集都会扫描数据集判定给定模式是否频繁,因此FP-gr0wth算法的速度要比Apriori算法快。
FP-growth算法发现频繁项集的过程:
- 构建FP树
- 从FP树中挖掘频繁项集
1. 构建FP树
1.1 这里必须着重说下FP树,很重要!
- FP-growth算法将数据存储在一种称为FP树的紧凑数据结构中。FP代表频繁模式(Frequent Pattern)。一棵FP树看上去与计算机科学中的其他树结构类似,但是它通过链接(link)来连接相似元素,被连起来的元素项可以看成一个链表。
- 与搜索树不同的是,一个元素项可以在一棵FP树种出现多次。FP树会存储项集的出现频率,而每个项集会以路径的方式存储在数中。存在相似元素的集合会共享树的一部分。只有当集合之间完全不同时,树才会分叉。 树节点上给出集合中的单个元素及其在序列中的出现次数,路径会给出该序列的出现次数。
- 相似项之间的链接称为节点链接(node link),用于快速发现相似项的位置。
1.2 FP-growth算法的工作流程如下
首先构建FP树,然后利用它来挖掘频繁项集。为构建FP树,需要对原始数据集扫描两遍。第一遍对所有元素项的出现次数进行计数。数据库的第一遍扫描用来统计出现的频率,而第二遍扫描中只考虑那些频繁元素。
FP-growth算法还需要一个称为头指针表的数据结构,其实很简单,就是用来记录各个元素项的总出现次数的数组,再附带一个指针指向FP树中该元素项的第一个节点。这样每个元素项都构成一条单链表。
1.3 事务数据样例
代码:
运行结果:
以上就是FP树的构建过程,已经把具体流程打印出类了,一步一步对应上面带头指针表的图就可以搞清楚其中的细节了,具体解释参考《机器学习实战》。
这里我只想说,数据结构很重要!数据结构很重要!数据结构很重要!
python中frozenset( )的用法
2. 从FP树中挖掘频繁项
有了FP树之后,就可以抽取频繁项集了。这里的思路与Apriori算法大致类似,首先从单元素项集合开始,然后在此基础上逐步构建更大的集合。
从FP树中抽取频繁项集的三个基本步骤如下:
- 从FP树中获得条件模式基;
- 利用条件模式基,构建一个条件FP树;
- 迭代重复步骤1步骤2,直到树包含一个元素项为止。
其中关键是寻找条件模式基的过程,之后为每一个条件模式基创建对应的条件FP树。
2.1 抽取条件模式基
首先从头指针表中的每个频繁元素项开始,对每个元素项,获得其对应的条件模式基(conditional pattern base)。条件模式基是以所查找元素项为结尾的路径集合。每一条路径其实都是一条前缀路径(prefix path)。简而言之,一条前缀路径是介于所查找元素项与树根节点之间的所有内容。
前缀路径将在下一步中用于构建条件FP树,暂时先不考虑。如何发现某个频繁元素项的所在的路径?利用先前创建的头指针表和FP树中的相似元素节点指针,我们已经有了每个元素对应的单链表,因而可以直接获取。
在代码实现中:为给定元素项生成一个条件模式基(前缀路径),这通过访问树中所有包含给定元素项的节点来完成。
2.2 创建条件FP树
对于每一个频繁项,都要创建一棵条件FP树。可以使用刚才发现的条件模式基作为输入数据,并通过相同的建树代码来构建这些树。例如,对于r,即以“{x, s}: 1, {z, x, y}: 1, {z}: 1”为输入,调用函数createTree()获得r的条件FP树;对于t,输入是对应的条件模式基“{z, x, y, s}: 2, {z, x, y, r}: 1”,然后再递归地发现频繁项集,发现条件模式基,以及发现另外的条件树。
2.3 递归查找频繁项集
有了FP树和条件FP树,我们就可以在前两步的基础上递归得查找频繁项集。
完整代码:
运行结果:
上面是具体的过程。
补充:因为中间涉及到很多递归,所以具体的过程比较麻烦,这里举一个例子.
一行当basePat为’t’时的过程:
对照上面代码的运行结果可以帮助分析,没别的,就是数据结构的东西。
3. 从新闻网站点击流中挖掘新闻报道
书中的这两章有不少精彩的示例,这里只选取比较有代表性的一个——从新闻网站点击流中挖掘热门新闻报道。这是一个很大的数据集,有将近100万条记录(参见扩展阅读:kosarak)。在源数据集合保存在文件kosarak.dat中。该文件中的每一行包含某个用户浏览过的新闻报道。新闻报道被编码成整数,我们可以使用Apriori或FP-growth算法挖掘其中的频繁项集,查看那些新闻ID被用户大量观看到。
在2中的代码主函数部分改成如下:
运行结果:
同时也可以使用其他设置来查看运行结果,比如降低置信度级别。
总结:
- FP-growth算法是一种用于发现数据集中频繁模式的有效方法。FP-growth算法利用Apriori原则,执行更快。
- FP-growth算法还有一个map-reduce版本的实现,它也很不错,可以扩展到多台机器上运行。Google使用该算法通过遍历大量文本来发现频繁共现词,其做法和我们刚才介绍的例子非常类似。
4. 笔记
(1)Python 字典(Dictionary) get()方法:
Python 字典(Dictionary) get() 函数返回指定键的值,如果值不在字典中返回默认值。
get()方法语法: dict.get(key, default=None)
key – 字典中要查找的键
default – 如果指定键的值不存在时,返回该默认值值。
示例:
(2) 的用法:
(3)的用法:
(4)的用法: