关联规则挖掘算法及代码(测试后)

Apriori算法

Apriori算法介绍1
Apriori算法介绍2
Apriori算法介绍3,容易看懂一些

FP-Growth算法

FP-Growth算法介绍1
实现

# -*- 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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值