【频繁模式挖掘】FP-Tree算法(附Python实现)

一、实验内容简介

该实验主要使用频繁模式和关联规则进行数据挖掘,在已经使用过Apriori算法挖掘频繁模式后,这次使用FP-tree算法来编写和设计程序,依然使用不同规模的数据集来检验效果,最后分析和探讨实验结果,看其是否达到了理想的效果。本实验依然使用Python语言编写。

二、算法说明

首先简单介绍频繁模式关联规则

  • 频繁模式一般是指频繁地出现在数据集中的模式。

  • 关联规则是形如X→Y的蕴涵表达式,其中X和Y是不相交的项集,即X∩Y=∅。关联规则的强度可以用它的支持度(support)和置信度(confidence)来度量。计算公式如下:

  • 支持度:support(A=>B)=P(A∪B),表示A和B同时出现的概率。

  • 置信度:confidence(A=>B)=support(A∪B)/support(A),表示A和B同时出现的概率占A出现概率的比值。

  • 强关联规则是指达到了最小支持度和最小置信度的关联规则。

然后再介绍FP-Tree算法

2000年,Han Jiawei等人提出了基于频繁模式树(Frequent Pattern Tree, FP—Tree)的发现频繁模式的算法FP-Growth。其思想是构造一棵FP-Tree,把数据集中的数据映射到树上,再根据这棵FP-Tree找出所有频繁项集。

FP-Growth算法是指,通过两次扫描事务数据集,把每个事务所包含的频繁项目按其支持度降序压缩存储到FP-Tree中。在以后发现频繁模式的过程中,不需要再扫描事务数据集,而仅在FP-Tree中进行查找即可。通过递归调用FP-Growth的方法可直接产生频繁模式,因此在整个发现过程中也不需产生候选模式。由于只对数据集扫描两次,因此FP-Growth算法克服了Apriori算法中存在的问题,在执行效率上也明显好于Apriori算法。

image-20240407103431324

上图为FP-Tree示意图,展示了该数据结构的构成方式。

三、算法分析与设计

了解完算法的基本原理后,现在开始真正实现该算法。首先需要读取最小支持度,读取数据集。这里的数据集可大可小,我用Python中的字典来表示数据

这里的数据存储格式与之前写Apriori算法时一样,使用字典来存储。然后由用户来输入支持度和置信度(因为这次还要挖掘关联规则,所以增加了置信度输入)。

作为FP-Tree的基础,首先构建树节点。一个节点有四个基本属性,分别节点名称、出现次数、双亲节点和孩子节点。因为这里不是二叉树,树的孩子节点个数不确定,因此用字典来存储,大小可控。

class Node:
    def __init__(self, value, parent, count=0):
        self.value = value
        self.parent = parent
        self.count = count
        self.children = {
   }

    def addChild(self, child):
        self.children.update(child)
    def __init__(self, value, parent, count=0):

前置准备完成后,开始实现FP-Tree算法。FP-Tree算法可大致分为构建项头表、构建FP-Tree、利用条件模式基挖掘频繁模式和关联规则几步。把这几步集成到一个类中,这样避免了大量函数传参操作,思路更清晰。

首先构建项头表,先扫描一遍数据集挖掘频繁1项集,挖掘出来的数据按支持度降序排列,并按此顺序重新排列原数据集的数据,对于不符合要求的数据直接删除。

    def first_scan(self):
        """
        生成项头表,整理数据
        """
        Dict = dict()
        for i in self.data.values():
            for j in i:
                if j not in Dict.keys():
                    Dict.update({
   j: 1})
                else:
                    Dict[j] += 1
        self.first_list = list(Dict.items())
        self.first_list.sort(key=lambda l: l[1], reverse=True)
        for i in range(len(self.first_list) - 1, 0, -1):
            if self.first_list[i][1] < self.support * len(self.data):
                continue
            else:
                rubbish = [self.first_list[j][0] for j in range(i + 1, len(self.first_list))]
                self.first_list = self.first_list[:i + 1]
                break

        # 将原来的数据重新按支持度排序并剔除非频繁1项集
        sort_refer = [i[0] for i in self.first_list]
        for i in self.data.values():
            for j in i:
                if j in rubbish:
                    i.remove(j)
            i.sort(key=lambda l: sort_refer.index(l))

        # 添加频繁1项集
        self.pinfan.extend([list(i) for i in self.first_list])

        # 整理项头表
        self.value_list = [i[0] for i in self.first_list]
        temp = {
   }
        for i in self.first_list:
            temp.update({
   i[0]: [
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪个编程语言更好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值