fp-growth代码问题(Python)
网上的 python3 fp-growth代码每次在执行时可能会出现找出的频繁项集不一致的情况,这是因为每次执行代码时建的FP树可能不一致。
加了一行代码可以解决这个问题(第59行):先对 frequentItemsInRecord 按 key 的ASSIC码排序,然后再按照 key 的支持度(即value值)降序排列。
之所以这么做是因为 frequentItemsInRecord 中可能会出现支持度一样的项,如果不按ASSIC码先排一次的话,
有可能出现每次执行代码时 orderedFrequentItems (第60行)中相同支持度的项出现的顺序不一致,从而造成每次建的FP树不一致,导致找出的频繁项集不一致。
import pprint def loadDataSet():
dataSet = [['bread', 'milk', 'vegetable', 'fruit', 'eggs'],
['noodle', 'beef', 'pork', 'water', 'socks', 'gloves', 'shoes', 'rice'],
['socks', 'gloves'],
['bread', 'milk', 'shoes', 'socks', 'eggs'],
['socks', 'shoes', 'sweater', 'cap', 'milk', 'vegetable', 'gloves'],
['eggs', 'bread', 'milk', 'fish', 'crab', 'shrimp', 'rice']] return dataSet def transfer2FrozenDataSet(dataSet):
frozenDataSet = {}
for elem in dataSet:
frozenDataSet[frozenset(elem)] = 1 return frozenDataSet class TreeNode:
def __init__(self, nodeName, count, nodeParent):
self.nodeName = nodeName
self.count = count
self.nodeParent = nodeParent
self.nextSimilarItem = None
self.children = {} def increaseC(self, count):
self.count += count def createFPTree(frozenDataSet, minSupport):
# scan dataset at the first time, filter out items which are less than minSupport
headPointTable = {}
for items in frozenDataSet:
for item in items:
headPointTable[item] = headPointTable.get(item, 0) + frozenDataSet[items]
headPointTable = {
k: v
for k, v in headPointTable.items() if v >= minSupport
}
frequentItems = set(headPointTable.keys())
if len(frequentItems) == 0: return None, None for k in headPointTable:
headPointTable[k] = [headPointTable[k], None] fptree = TreeNode("null", 1, None)
# scan dataset at the second time, filter out items for each record
for items, count in frozenDataSet.items():
frequentItemsInRecord = {}
for item in items:
if item in frequentItems:
frequentItemsInRecord[item] = headPointTable[item][0]
if len(frequentItemsInRecord) > 0:
frequentItemsInRecord = sorted(frequentItemsInRecord.items(), key=lambda v: v[0])
orderedFrequentItems = [v[0] for v in sorted(frequentItemsInRecord, key=lambda v: v[1], reverse=True)]
updateFPTree(fptree, orderedFrequentItems, headPointTable, count) return fptree, headPointTable def updateFPTree(fptree, orderedFrequentItems, headPointTable, count):
# handle the first item
if orderedFrequentItems[0] in fptree.children:
fptree.children[orderedFrequentItems[0]].increaseC(count)
else:
fptree.children[orderedFrequentItems[0]] = TreeNode(orderedFrequentItems[0], count, fptree) # update headPointTable
if headPointTable[orderedFrequentItems[0]][1] == None:
headPointTable[orderedFrequentItems[0]][1] = fptree.children[orderedFrequentItems[0]]
else:
updateHeadPointTable(headPointTable[orderedFrequentItems[0]][1], fptree.children[orderedFrequentItems[0]])
# handle other items except the first item
if (len(orderedFrequentItems) > 1):
updateFPTree(fptree.children[orderedFrequentItems[0]], orderedFrequentItems[1::], headPointTable, count) def updateHeadPointTable(headPointBeginNode, targetNode):
while (headPointBeginNode.nextSimilarItem != None):
headPointBeginNode = headPointBeginNode.nextSimilarItem
headPointBeginNode.nextSimilarItem = targetNode def mineFPTree(headPointTable, prefix, frequentPatterns, minSupport):
# for each item in headPointTable, find conditional prefix path, create conditional fptree,
# then iterate until there is only one element in conditional fptree
headPointItems = [v[0] for v in sorted(headPointTable.items(), key=lambda v: v[1][0])]
if (len(headPointItems) == 0): return for headPointItem in headPointItems:
newPrefix = prefix.copy()
newPrefix.add(headPointItem)
support = headPointTable[headPointItem][0]
frequentPatterns[frozenset(newPrefix)] = support prefixPath = getPrefixPath(headPointTable, headPointItem)
if (prefixPath != {}):
conditionalFPtree, conditionalHeadPointTable = createFPTree(prefixPath, minSupport)
if conditionalHeadPointTable != None:
mineFPTree(conditionalHeadPointTable, newPrefix, frequentPatterns, minSupport) def getPrefixPath(headPointTable, headPointItem):
prefixPath = {}
beginNode = headPointTable[headPointItem][1]
prefixs = ascendTree(beginNode)
if ((prefixs != [])):
prefixPath[frozenset(prefixs)] = beginNode.count while (beginNode.nextSimilarItem != None):
beginNode = beginNode.nextSimilarItem
prefixs = ascendTree(beginNode)
if (prefixs != []):
prefixPath[frozenset(prefixs)] = beginNode.count return prefixPath def ascendTree(treeNode):
prefixs = []
while ((treeNode.nodeParent != None) and (treeNode.nodeParent.nodeName != 'null')):
treeNode = treeNode.nodeParent
prefixs.append(treeNode.nodeName) return prefixs def rulesGenerator(frequentPatterns, minConf, rules):
for frequentset in frequentPatterns:
if (len(frequentset) > 1):
getRules(frequentset, frequentset, rules, frequentPatterns, minConf) def removeStr(set, str):
tempSet = []
for elem in set:
if (elem != str):
tempSet.append(elem)
tempFrozenSet = frozenset(tempSet) return tempFrozenSet def getRules(frequentset, currentset, rules, frequentPatterns, minConf):
for frequentElem in currentset:
subSet = removeStr(currentset, frequentElem)
confidence = frequentPatterns[frequentset] / frequentPatterns[subSet]
if (confidence >= minConf):
flag = False
for rule in rules:
if (rule[0] == subSet and rule[1] == frequentset - subSet):
flag = True if (flag == False):
rules.append((subSet, frequentset - subSet, confidence)) if (len(subSet) >= 2):
getRules(frequentset, subSet, rules, frequentPatterns, minConf) if __name__ == '__main__':
dataSet = loadDataSet()
frozenDataSet = transfer2FrozenDataSet(dataSet)
minSupport = 3
fptree, headPointTable = createFPTree(frozenDataSet, minSupport)
frequentPatterns = {}
prefix = set([])
mineFPTree(headPointTable, prefix, frequentPatterns, minSupport)
print("frequent patterns:")
pprint.pprint(frequentPatterns) minConf = 0.6
rules = []
rulesGenerator(frequentPatterns, minConf, rules)
print("association rules:")
pprint.pprint(rules)
print('rules num:', len(rules))
fp-growth代码问题(Python)的更多相关文章
- FP—Growth算法
FP_growth算法是韩家炜老师在2000年提出的关联分析算法,该算法和Apriori算法最大的不同有两点: 第一,不产生候选集,第二,只需要两次遍历数据库,大大提高了效率,用31646条测试记录, ...
- FP - growth 发现频繁项集
FP - growth是一种比Apriori更高效的发现频繁项集的方法.FP是frequent pattern的简称,即常在一块儿出现的元素项的集合的模型.通过将数据集存储在一个特定的FP树上,然后发 ...
- 编写高质量代码--改善python程序的建议(六)
原文发表在我的博客主页,转载请注明出处! 建议二十八:区别对待可变对象和不可变对象 python中一切皆对象,每一个对象都有一个唯一的标识符(id()).类型(type())以及值,对象根据其值能否修 ...
- 编写高质量代码--改善python程序的建议(八)
原文发表在我的博客主页,转载请注明出处! 建议四十一:一般情况下使用ElementTree解析XML python中解析XML文件最广为人知的两个模块是xml.dom.minidom和xml.sax, ...
- 编写高质量代码--改善python程序的建议(三)
原文发表在我的博客主页,转载请注明出处! 建议十三:警惕eval()的安全漏洞 相信经常处理文本数据的同学对eval()一定是欲罢不能,他的使用非常简单: eval("1+1==2" ...
- 抓取oschina上面的代码分享python块区下的 标题和对应URL
# -*- coding=utf-8 -*- import requests,re from lxml import etree import sys reload(sys) sys.setdefau ...
- Frequent Pattern 挖掘之二(FP Growth算法)(转)
FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达到这样的效果,它采用了一种简洁的数据结 ...
- 编写高质量代码改善python程序91个建议学习01
编写高质量代码改善python程序91个建议学习 第一章 建议1:理解pythonic的相关概念 狭隘的理解:它是高级动态的脚本编程语言,拥有很多强大的库,是解释从上往下执行的 特点: 美胜丑,显胜隐 ...
- 关联规则算法之FP growth算法
FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达到这样的效果,它采用了一种简洁的数据结 ...
- Frequent Pattern (FP Growth算法)
FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达 到这样的效果,它采用了一种简洁的数据 ...
随机推荐
- [快捷键的使用] IntelliJ IDEA 将数据库里面的表转化为对象
本文讲述IntelliJ IDEA 多行编辑快捷键的使用,希望能帮到新人提高效率. 注意:在笔记本键盘上操作的方法. 数据库连接工具使用SQLyog 第一步: 从数据里面将文本拷贝到User类里面. ...
- Celery简介以及Django中使用celery
目录 Celery简介 消息中间件 任务执行单元 任务结果存储 使用场景 Celery的安装和配置 Celery执行异步任务 基本使用 延时任务 定时任务 异步处理Django任务 案例: Celer ...
- python高级编程——锁
锁 在使用用的过程中需要导入threading模块的Lock类 使用锁: 当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制 线程同步能够保证多个线程安全访问竞争资源,最 ...
- Vue配置路由和传参方式及路由守卫!
安装路由 npm i vue-router -S 引入路由 import VueRouter form VueRouter 注入路由模块 Vue.use(VueRouter) 定义路由匹配规则 let ...
- python打印带颜色字体
设置颜色开始 :\033[显示方式;前景色;背景色m 前景色 背景色 颜色 30 40 黑色 31 41 红色 32 42 绿色 33 43 黃色 34 44 蓝色 35 45 紫红色 36 46 青 ...
- 海思3519A 移植ffmpeg
文件下载 下载x264 git clone git://git.videolan.org/x264.git 下载ffmpeg git clone git://source.ffmpeg.org/ffm ...
- Odoo报表的report标签和报表格式定义
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826329.html 一:Report标签 report标签可用于定义一条报表记录.属性有: 1) ...
- Redis开启远程访问及密码
一.开启远程访问 1.开放端口 firewall-cmd --zone=public --add-port=6379 firewall-cmd --zone=public --add-port=637 ...
- 学Redis
Redis 简介 Redis 是完全开源免费的,遵守 BSD 协议,是一个高性能的 key - value 数据库 Redis 与 其他 key - value 缓存产品有以下三个特点: Redis ...
- libass简明教程
[时间:2019-05] [状态:Open] [关键词:字幕,libass,字幕渲染,ffmpeg, subtitles, video filter] 0 引言 libass库则是一个轻量级的对ASS ...