Frequent Pattern 挖掘之二(FP Growth算法)(转)

FP树构造

FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对。为了达到这样的效果,它采用了一种简洁的数据结构,叫做frequent-pattern tree(频繁模式树)。下面就详细谈谈如何构造这个树,举例是最好的方法。请看下面这个例子:

这张表描述了一张商品交易清单,abcdefg代表商品,(ordered)frequent items这一列是把商品按照降序重新进行了排列,这个排序很重要,我们操作的所有项目必须按照这个顺序来,这个顺序的确定非常简单,只要对数据库进行一次扫描就可以得到这个顺序。由于那些非频繁的项目在整个挖掘中不起任何作用,因此在这一列中排除了这些非频繁项目。我们在这个例子中设置最小支持阈值(minimum support threshold)为3。

我们的目标是为整个商品交易清单构造一颗树。我们首先定义这颗树的根节点为null,然后我们开始扫描整个数据库的每一条记录开始构造FP树。

第一步:扫描数据库的第一个交易,也就是TID为100的交易。那么就会得到这颗树的第一个分支<(f:1),(c:1),(a:1),(m:1),(p:1)>。注意这个分支一定是要按照降频排列的。

第二步:扫描第二条交易记录(TID=200),我们会有这么一个频繁项目集合<f,c,a,b,m>。仔细观察这个队列,你会发现这个集合的前3项<f,c,a>与第一步产生的路径<f,c,a,m,p>的前三项是相同的,也就是说他们可以共享一个前缀。于是我们在第一步产生的路径的基础上,把<f,c,a>三个节点的数目加1,然后将<(b:1),(m:1)>作为一个分支加在(a:2)节点的后面,成为它的子节点。看下图:

第三步:接着扫描第三条交易记录(TID=300),你会看到这条记录的集合是<f, b>,与已存在的路径相比,只有f是共有的前缀,那么f节点加1,同时再为f节点生成一个新的字节点(b:1).就会有下图:

第四步:继续看第四条交易记录,它的集合是<c,b,p>,哦,这回不一样了。你会发现这个集合的第一个元素是c,与现存的已知路径的第一个节点f不一样,那就不用往下比了,没有任何公共前缀。直接将该集合作为根节点的子路径附加上去。就得到了下图(图1):

第五步:最后一条交易记录来了,你看到了一条集合<f,c,a,m,p>。你惊喜得发现这条路径和树现有最左边的路径竟然完全一样。那么,这整条路径都是公共前缀,那么这条路径上的所有点都加1好了。就得到了最终的图(图2)。

好了,一颗FP树就已经基本构建完成了。等等,还差一点。上述的树还差一点点就可以称之为一个完整的FP树啦。为了便于后边的树的遍历,我们为这棵树又增加了一个结构-头表,头表保存了所有的频繁项目,并且按照频率的降序排列,表中的每个项目包含一个节点链表,指向树中和它同名的节点。罗嗦了半天,可能还是不清楚,好吧直接上图,一看你就明白:

以上就是整个FP树构造的完整过程。聪明的读者一定不难根据上述例子归纳总结出FP树的构造算法。这里就不再赘述。

 

 

FP树的挖掘

 

下面就是最关键的了。我们已经有了一个非常简洁的数据结构,下一步的任务就是从这棵树里挖掘出我们所需要的频繁项目集合而不需要再访问数据库了。还是看上面的例子。

 

第一步:我们的挖掘从头表的最后一项p开始,那么一个明显的直接频繁集是(p:3)了。根据p的节点链表,它的2个节点存在于2条路径当中:路径<f:4,c:3,a:3,m:2,p:2>和路径<c:1,b:1,p:1>.从路径<f:4,c:3,a:3,m:2,p:2>我们可以看出包含p的路径<f,c,a,m,p>出现了2次,同时也会有<f,c,a>出现了3次,<f>出现了4次。但是我们只关注<f,c,a,m,p>,因为我们的目的是找出包含p的所有频繁集合。同样的道理我们可以得出<c,b,p>在数据库中出现了1次。于是,p就有2个前缀路径{(fcam:2),(cb:1)}。这两条前缀路径称之为p的子模式基(subpattern-base),也叫做p的条件模式基(之所以称之为条件模式基是因为这个子模式基是在p存在的前提条件下)。接下来我们再为这个条件子模式基构造一个p的条件FP树。再回忆一下上面FP树的构造算法,很容易得到下面这棵树:

但是由于频繁集的阈值是3。那么实际上这棵树经过剪枝之后只剩下一个分支(c:3),所以从这棵条件FP树上只能派生出一个频繁项目集{cp:3}.加上直接频繁集(p:3)就是最后的结果.

第二步:我们接下来开始挖掘头表中的倒数第二项m,同第一步一样,显然有一个直接的频繁集(m:3).再查看它在FP树中存在的两条路径<f:4,c:3,a:3,m:2>和<f:4,c:3,a:3,b1,m:1>.那么它的频繁条件子模式基就是{ (fca:2),(fcab:1)}.为这个子模式基构造FP树,同时舍弃不满足最小频繁阈值的分支b,那么其实在这棵FP树中只存在唯一的一个频繁路径<f:3,c:3,a:3>.既然这颗子FP树是存在的,并且不是一颗只有一个节点的特殊的树,我们就继续递归得挖掘这棵树.这棵子树是单路径的子树,我们可以简化写成mine(FP tree|m)=mine(<f:3,c:3,a:3>|m:3).

下面来阐述如何挖掘这颗FP子树,我们需要递归.递归子树也需要这么几个步骤:

1这颗FP子树的头表最后一个节点是a,结合递归前的节点m,那么我们就得到am的条件子模式基{(fc:3)},那么此子模式基构造的FP树(我们称之为m的子子树)实际上也是一颗单路径的树<f:3,c:3>,接下也继续继续递归挖掘子子树mine(<f:3,c:3>|am:3). (子子树的递归分析暂时打住.因为再分析子子树的递归的话文字就会显得太混乱)

2同样,FP子树头表的倒数第二个节点是c,结合递归前节点m,就有我们需要递归挖掘mine(<f:3>|cm:3).

3 FP子树的倒数第三个节点也是最后一个节点是f,结合递归前的m节点,实际上需要递归挖掘mine(null|fm:3),实际上呢这种情况下的递归就可以终止了,因为子树已经为空了.因此此情况下就可以返回频繁集合<fm:3>

注意:这三步其实还包含了它们直接的频繁子模式<am:3>,<cm:3>,<fm:3>,这在每一步递归调用mine<FPtree>都是一样的,就不再罗嗦得一一重新指明了.

实际上这就是一个很简单的递归过程,就不继续往下分析了,聪明的读者一定会根据上面的分析继续往下推导递归,就会得到下面的结果.

mine(<f:3,c:3>|am:3)=><cam:3>,<fam:3>,<fcam:3>

mine(<f:3>|cm:3)=><fcm:3>

mine(null|fm:3)=><fm:3>

这三步还都包含了各自直接的频繁子模式<am:3>,<cm:3>,<fm:3>.

最后再加上m的直接频繁子模式<m:3>,就是整个第二步挖掘m的最后的结果。请看下图:

第三步:来看看头表倒数第三位<b:3>的挖掘,它有三条路径<f:4,c:3,a:3,b:1>,<f:4,b:1>,<c:1,b:1>,形成的频繁条件子模式基为{(fca:1),(f:1),(c:1)},构建成的FP树中的所有节点的频率均小于3,那么FP树为空,结束递归.这一步得到的频繁集就只有直接频繁集合<b:3>

第四步:头表倒数第四位<a:3>,它有一条路径<f:4,c:3>,频繁条件子模式基为{(fc:3)},构成一个单路径的FP树.实际上可能有人早已经发现了,这种单路径的FP树挖掘其实根本不用递归这么麻烦,只要进行排列组合就可以直接组成最后的结果.实际上也确实如此.那么这一步最后的结果根据排列组合就有:{(fa:3),(ca:3),(fca:3),(a:3)}

第五步:头表的倒数第五位<c:4>,它只有一条路径<f:4>,频繁条件子模式基为{(f:3)},那么这一步的频繁集也就很明显了:{(fc:3),(c:4)}

第六步:头表的最后一位<f:4>,没有条件子模式基,那么只有一个直接频繁集{(f:4)}

这6步的结果加在一起,就得到我们所需要的所有频繁集.下图给出了每一步频繁条件模式基.

其实,通过上面的例子,估计早有人看出来了,这种单路径的FP树挖掘其实是有规律的,根本不用递归这么复杂的方法,通过排列组合可以直接生成.的确如此,Han Jiawei针对这种单路径的情况作了优化.如果一颗FP树有一个很长的单路径,我们将这棵FP树分成两个子树:一个子树是由原FP树的单路径部分组成,另外一颗子树由原FP树的除单路径之外的其余部分组成.对这两个子树分别进行FP Growth算法,然后对最后的结果进行组合就可可以了.

通过上面博主不厌其烦,孜孜不倦,略显罗嗦的分析,相信大家已经知道FP Growth算法的最终奥义.实际上该算法的背后的思想很简单,用一个简洁的数据结构把整个数据库进行FP挖掘所需要的信息都包含了进去,通过对数据结构的递归就可以完成整个频繁模式的挖掘.由于这个数据结构的size远远小于数据库,因此可以保存在内存中,那么挖掘速度就可以大大提高.

也许有人会问?如果这个数据库足够大,以至于构造的FP树大到无法完全保存在内存中,这该如何是好.这的确是个问题. Han Jiawei在论文中也给出了一种思路,就是通过将原来的大的数据库分区成几个小的数据库(这种小的数据库称之为投射数据库),对这几个小的数据库分别进行FP Growth算法.

还是拿上面的例子来说事,我们把包含p的所有数据库记录都单独存成一个数据库,我们称之为p-投射数据库,类似的m,b,a,c,f我们都可以生成相应的投射数据库,这些投射数据库构成的FP树相对而言大小就小得多,完全可以放在内存里.

转载于:https://www.cnblogs.com/xiaohua92/p/5516266.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 两个类之间传递数据

1、通过全局变量 2、通过构造函数传递参数 3、通过委托实现通过委托例子&#xff1a;WebForm1 向Class1传递参数值&#xff1a; // namespace WebApplication2{public partial class WebForm1 : System.Web.UI.Page{//step1.声明一个委托public delegate void DoSomethingEvent…

可行性研究课后题

题目: 为方便储户&#xff0c;某银行拟开发计算机储蓄管理系统。储户填写的存款单或取款单由银行柜台业务员键入系统&#xff0c;如果是存款&#xff0c;系统记录存款人姓名、住址、存款类型、存款日期、利息等信息&#xff0c;并印出存款单给储户;如果是取款&#xff0c;系统进…

jQuery语法

jQuery不是W3C标准&#xff01; jQuery使用CSS选择器来选取元素。 jQuery语法 一、jury语法是为HTML元素的选取编制的&#xff0c;可以对元素执行某些操作。 基础语法是&#xff1a;$(selector).action() .美元符号定义jQuery .选择符&#xff08;selector&#xff09;“查…

Sublime 解决目录显示为方块的问题

2019独角兽企业重金招聘Python工程师标准>>> 修改Perferences->Settings-User { "font_face": "Consolas Italic", #传说这个字体比较好看。 "font_size": 15, "ignored_packages": [ "Vintage" ], "dpi…

VS toolTip1控件的使用1

http://blog.csdn.net/Mr_Liyong/article/details/780141381、在工具栏找到“toolTip”控件后拖到窗体后&#xff0c;窗体下方会显示此控件则拖放成功。 2、单击此控件右键选择属性&#xff1a;开始 修改属性。 3、当添加一个TOOLTIP控件后&#xff0c;在WINFORM界面上所有的控…

python 代码片段9

#codingutf-8# 字符串指示符号 r表示raw u表示unicodemystringuthis is unicode!--by print mystring# raw表示告诉解释器不要转换字符串任何字符filerc:\temp\folder\robots.txt print file# 另一个实用raw的地方是正则表达式# 可以在内放任何的字符串&#xff0c;不需要转义&…

【TL】【编码】瞬间移动-百度之星初赛(Astar Round2B)1003-2016.05.22

瞬间移动 Accepts: 1018 Submissions: 3620Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description有一个无限大的矩形&#xff0c;初始时你在左上角&#xff08;即第一行第一列&#xff09;&#xff0c;每次你都可以选择一个…

蓝懿IOS委托模式代理模式

今天刘国斌老师讲了有关oc语言里的委托模式&#xff08;代理模式&#xff09;&#xff0c;通过了一个打地鼠的游戏讲解了委托模式的功能作用&#xff0c;之后连带讲解了协议的书写和使用。 打地鼠功能包括屏幕随机出现地鼠&#xff0c;点击消失&#xff0c;如果不点击5秒后自…

C#调用C++类(以COM组件的形式)

如果想用C#调用C/C写的函数&#xff0c;可以先将C/C的函数写成dll文件&#xff0c;由C#用DllImport的方式来调用&#xff0c;但是这种方法无法调用C写的类&#xff0c;如果想调用C类&#xff0c;可以先把C类封装成COM组件&#xff0c;再由C#来调用。方法如下&#xff08;以VS20…

Duplicate interface definition for class

在添加文件之后&#xff0c;报 Duplicate interface definition for class 原因是&#xff1a;重复添加文件 仔细检查检查

dom解析xml

为什么80%的码农都做不了架构师&#xff1f;>>> 转载自&#xff1a;http://www.cnblogs.com/shenliang123/archive/2012/05/11/2495252.html 使用eclipse需要手动导入crimson.jar包 org.w3c.dom(java dom)解析XML文档 位于org.w3c.dom操作XML会比较简单&#xff0c…

逃离北上广:你以为回到小城市就非常幸福了吗?

忘记在哪儿看的了。感觉不错&#xff0c;随手发出来。我博客也有更新&#xff0c;底下有留个人博客链接 在过去几年里。“逃离北上广”一直是一个热门短语。拿我自己来说&#xff0c;工作在上海&#xff0c;但又不是上海人。毕业后&#xff0c;就选择租房&#xff0c;首先就为这…

Redefinition of enumerator ios

添加文件之后 报 Redefinition of enumerator iOS 原因是&#xff1a;重复添加文件 仔细检查检查

[WinForm] VS2010发布、打包安装程序(超全超详细)

from: http://blog.csdn.net/y13156556538/article/details/555321841、 在vs2010 选择“新建项目”→“ 其他项目类型”→“ Visual Studio Installer→“安装项目”&#xff1a; &#xff08;如果是在solution中添加&#xff0c;就直接solution -- 右键 -- 添加project&#…

易货Beta版本发布说明

说明 由于前几天确实比较忙&#xff0c;所以没来得及写发布说明。 功能 我们在beta版本主要加入了以下几个功能&#xff1a; 一&#xff1a;增加了用户的发布界面 二&#xff1a;增加了用户的购买界面 三&#xff1a;使用下拉刷新取代了之前的handler后台更新 四&#xff1a;优…

【译】什么导致了Context泄露:Handler内部类

思考下面代码 1 public class SampleActivity extends Activity { 2 3 private final Handler mLeakyHandler new Handler() { 4 Override 5 public void handleMessage(Message msg) { 6 // ... 7 } 8 } 9 } 如果没有仔细观察&#xff0c;上面的代码…

js基础 one

js忽略空格符和换行符 js严格区分大小写 &#xff1b;为js的结束符 可以使用{}扩成一个语句组&#xff0c;形成一个block块 通过 \ 实现折行操作 document.write(hello \world); 通过document.write() 向文档书写内容 通过xonsole.log()向控制台写入内容变量 js变量重名会产…

关于.Net中Process和ProcessStartInfor的使用

System.Diagnostics.Process.Start(); 能做什么呢&#xff1f;它主要有以下几个功能&#xff1a;1、打开某个链接网址&#xff08;弹窗&#xff09;。2、定位打开某个文件目录。3、打开系统特殊文件夹&#xff0c;如“控制面板”等。那么它是怎么实现这几个功能的呢&#xff1f…

Sublime 的中文乱码问题

Sublime Text 是现在最受欢迎的文本编辑器&#xff0c;没有之一。它非常简洁&#xff0c;而且对各种代码的高亮显示很美观。但是&#xff0c;它默认不支持 GBK、Shift-JIS 等中文、日本编码格式&#xff0c;故打开此类文件会出现乱码。 安装 Package Control 首先要安装一个包控…

苹果应用上架遇到的问题(2017年4月27日)

在更新app store的时候报&#xff08;如图&#xff09;&#xff1a; ERROR ITMS-90086: "Missing 64-bit support. iOS apps submitted to the App Store must include 64-bit support and be built with the iOS 8 SDK or later. We recommend using the default "S…