网上的 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)的更多相关文章

  1. FP—Growth算法

    FP_growth算法是韩家炜老师在2000年提出的关联分析算法,该算法和Apriori算法最大的不同有两点: 第一,不产生候选集,第二,只需要两次遍历数据库,大大提高了效率,用31646条测试记录, ...

  2. FP - growth 发现频繁项集

    FP - growth是一种比Apriori更高效的发现频繁项集的方法.FP是frequent pattern的简称,即常在一块儿出现的元素项的集合的模型.通过将数据集存储在一个特定的FP树上,然后发 ...

  3. 编写高质量代码--改善python程序的建议(六)

    原文发表在我的博客主页,转载请注明出处! 建议二十八:区别对待可变对象和不可变对象 python中一切皆对象,每一个对象都有一个唯一的标识符(id()).类型(type())以及值,对象根据其值能否修 ...

  4. 编写高质量代码--改善python程序的建议(八)

    原文发表在我的博客主页,转载请注明出处! 建议四十一:一般情况下使用ElementTree解析XML python中解析XML文件最广为人知的两个模块是xml.dom.minidom和xml.sax, ...

  5. 编写高质量代码--改善python程序的建议(三)

    原文发表在我的博客主页,转载请注明出处! 建议十三:警惕eval()的安全漏洞 相信经常处理文本数据的同学对eval()一定是欲罢不能,他的使用非常简单: eval("1+1==2" ...

  6. 抓取oschina上面的代码分享python块区下的 标题和对应URL

    # -*- coding=utf-8 -*- import requests,re from lxml import etree import sys reload(sys) sys.setdefau ...

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

    FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达到这样的效果,它采用了一种简洁的数据结 ...

  8. 编写高质量代码改善python程序91个建议学习01

    编写高质量代码改善python程序91个建议学习 第一章 建议1:理解pythonic的相关概念 狭隘的理解:它是高级动态的脚本编程语言,拥有很多强大的库,是解释从上往下执行的 特点: 美胜丑,显胜隐 ...

  9. 关联规则算法之FP growth算法

    FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达到这样的效果,它采用了一种简洁的数据结 ...

  10. Frequent Pattern (FP Growth算法)

    FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达 到这样的效果,它采用了一种简洁的数据 ...

随机推荐

  1. G++命令

    gcc and g++分别是gnu的c & c++编译器. 从源代码到可执行文件的四步 gcc/g++在执行编译工作的时候,总共需要4步 1.预处理,生成.i的文件,用到预处理器cpp.这一步 ...

  2. Spring通过配置类加载实体bean

    以下4个java类都在都一个包下: 1.定义接口 public interface AA { void play(); } 2.定义实体bean //组件注解,表明该类是一个组件 @Component ...

  3. (原)堆叠hourglass网络

    转载请注明出处: https://www.cnblogs.com/darkknightzh/p/11486185.html 论文: https://arxiv.org/abs/1603.06937 官 ...

  4. MySQL数据库(六)-- SQL注入攻击、视图、事物、存储过程、流程控制

    一.SQL注入攻击 1.什么是SQL注入攻击 一些了解sql语法的用户,可以输入一些关键字 或合法sql,来导致原始的sql逻辑发生变化,从而跳过登录验证 或者 删除数据库 import pymysq ...

  5. Docker安装Redis4.0

    docker pull redis:4.0 拉取Redis4.0镜像 docker images 查看本地的镜像 mkdir -p /root/redis4.0/data 在宿主机创建数据文件目录 w ...

  6. Leetcode——2. 两数相加

    难度: 中等 题目 You are given two non-empty linked lists representing two non-negative integers. The digit ...

  7. django rest framework 解析器组件 接口设计,视图组件 (1)

    一.解析器组件 -解析器组件是用来解析用户请求数据的(application/json), content-type 将客户端发来的json数据进行解析 -必须适应APIView -request.d ...

  8. MySQL版本问题导致的SQLException

    背景 ​ 学习使用 SpringCloud 时,使用 消费者 调用 生产者 时抛出 SQLException,持久层框架为 MyBatis,数据库为最新版本的 MySQL 版本如下: Server v ...

  9. 回溯法 | n皇后问题

    今早上看了一篇英语阅读之后,莫名有些空虚寂寞冷.拿出算法书,研读回溯法.我觉得n皇后问题完全可以用暴力方式,即先对n个数进行全排列,得到所有结果的下标组合,问题规模为n!. 全排列花了比较久的时间才编 ...

  10. NOIP2019翻车前写(and 抄)过的代码

    咕咕咕.按上传时间升序排列. //树的重心 void dfs(int x) { v[x]=1; size[x]=1; int max_part=0; for(int i=hed[x];i;i=nxt[ ...