使用 FP-growth 算法来高效发现频繁项集

在我们日常生活中,使用搜索引擎时,输入一个单词或者单词的一部分,就会自动补全查询词项

FP-growth算法,不同于Apriori算法生成候选项集再检查是否频繁的”产生-测试“方法,但是基于Apriori构建,但在完成相同任务时采用了一些不同的技术.这里的任务是将数据集存储在一个特定的称作FP树的结构之后发现频繁项集或频繁项对,即常在一块出现的元素项的集合FP树.这种做法是的算法的执行速度要快于Apriori,通常性能要好两个数量级以上.

FP-growth 算法是一种用于发现数据集中频繁模式的有效方法,利用Apriori 原理,只对数据集扫描两次,运行更快。在算法中,数据集存储在 FP 树中,构建完树后,通过查找元素项的条件基及构建条件 FP 树来发现频繁项集。重复进行直到FP树只包含一个元素为止。

优点:一般要快于 Apriori 算法。

缺点:实现比较困难,在某些数据集上性能会下降。

适用数据类型:离散型数据。

应用领域:在多种文本文档中查找频繁单词;购物交易;医学诊断;大气研究等。

一、FpTree
FP代表频繁模式(Frequent Pattern)。一棵FP树看上去与[计算机科学中的其他树结构类似,但是它通过链接(link)来连接相似元素,被连起来的元素项可以看成一个链表。

FP树看上去就是一棵前缀树,根节点是空集,结点上是单个元素,保存了它在数据集中的出现次数,出现次数越多的元素越接近根。此外,结点之间通过链接(link)相连,只有相似元素会被连起来,连起来的元素又可以看成链表。同一个元素可以在FP树中多次出现,根据位置不同,对应着不同的频繁项集。可以为FP树设置最小支持度,过滤掉出现次数太少的元素。
下面这个数据集构造FP树如下图所示。



假设最下支持度为3,即低于3的元素项被认为是不频繁的,不会出现在树中,例如p,q


这棵树每个结点上都是一个单独的元素,及其在路径中的出现次数,例如"z:5"表示集合{z}出现了5次,而"x:3"表示集合{z,x}出现了3次,这是路径相关的。

FP-growth算法的工作流程:首先构建FP树,然后利用它来挖掘频繁项集。为构建FP树,需要对原始数据集扫描两遍。第一遍对所有元素项的出现次数进行计数。数据库的第一遍扫描用来统计出现的频率,而第二遍扫描中只考虑那些频繁元素。

FP-growth算法还需要一个称为头指针表的数据结构,其实很简单,就是用来记录各个元素项的总出现次数的数组,再附带一个指针指向FP树中该元素项的第一个节点。这样每个元素项都构成一条单链表。这个header除了指向指定元素的第一个结点外,还可以保存该元素在数据集中的总出现次数。

这里使用Python字典作为数据结构,来保存头指针表。以元素项名称为键,保存出现的总次数和一个指向第一个相似元素项的指针。

首先,遍历一次数据集,统计每个元素出现的次数,然后把出现次数较小的滤掉(例如选取最小支持度3,将出现次数小于3的元素滤除),然后对每个样本按照元素出现次数重排序。上面给出的数据集样例中,出现次数不小于3的元素有:z、r、x、y、s、t,滤除并重排后的样本如下所示。

元素项排序:FP树会合并相同的频繁项集(或相同的部分)。因此为判断两个项集的相似程度需要对项集中的元素进行排序(不过原因也不仅如此,还有其它好处)。排序基于元素项的绝对出现频率(总的出现次数)来进行。在第二次遍历数据集时,会读入每个项集(读取),去掉不满足最小支持度的元素项(过滤),然后对元素进行排序(重排序)。

对示例数据集进行过滤和重排序的结果如下:


二、构造fp树
在对事务记录过滤和排序之后,就可以构建FP树了。从根节点∅开始,将过滤并排序后的样本一个个加入树中,若FP树不存在现有元素则添加分支,若存在则增加相应的值。如果现有元素不存在,则向树添加一个分支。下图给出了从根节点∅开始依次添加三个样本(过滤且排序)后FP的情况。


那么对于单个样本,FP树应该怎么生长呢?自然而然地想到递归。因为每个样本都是排序过的,频数高的频繁项集在前面,它总是更接近根结点,所以也可以把每个样本看成一棵子树,而我们要做的就是把子树添加到FP树里。因此每次只需判断第一个结点是否是根的儿子,若是则增加计数,若不是则增加分枝,然后递归调用构造FP树,传入第二个元素开始的子树即可。比如上例中往根节点∅增加样本(z,r)时,根没有z这个儿子,因此增加分支z。接着,只需递归地构造FP树,传入(r),发现当前FP树∅-z也没有r这个儿子,因此增加分支r。最终递归返回,引入样本(z,r)后构造的FP树就是∅-z-r。

下图详细地描述了这个过程,代码中updateFPtree()函数实现了这个功能。



三、从FP树提取条件模式基
条件模式基(conditional pattern base)定义为以所查找元素为结尾的所有前缀路径(prefix path)的集合。我们要做的就是从header列表开始,针对每一个频繁项,都查找其对应的条件模式基。举个例子,如下图所示,元素"r"的前缀路径是{z}、{z,x,y}和{x,s}。同时,每一个路径要与起始元素的计数值关联,该计数值等于起始元素项的计数值,该计数值给了每条路径上r的数目。



下面为每一个频繁项的所有前缀路径。

四、创建条件FP树
对每一个频繁项,都建立一棵条件FP树。上面我们对每一个频繁项提取了条件模式基,现在就用它作为输入数据,即把每一个前缀路径当成一个样本,调用createFPtree()构造一棵FP树,即条件FP树。然后,对这个条件FP树,递归地挖掘。由于createFPtree()中含有过滤的功能,因此最终总能获得所有满足最小支持度的频繁项,即我们所需要的频繁项集。


重复进行,直到条件数中没有元素为止。

五、实例(上述的Python实现)
导入数据库中的数据

import fpGrowth
simpDat=fpGrowth.loadSimpDat()
simpDat

为了createTree函数,对上面数据进行格式化处理

initSet = fpGrowth.createInitSet(simDat)
initSet

创建FP树

myFPtree, myHeaderTab = fpGrowth.createTree(initSet, 3)

给出树的文本表示结果

myFPtree.disp()

提取条件模式基

fpGrowth.findPrefixPath('z', myHeaderTab['z'][1]),fpGrowth.findPrefixPath('r', myHeaderTab['r'][1]),fpGrowth.findPrefixPath('x', myHeaderTab['x'][1])

生成条件树

freqItems = [] #建立空列表,存储所有频繁项集
fpGrowth.mineTree(myFPtree, myHeaderTab, 3, set([]), freqItems)

检查一下返回的项集是否与条件树相匹配

freqItems

显示相匹配

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358

推荐阅读更多精彩内容