频繁模式增长Frequent-Pattern Growth(FP-Growth)
文章目录
- 频繁模式增长Frequent-Pattern Growth(FP-Growth)
- 从DB构建一个FP树
- 挖掘FP树
- FP-Growth构建
频繁模式增长Frequent-Pattern Growth(FP-Growth)
由于Apriori算法的两大缺陷:
- 大量候选集问题
- 多次访问数据库
FP-Growth特点:
- 将代表频繁项集的数据库压缩成一棵频繁模式树
- 无候选集
- 只需两次访问数据库
从DB构建一个FP树
- 扫描DB,导出 频繁项集(1-项集)
- 将频繁项降序排列 ,创建出 项头表
- 再次扫描DB,构建FP树
事务信息表
TID | Item bought | frequent items(由大到小) |
---|---|---|
100 | { f , a , c , d , g , i , m , p } | { f , c , a , m , p} |
200 | { a , b , c , f , m , o } | { f ,c , a , m , p} |
300 | { b , f , h , j , o } | { f , b } |
400 | { b , c , k , s , p} | { c , b , p} |
500 | { a , f , c , e , l , p , m , n } | { f , c , a , m , p } |
最小支持度min_support
|
0.5 |
项头表
Item | frequency(降序) | head |
---|---|---|
f | 4 | |
c | 4 | |
a | 3 | |
b | 3 | |
m | 3 | |
p | 3 |
构造过程
挖掘FP树
mining:
- 项头表由底到顶挖掘
- 获取条件模式基(一个FP子树)
步骤Step : 设阀值为 2
step | operate(behavior) | Example |
---|---|---|
1 | 找到FP树的一个叶子结点 X | X=b |
2 | 对 X 所有的祖先节点计数 | ( f:2,c:1,a:1,b:2) |
3 | 删除低于阀值的计数 | ( f:2,b:2 ) |
4 | 可得到频繁K项集(K值为满足阀值节点数目) | ( f:2,b:2 ) |
5 | 满足阀值节点的组合就是频繁项集 (1-项集可直接得到) | { f,b} |
step | Example |
---|---|
1 | X=m |
2 | f:3,c:3,a:3,m:3,b:1 |
3 | f:3,c:3,a:3,m:3 |
4 | ( f:3,c:3,a:3,m:3 ) |
5 | { f , m } ,{ c,m } ,{ a,m } ,{ f,c,m } ,{ f,a,m },{ c,a,m },{ f,c,a,m } |
FP-Growth构建
# -*- coding: utf-8 -*-
"""
Created on Sat Jun 8 11:22:00 2019@author: ALVIN
"""
''' python基础知识
sorted()函数
:是一个高阶函数,它还可以接收一个key函数来实现自定义的排序
:例如按绝对值大小排序:sorted([36, 5, -12, 9, -21], key=abs)
:要进行反向排序,不必改动key函数,可以传入第三个参数reverse=True 。
:sorted(list, key=abs,reverse=True)lambda表达式
lambda 参数列表:表达式
lambda parm1,parm2,...,parmn : expressionlambda p:p[1],reverse = True'''
from numpy import *class treeNode:def __init__(self, nameValue, numOccur, parentNode):self.name = nameValue #结点名称self.count = numOccur #节点计数值self.nodeLink = None #用于链接相似的元素项self.parent = parentNode #needs to be updatedself.children = {} #子节点def inc(self,numOccur): #增加count数目self.count += numOccurdef disp(self,ind = 1):print(' '*ind,self.name,' ',self.count)for child in self.children.values():child.disp(ind+1)'''**********************************FP构建*************************************'''
#FP构建函数
#dataSet 事务集合 其中每一条都是一项事务(比如购买:小米耳机、华为手机、Ipad)
def createTree(dataSet,minSup = 1):#==============================项头表的构建===================================#项头表 事务中每一个项 出现的次数 # {} 是python的集合类型也可以是字典(这儿是字典)#---------------------项头表的构建(包含所有的项)------------------------------headerTable = {}for trans in dataSet:#trans 是一个事务for item in trans: #item 是事务中的单个项#记录每个元素项出现的频度headerTable[item] = headerTable.get(item,0) + dataSet[trans] ''' headerTable是key-value的形式:如下h 1r 3z 5'''#---------------------项头表的构建(删除不符合的项)----------------------------#!!字典迭代时候不能修改、删除for key in list(headerTable.keys()):if headerTable[key] < minSup:#将不满足最小支持度的删掉del(headerTable[key])#将项头表的所有项 放入集合freqItemSet = set(headerTable.keys())#判断是否存在满足最小支持度要求的(若没有则没有意义了)if len(freqItemSet) == 0:#不满足最小值支持度要求的除去return None,None#设置项投表标准格式 :由1到2# 1. key项 - value(出现次数 )# 2. key项 - value(出现次数 - 指向)for key in headerTable:headerTable[key] = [headerTable[key],None]#=====================项头表的构建完成=========================================#=====================FP树的构建==============================================retTree = treeNode('Null Set',1,None)#每次循环就会将一个事务的数据写入到FP-Growth树中#for循环多参数时候 in后的数据的一般需要 使用zip(data)#dataSet是字典类型 字典类型可以直接使用for循环的多参数方式for tranSet,count in dataSet.items():# test用 print(tranSet,count)# 打印结果:frozenset({'h', 'r', 'z', 'p', 'j'}) 1 ....localD = {}for item in tranSet:#判断item是否在频繁项集中if item in freqItemSet:#将每条事务中满足min_support的项用key-value的方式取出放入localD中localD[item] = headerTable[item][0]if len(localD) > 0:#将localD用出现次数(value)排序 并且放到 orderedItems之中orderedItems = [v[0] for v in sorted(localD.items(),key = lambda p:p[1],reverse = True)]#将排序后的item集合填充的树中updateTree(orderedItems,retTree,headerTable,count)#返回树型结构和头指针表return retTree,headerTable
#=====================FP树的构建完成==============================================#将排序后的item集合填充的树中(递归的方式)
#item 是满足min_support并且 使用频繁数目由大到小排序的 项 列表 如:['x', 'r', 's']
#inTree 是FP-Growth树的根
#headerTable 是项头表
#count是 ??? (感觉没什么必要)
def updateTree(items, inTree, headerTable, count):#判断第一个结点是否是null的子节点 就是说该节点已经存入if items[0] in inTree.children:#是 则该结点count加 1inTree.children[items[0]].inc(count) else:#创建一个结点 并设置为 Null 结点的子节点inTree.children[items[0]] = treeNode(items[0], count, inTree)#判断项头表的指向 是否已经设置if headerTable[items[0]][1] == None:#未设置则项头表的指向 设置为该节点headerTable[items[0]][1] = inTree.children[items[0]]else:#已设置则项头表的指向 添加到项头表的指向链的链尾#items[0] --> key headerTable[key] --> (value,linkNode)#headerTable[key][0] 代表值 headerTable[key][1] 代表指向updateHeader(headerTable[items[0]][1], inTree.children[items[0]])#判断 items 中不止一个 项if len(items) > 1:#递归操作updateTree(items[1::], inTree.children[items[0]], headerTable, count)#更新项头表的指向链,链表的尾插法
def updateHeader(nodeToTest, targetNode): while (nodeToTest.nodeLink != None):nodeToTest = nodeToTest.nodeLinknodeToTest.nodeLink = targetNode#加载测试数据
def loadSimpDat():simpDat = [['r', 'z', 'h', 'j', 'p'],['z', 'y', 'x', 'w', 'v', 'u', 't', 's'],['z'],['r', 'x', 'n', 'o', 's'],['y', 'r', 'x', 'z', 'q', 't', 'p'],['y', 'z', 'x', 'e', 'q', 's', 't', 'm']]return simpDat
#初始化事务集 使用字典的方式存储
def createInitSet(dataSet):retDict = {}for trans in dataSet:retDict[frozenset(trans)] = 1return retDict'''**********************************FP树挖掘***********************************'''#=====================抽取条件模式基=============================================
#迭代上溯整棵树 结合树来看:竖向)
#leafNode 开始向上迭代的叶子节点
#prefixPath 存储向上迭代路径节点的列表
def ascendTree(leafNode, prefixPath): if leafNode.parent != None:prefixPath.append(leafNode.name)ascendTree(leafNode.parent, prefixPath)#从项头表的指向开始 获取所有basePat的项的向上迭代的路径集合(结合树来看:横向)
#basePat 开始向上迭代的叶子节点
#treeNode 该节点对应项头表的指向
def findPrefixPath(basePat, treeNode): #treeNode comes from header tablecondPats = {}while treeNode != None:prefixPath = []#迭代上溯整棵树ascendTree(treeNode, prefixPath)if len(prefixPath) > 1: #不算上叶子节点 所以使用[1: ]的方式condPats[frozenset(prefixPath[1:])] = treeNode.counttreeNode = treeNode.nodeLink#使用Key-Value的方式存储 路径集合 与 对应的叶子节点计数return condPats#=====================递归查找频繁项集===========================================
#inTree :FP-Growth树
#headerTable:项头表 key(name):value(Frequent num,pointer)
#minSup:最小支持度要求
#preFix:????????????
#freqItemList:频繁项集列表
def mineTree(inTree, headerTable, minSup, preFix, freqItemList):#将headerTable.items()的key用出现次数(value)排序 并且放到 bigL 之中 (由小到大)# 1.排序头指针表bigL = [v[0] for v in sorted(headerTable.items(), key=lambda p: p[1][0])]#print(bigL)#从头指针表的底端开始for basePat in bigL:newFreqSet = preFix.copy()newFreqSet.add(basePat)#添加的频繁项列表freqItemList.append(newFreqSet)print ('finalFrequent Item: ',newFreqSet) condPattBases = findPrefixPath(basePat, headerTable[basePat][1])print ('condPattBases :',basePat, condPattBases)# 2.从条件模式基创建条件FP树myCondTree, myHead = createTree(condPattBases, minSup)# 3.挖掘条件FP树 if myHead != None: mineTree(myCondTree, myHead, minSup, newFreqSet, freqItemList)print ('\n\n') '''********************************** test ***********************************'''minSupport = 3
simpDat = loadSimpDat()
initSet = createInitSet(simpDat)myFPtree,myHeaderTab = createTree(initSet,minSupport)
print('-----------------------FP树:')
a = myFPtree.disp()
print('-----------------------项头表:')
lis = [v[0] for v in sorted(myHeaderTab.items(), key=lambda p: p[1][0])]
for k in lis:print(k,myHeaderTab[k][0])
print('-----------------------mining:')
myFreqList = []
mineTree(myFPtree, myHeaderTab, minSupport, set([]), myFreqList)
频繁模式增长Frequent-Pattern Growth(FP-Growth)相关推荐
- 频繁模式挖掘Frequent Pattern Mining
频繁模式挖掘(Frequent Pattern Mining): 频繁项集挖掘是通常是大规模数据分析的第一步,多年以来它都是数据挖掘领域的活跃研究主题.建议用户参考维基百科的association r ...
- 【数据挖掘笔记六】挖掘频繁模式、关联和相关性:基本概念和方法
6.挖掘频繁模式.关联和相关性:基本概念和方法 频繁模式(frequent pattern)是频繁地出现在数据集中的模式. 6.1 基本概念 频繁模式挖掘搜索给定数据集中反复出现的联系,旨在发现大型事 ...
- 频繁模式挖掘——概述
频繁模式挖掘(Frequent Pattern Mining) 基本概念 a. 频繁模式(frequent pattern)是频繁地出现在数据集中的模式(如项集.子序列或子结构). 例如: i. 频繁 ...
- 频繁模式(frequent pattern)
Datawhale 频繁模式(frequent pattern) 频繁模式一般是指频繁地出现在数据集中的模式.这种频繁模式和关联规则是数据挖掘中想要挖掘的知识. 我们都知道一个很有趣的故事,就是啤酒和 ...
- 浅谈数据挖掘——频繁模式、序列挖掘与搜索优化算法
本系列将从下面几方面谈谈最近的一点点收获 令声明:本文主要是对我找到的一个莫名其妙国外英文pdf文件的学习与解读,因为我也没有找到他的出处(也没作者也没学校),所以我仅以此段文字向这个未知的作者致敬. ...
- 挖掘频繁模式、关联和Apriori算法
挖掘频繁模式.关联和Apriori算法 1. 引入 1.1 基本概念 频繁模式:频繁出现在数据集中的模式 频繁模式挖掘:获取到给定数据集中反复出现的联系 注:模式其实可以理解为,你在淘宝购物,你的购物 ...
- apriori算法_挖掘频繁模式、关联和Apriori算法
挖掘频繁模式.关联和Apriori算法 1. 引入 1.1 基本概念 频繁模式:频繁出现在数据集中的模式 频繁模式挖掘:获取到给定数据集中反复出现的联系 注:模式其实可以理解为,你在淘宝购物,你的购物 ...
- 挖掘频繁模式、关联和相关性:基本概念和方法
基本概念 频繁模式挖掘搜索给定数据及中国反复出现的联系. 购物篮分析:一个例子 频繁项集.闭项集和关联规则 规则的支持度和置信度是规则兴趣度的两种度量. 一个例子: 支持度:支持度为2%,意味着分析的 ...
- Frequent Pattern 挖掘之二(FP Growth算法)(转)
FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达到这样的效果,它采用了一种简洁的数据结 ...
最新文章
- 苹果新的编程语言 Swift 语言进阶(三)--基本运算和扩展运算
- 如果你能用你的大脑控制电脑,感觉怎么样?
- python第三方库有哪些常用的、请列举15个-python基础面试常见题
- php 一个简单正则表达式,PHP中正则表达式回顾(3)--编写一个简单的正则表达式工具类...
- 关于异步IO与同步IO的写操作区别
- 冒泡排序 和 归并排序
- JQuery和php方面的填空题,PHP复习题(问答题)
- word整个表格首行缩进_Word排版对不齐?别忘了这个明星按键
- cadence 16.6中Z-copy的用法
- 贝叶斯信念网络Bayes Belief network
- 关于流(文件)的输入,输出与调用(fprintf,fscanf)
- 基于C++的Qt网络编程——聊天客户端
- 6000件数字藏品上线秒空!“国宝级”数字藏品长这样
- 软件测试中根据测试用例设计的方法,测试用例设计方法有哪些?举例说明
- chrome浏览器添加crx插件
- 交换机运维-排查用户反应网速卡的问题
- 黄河中下游地区精化似大地水准面研究与实施
- 中文转拼音开头以及五笔开头
- Spark(一)Spark介绍
- Win10自动宽带连接
热门文章
- django处理select下拉表单(从model到前端到post到form)
- opencv ppt效果_opencv几何图形画法
- grafana官方使用文档_5. Centos7 下部署使用 nmon2influxdb
- java字符串拼接_字符串拼接,什么时候会走StringBuilder?
- Php超出高度隐藏,html设置div最小高度,超出的自适应
- Centos7下安装python3
- C#编写程序监测某个文件夹内是否有文件进行了增,删,改的动作?
- 构建之法----软件工程简介
- [原创]java WEB学习笔记36:Java Bean 概述,及在JSP 中的使用,原理
- Smack+Openfire 接收和发送文件