Apriori算法
Apriori算法介绍1
Apriori算法介绍2
Apriori算法介绍3,容易看懂一些
FP-Growth算法
# -*- coding: utf-8 -*-
# @Time : 2020/11/5 21:21
# @Author : cubewwt
# @File : test1.py
# @contact: wwt98@foxmail.com
# 构建FP树
class treeNode:
def __init__(self, nameValue=None, nodelink=None, parentNode=None):
self.name = nameValue # 节点名称
self.count = 1 # 节点出现的次数
self.nodeLink = nodelink # 链接指向的下一个节点
self.parent = parentNode # 父节点
self.children = {} # 子节点,{name:treeNode}
def inc(self): # 该函数用来增加节点出现的次数
self.count += 1
# 利用递归实现树的先序遍历,用于检查
def front_(self, root, list):
if not root:
return None
list.append([root.name, root.count])
for i in root.children:
self.front_(root.children[i], list)
return list
# 输入值data是一个多维列表,原始数据,每一个元素是一个列表,该列表表示出现的元素
# 输入值headerTable_del是根据最小支持度生成的待删除的元素列表
# 返回值data是一个多维列表,处理过后的数据,对每条记录按照出现次数多少进行排序,并删除小于最小支持度的选项
def get_data_processed(data, headerTable_del):
for i in range(len(data)):
for j in range(len(data[i])):
for k in range(0, len(data[i]) - j - 1):
if headerTable_sorted[data[i][k]] < headerTable_sorted[data[i][k + 1]]:
data[i][k], data[i][k + 1] = data[i][k + 1], data[i][k]
for i in range(len(data)):
for j in range(len(data[i])):
if data[i][j] in headerTable_del:
del data[i][j:]
break
# return data
# 输入data 是一个多维列表,输入应该是删除多余元素,处理后的列表
# 输入headerTable_Point是存储同值在树中的位置的字典,{name:位置}
# 输出tree是一个树的头节点
def create_Tree(data, headerTable_Point):
# 创建一个空的头节点
tree = treeNode()
for i in data:
temp = []
if i[0] in tree.children:
tree.children[i[0]].inc()
temp.append(tree.children[i[0]])
else:
temp.append(treeNode(i[0], None, tree))
tree.children[i[0]] = temp[0]
headerTable_Point[i[0]].append(temp[0])
for j in range(1, len(i)):
if i[j] in temp[j - 1].children:
temp[j - 1].children[i[j]].inc()
temp.append(temp[j - 1].children[i[j]])
else:
temp.append(treeNode(i[j], None, temp[j - 1]))
temp[j - 1].children[i[j]] = temp[j]
headerTable_Point[i[j]].append(temp[j])
return tree, headerTable_Point
# 得到条件模式基
# 输入item是一个存在于headerTable_sorted_del_list中的数据,要查询的目标
# 输入headerTable_Point是记录目标对应树节点位置的字典{目标:在树中位置}
# 输出prefixpath是记录路径以及出现次数的字典{路径:次数}
# 注意这里的输出不包括出现次数最多的元素,因为出现次数最多的元素的父节点一定是null,所以不用输出
def get_prefixpath(headerTable_Point, headerTable_sortedlist):
prefixpath = {} # 记录条件模式基的字典,{单个频繁项:{路径:次数}}
for i in range(1, len(headerTable_sortedlist)):
temp = {}
for j in headerTable_Point[headerTable_sortedlist[-i]]:
list_ = []
count = j.count
j = j.parent
while j.name:
list_.append(j.name)
j = j.parent
temp[tuple(list_)] = count
prefixpath[headerTable_sortedlist[-i]] = temp
return prefixpath
# 得到条件模式基,并通过条件模式基进行筛选,得到频繁项集
# 输入item是一个存在于headerTable_sorted_del_list中的数据,要查询的目标
# 输入headerTable_Point是记录目标对应树节点位置的字典{目标:在树中位置}
# 输入min_support是最小支持度,用来剪枝条件模式基
# 输入k是目标元素,求取目标元素的频繁项集
# frequency_count记录的是某元素的条件模式基,方便对后续的进行处理
# 注意这里的输出不包括出现次数最多的元素,因为出现次数最多的元素的父节点一定是null,所以就他来说除了他自身,并无其他可以再发掘的频繁项集
def get_frequency(headerTable_Point, headerTable_sortedlist, min_support, k):
frequency_count = {}
for i in range(1, len(headerTable_sortedlist)):
temp = {}
for j in headerTable_Point[headerTable_sortedlist[-i]]:
count = j.count
j = j.parent
while j.name:
if j.name not in temp:
temp[j.name] = count
else:
temp[j.name] += count
j = j.parent
frequency_count[headerTable_sortedlist[-i]] = temp
# 求取频繁项集
if k not in frequency_count:
return None
cpb = frequency_count[k]
cpb = sorted(cpb.items(), key=lambda x: x[1], reverse=True)
frequent_set = []
for i, j in cpb:
if j < min_support:
break
frequent_set.append(i)
return cpb, frequent_set
# 主程序
# 初始化数据
dataset = [['1', '2', '3', '4', '5'],
['2', '5', '4', '3', '9'],
['6', '7', '9'],
['1', '5', '8', '9', '2'],
['2', '1', '3']]
headerTable_count = {} # 用来存储每项元素及其出现次数
for i in dataset: # 遍历每条记录
for j in i: # 遍历每条记录的每项元素
if j in headerTable_count:
headerTable_count[j] += 1
else:
headerTable_count[j] = 1 # 计算每项元素的出现次数
# 按照出现次数多少进行排序,从大到小
headerTable_count = sorted(headerTable_count.items(), key=lambda x: x[1], reverse=True)
print(headerTable_count)
print("headerTable's length:", len(headerTable_count))
print('-' * 88)
min_support = 2 # 设定最小支持度
headerTable_Point = {} # 用来记在树中的位置,删除了小于最小支持度的
headerTable_del = [] # 用来记应删除的元素
headerTable_sorted = {} # 用来记单个出现的次数
headerTable_sorted_del_list = [] # 用来记录最终排序,出现次数多的在前面
# 生成以上几个列表或字典
for i in headerTable_count:
if i[1] >= min_support:
headerTable_Point[i[0]] = []
headerTable_sorted[i[0]] = i[1]
headerTable_sorted_del_list.append(i[0])
else:
headerTable_sorted[i[0]] = i[1]
headerTable_del.append(i[0])
print('headerTable_sorted:', headerTable_sorted)
print('-' * 88)
print('headerTable_sorted_del_list', headerTable_sorted_del_list)
print('-' * 88)
print('get_data_processed:')
# 这里就直接改变dataset
get_data_processed(dataset, headerTable_del)
print(dataset)
print('-' * 88)
Tree, headerTable_Point = create_Tree(dataset, headerTable_Point)
print('headerTable_Point:', headerTable_Point)
print('-' * 88)
# 检查
print('pre-order print the tree to check')
print(Tree.front_(Tree, []))
print('-' * 88)
print('get pre-path and the count')
print(get_prefixpath(headerTable_Point, headerTable_sorted_del_list))
print('-' * 88)
target = '4'
cpb, frequent_Set = get_frequency(headerTable_Point, headerTable_sorted_del_list, 2, target)
print(target, '\'s conditional pattern base:', cpb)
print(target, '\'s frequent set:', frequent_Set)
print('-' * 88)