FP-Growth算法是这里要介绍的第三个非监督学习算法,FP(Frequent Pattern)代表频繁模式。FP-Growth算法相对于Apriori算法来说效率更高,其只需要对数据集进行两轮扫描即可发现频繁项集,而Apriori却做不到。通常情况,FP-Growth会比Apriori快两个数量级。但FP-Growth只能发现频繁项集,不能发现关联规则。

FP-Growth发现频繁项集的过程包括构建FP树从FP树中找出频繁项集两个部分。

本节包含以下内容:

  1. 构建FP树
  2. 从FP树中发现频繁项集

部分内容引用自《Machine Learning in Action》


构建FP树

FP树和一般的树没有太大的差别,如下图所示:

树的根节点为空,其它节点包含一个节点名称(这里是英文字母)和对应的出现次数,相同节点名称之间还有一个指针链接,这样可以容易找到相同的节点。

下面数据集可对应于上面的FP树,注意,这里将最小支持度设定为3,所以出现次数小鱼3的元素将不会出现在FP树中,例如q,p等,

通过FP树可以看出,(t,s,y,x,z)出现了两次(因为叶子节点 t 的值为2),在数据集中可以找到对应的TID是002和006。(z)出现了5次,分别为(r,z)一次,(t,s,y,x,z)两次,(t,r,y,x,z)一次,(z)一次。

为了便于计算,我们还需要一个头指针表用来指向给定类型的第一个实例,

构建FP树的过程是,先计算数据集中的每个元素出现的频率,如果元素不满足最小支持度,则删掉此元素。然后对每个子集中的元素,按照元素出现的次数排序,例如:

然后开始构建FP树,从空树开始,不断增加FP树(让其生长),如果树中已经存在现有元素,则增加值,否则向树中增加一个分支,例如:

下面通过python代码来实现构建FP树的过程,创建模块 fp_tree.py,并输入以下代码:

class tree_node:def __init__(self, name, num_occur, parent_node):self.name = nameself.count = num_occurself.node_link = Noneself.parent = parent_nodeself.children = {}def inc(self, num_occur):self.count += num_occurdef disp(self, ind=1):print("%r%r%r%r" % ('  ' * ind, self.name, ' ', self.count))for child in self.children.values():child.disp(ind + 1)def create_tree(data_set, min_sup=1):header_table = {}for trans in data_set:for item in trans:header_table[item] = header_table.get(item, 0) + data_set[trans]for k in list(header_table.keys()):if header_table[k] < min_sup:header_table.pop(k)freq_item_set = set(header_table.keys())if len(freq_item_set) == 0: return None, Nonefor k in header_table:header_table[k] = [header_table[k], None]ret_tree = tree_node('Null Set', 1, None)for tran_set, count in data_set.items():local_dataset = {}for item in tran_set:if item in freq_item_set:local_dataset[item] = header_table[item][0]if len(local_dataset) > 0:ordered_items = [v[0] for v in sorted(local_dataset.items(), key=lambda p: p[1], reverse=True)]update_tree(ordered_items, ret_tree, header_table, count)return ret_tree, header_tabledef update_tree(items, in_tree, header_table, count):if items[0] in in_tree.children:in_tree.children[items[0]].inc(count)else:in_tree.children[items[0]] = tree_node(items[0], count, in_tree)if header_table[items[0]][1] == None:header_table[items[0]][1] = in_tree.children[items[0]]else:update_header(header_table[items[0]][1], in_tree.children[items[0]])if len(items) > 1:update_tree(items[1::], in_tree.children[items[0]], header_table, count)def update_header(node_to_test, target_node):while (node_to_test.node_link != None):node_to_test = node_to_test.node_linknode_to_test.node_link = target_nodedef load_simp_dat():simp_data = [['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 simp_datadef create_init_set(data_set):ret_dict = {}for trans in data_set:ret_dict[frozenset(trans)] = 1return ret_dictif __name__ == '__main__':data = create_init_set(load_simp_dat())tree, table = create_tree(data, min_sup=3)print("Head table:")print(table)print("FP Tree:")tree.disp()freqItems = []

运行结果:

D:\work\python_workspace\machine_learning\venv\Scripts\python.exe D:/work/python_workspace/machine_learning/fp_growth/fp_tree.py
Head table:
{'r': [3, <__main__.tree_node object at 0x00000000027E45E0>], 'z': [5, <__main__.tree_node object at 0x00000000026B0CD0>], 't': [3, <__main__.tree_node object at 0x00000000027C8340>], 'y': [3, <__main__.tree_node object at 0x00000000027C8280>], 's': [3, <__main__.tree_node object at 0x00000000027C8130>], 'x': [4, <__main__.tree_node object at 0x00000000027C8460>]}
FP Tree:
'  ''Null Set'' '1
'    ''z'' '5
'      ''r'' '1
'      ''x'' '3
'        ''t'' '3
'          ''y'' '3
'            ''s'' '2
'            ''r'' '1
'    ''x'' '1
'      ''s'' '1
'        ''r'' '1Process finished with exit code 0

注意,输出结果的FP树和上面示例中的树在结构上有一点差异,但本质上还是同一棵树。

从FP树中发现频繁项集

从FP树中发现频繁项集包含下面三个步骤:

  1. 从FP树中获取条件模式基
  2. 利用条件模式基构建一个条件FP树
  3. 迭代重复步骤1和步骤2,直到树包含一个元素为止

条件模式基

条件模式基是以所有查询元素项为结尾的路径集合。每一条路径都是一条前缀路径,例如:

发现条件模式基并不困难,通过头指针表即可遍历出路径上的元素。例如元素t,首先通过头指针表找到第一个元素 t 在FP树中的位置,然后向上遍历到根节点可找到一个条件模式基(z,x,y,s),接着找到第一个 t 的链接,再向上遍历即可得到第二个条件模式基(z,x,y,r),条件模式基的数值就是当前节点的数值。

创建条件FP树

对于每一个频繁项,都要创建一个条件FP树。例如,假定为频繁项 t 创建一个条件FP树,首先会得到(t,x),(t,y),(t,z),

由于s和r不满足最小支持度3,因此需要去掉,可以看出(t,s)和(t,r)的组合并不满足最小支持度,虽然单独的s或t都满足最小支持度3。得到(t,z),(t,y),(t,x)以后,需要进一步挖掘对应的条件树,这会产生更多复杂的频繁项。

下面通过python代码来实现,创建模块 frequent_items.py,并输入以下代码:

import fp_growth.fp_tree as fp_treedef ascend_tree(leaf_node, pre_fix_path):if leaf_node.parent != None:pre_fix_path.append(leaf_node.name)ascend_tree(leaf_node.parent, pre_fix_path)def find_pre_fix_path(base_pat, tree_node):cond_pats = {}while tree_node != None:pre_fix_path = []ascend_tree(tree_node, pre_fix_path)if len(pre_fix_path) > 1:cond_pats[frozenset(pre_fix_path[1:])] = tree_node.counttree_node = tree_node.node_linkreturn cond_patsdef mine_tree(in_tree, header_table, min_sup, pre_fix, freq_item_list):bigL = [v[0] for v in sorted(header_table.items(), key=lambda p: p[1][0])]for base_pat in bigL:new_freq_set = pre_fix.copy()new_freq_set.add(base_pat)freq_item_list.append(new_freq_set)cond_patt_bases = find_pre_fix_path(base_pat, header_table[base_pat][1])my_cond_tree, my_head = fp_tree.create_tree(cond_patt_bases, min_sup)if my_head != None:mine_tree(my_cond_tree, my_head, min_sup, new_freq_set, freq_item_list)if __name__ == '__main__':data = fp_tree.create_init_set(fp_tree.load_simp_dat())tree, table = fp_tree.create_tree(data, min_sup=3)freqItems = []mine_tree(tree, table, 3, set([]), freqItems)print("Frequent items:")print(freqItems)

运行结果:

D:\work\python_workspace\machine_learning\venv\Scripts\python.exe D:/work/python_workspace/machine_learning/fp_growth/frequent_items.py
Frequent items:
[{'r'}, {'y'}, {'y', 'z'}, {'y', 'x'}, {'y', 'z', 'x'}, {'t'}, {'y', 't'}, {'t', 'z'}, {'y', 't', 'z'}, {'t', 'x'}, {'y', 't', 'x'}, {'t', 'z', 'x'}, {'y', 't', 'z', 'x'}, {'s'}, {'s', 'x'}, {'x'}, {'z', 'x'}, {'z'}]Process finished with exit code 0

可以看出,我们能够正确的发现频繁项集了。

机器学习-使用FP-Growth算法来高效发现频繁项集相关推荐

  1. 机器学习实战—使用FP-growth算法来高效发现频繁项集

    FP-growth算法基于Apriori构建,但采用了高级的数据结构减少扫描次数,大大加快了算法速度.FP-growth算法只需要对数据库进行两次扫描,而Apriori算法对于每个潜在的频繁项集都会扫 ...

  2. 【机器学习实战】第12章 使用 FP-growth 算法来高效发现频繁项集

    第12章 使用FP-growth算法来高效发现频繁项集 前言 在 第11章 时我们已经介绍了用 Apriori 算法发现 频繁项集 与 关联规则. 本章将继续关注发现 频繁项集 这一任务,并使用 FP ...

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

    第12章 使用FP-growth算法来高效发现频繁项集 一.背景 大家都用过搜索引擎.当我们输入一个单词或单词的一份,搜索引擎就会自动补全查询词项.例如:当我们在百度输入"为什么" ...

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

    本博文内容包括以下: 发现事务数据中的公共模式 FP-growth算法 发现twitter源中的共同词 FP-growth 算法 是基于Apriori算法,但在完成相同的任务(将数据集存储在一个特定的 ...

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

    FP-growth算法基于Apriori构建,但采用了高级的数据结构减少扫描次数,大大加快了算法速度.FP-growth算法只需要对数据库进行两次扫描,而Apriori算法对于每个潜在的频繁项集都会扫 ...

  6. FP-growth算法高效发现频繁项集

    在用搜索引擎时,我们发现输入单词的一部分时,搜索引擎会自动补全查询词项,这里的原理其实是通过查询互联网上的词来找出经常出现在一块的词对,这需要一种高效发现频繁集的方法. 它基于Apriori构建,但在 ...

  7. FP-growth算法发现频繁项集(一)——构建FP树

    常见的挖掘频繁项集算法有两类,一类是Apriori算法,另一类是FP-growth.Apriori通过不断的构造候选集.筛选候选集挖掘出频繁项集,需要多次扫描原始数据,当原始数据较大时,磁盘I/O次数 ...

  8. python实现FP-growth算法发现频繁项集

    ★ FP-growth算法的作用: 该算法是代替Apriori算法来高效发现频繁集,但不能用于发现关联规则. ★ FP-growth算法的组成: 该算法需要构建三部分:1. 项头表   2. FP树  ...

  9. 使用FP-growth算法发现频繁项集

    源码如下: #coding=utf-8''' Created on Jun 14, 2011 FP-Growth FP means frequent pattern the FP-Growth alg ...

最新文章

  1. 利用dom4j将实体类转换为对应的xml报文
  2. 修改vscode的语言
  3. iOS性能优化:Instruments使用实战
  4. 管理者的智慧:靠制度管人,不靠人管人
  5. Android.bp 语法浅析-Android10.0编译系统(八)
  6. Linux中error while loading shared libraries错误解决办法
  7. 单独的plsql链接数据库
  8. python怎么导入视频-Python模块导入详解
  9. ios 拍照上传到服务器_ios端浏览器拍照上传到服务器,图片被旋转90度 php 解决方案...
  10. python云计算主要是干嘛的_国内python 云计算是干什么的
  11. 计算机视觉论文-2021-04-02
  12. 六:SpringCloud-Config
  13. 一文搞懂深度学习中常用的优化算法
  14. impala ERROR: TransmitData() to 10.19.231.254:27000 failed: Network error107
  15. 微盟致远OA聚水潭YonSuite系统对接集成整体解决方案
  16. 微商城是什么?如何制作一个微商城
  17. iOS 强制屏幕旋转
  18. Leetcode——四数之和问题
  19. 面向未来:元宇宙是可望不可及的彼岸世界
  20. php不能连接到数据库服务器,我似乎无法将PHP页面连接到SQL测试服务器和数据库...

热门文章

  1. 基于三维GIS技术的行业发展及研究现状
  2. Springboot在程序启动之前特殊处理
  3. 国标PS码流封装H264的MP4视频转H264MP4
  4. 服务器推送技术原理分析及dwr框架简单的使用
  5. 开源免费代码_02_单摇杆远程遥控小车,基于Arduino的ESP-NOW,ESP32发送指令、ESP32接收指令,实现小车毫秒级完美控制_公羽兴
  6. 2004 最后一天纪念
  7. VsCode设置快捷输入
  8. F盘文件系统RAW文件怎样恢复
  9. 38岁自考计算机本科有用吗,在国企上班的考生,想改变现状,但年龄已经38岁,有必要考研吗?...
  10. 3d Max 抱枕 提桶 斧子 月亮 罗马柱 烟灰缸