【Python机器学习】FP-growth算法——构建FP树

news2024/11/25 16:24:03

在第二次扫描数据集时会构建一棵FP树。为构建一棵树,需要一个容器来保存树。

创建FP树的数据结构

FP树要比书中其他树更加复杂,因此需要创建一个类来保存树的每一个节点:

class treeNode:
    def __init__(self,nameValue,numOccur,parentNode):
        self.name=nameValue
        self.count=numOccur
        self.nodeLink=None
        self.parent=parentNode
        self.children={}
    def inc(self,numOccur):
        self.count=self.count+numOccur
    def disp(self,ind=1):
        print(' '*ind,self.name,' ',self.count)
        for child in self.children.values():
            child.disp(ind+1)

上面的程序给出了FP树中节点的类定义。类中包含用于存放节点名字的变量和1个计数值,nodeLink变量用于链接相似的元素项。类中还使用了父变量parent来指向当前节点的父节点。通常情况下并不需要这个变量,因为通常是从上向下迭代访问节点的。之后还需要根据给定叶子节点上溯整棵树,这是就需要指向父节点的指针。最后,类中还包括一个空字典变量,用于存放节点的子节点。

上述代码还包括两个方法,其中inc()对count变量增加给定值,另一个方法disp()用于将树以文本形式显示。后者对于树构建来说并不是必要的,但它对调试非常有用。

创建一棵树的一个单节点,之后为其增加一个子节点:

rootNode=treeNode('pyramid',9,None)
rootNode.children['eye']=treeNode('eye',13,None)
print(rootNode.disp())

再添加一个节点看一下两个子节点的展示效果:

rootNode.children['phoenix']=treeNode('phoenix',3,None)
print(rootNode.disp())

现在FP树所需的数据结构已经建好,之后就可以构建FP树了。

构建FP树

FP树中,需要一个头指针来指向给定类型的第一个实例。利用头指针表,可以快速访问FP树中一个给定类型的所有元素,比如:

这里使用一个字典作为数据结构,来保存头指针表。除了存放指针外,头指针表还可以用来保存FP树中每个元素的总数。

第一次遍历数据集会获得每个元素项的出现频率。接下来,去掉不满足最小支持度的元素项。再下一步构建FP树。在构建时,读入每个项集并将其添加到一条已经存在的路径中。如果该路径不存在,则创建一条新路径。每个事务就是一个无序集合。假设有集合{z,x,y}和{y,z,r},那么在FP树中,相同项会只表示一次。为了解决这个问题,在将集合添加到树之前,需要对每个集合进行排序。排序基于元素项的绝对出现频率来进行。使用上图中的头指针节点值,对数据进行过滤、重排序的数据如下:

在对事务记录进行过滤和排序之后,就可以构建FP树了。从空集开始,向其中不断添加频繁项集。过滤、排序后的事务依次添加到树中,如果树中已存在现有元素,则增加现有元素的值;如果现有元素不存在,则向树添加一个分枝。

对上表前两条事务进行添加的过程:

接下来是代码实现上述过程:

def createTree(dataSet,minSup=1):
    headerTable={}
    for trans in dataSet:
        for item in trans:
            headerTable[item]=headerTable.get(item,0)+dataSet[trans]
    #移除不满足最小支持度的元素项
    #print('keys:',list(headerTable.keys()))
    for k in list(headerTable.keys()):
        if headerTable[k]<minSup:
            del(headerTable[k])
    freqItemSet=set(headerTable.keys())
    #如果没有元素项满足要求,退出,返回None
    if len(freqItemSet)==0:
        return None,None
    for k in headerTable:
        headerTable[k]=[headerTable[k],None]
    retTree=treeNode('Null set',1,None)
    for tranSet,count in dataSet.items():
        localD={}
        for item in tranSet:
            if item in freqItemSet:
                localD[item]=headerTable[item][0]
        if len(localD)>0:
            orderedItems=[v[0] for v in sorted(localD.items(),key=lambda p:p[1],reverse=True)]
            #使用排序后的频率项集对树进行填充
            updateTree(orderedItems,retTree,headerTable,count)
    return retTree,headerTable

def updateTree(items,inTree,headerTable,count):
    if items[0] in inTree.children:
        inTree.children[items[0]].inc(count)
    else:
        inTree.children[items[0]]=treeNode(items[0],count,inTree)
        if headerTable[items[0]][1]==None:
            headerTable[items[0]][1]=inTree.children[items[0]]
        else:
            updateHeader(headerTable[items[0]][1],inTree.children[items[0]])
    if len(items) > 1:
        #对剩下的元素迭代调用updateTree函数
        updateTree(items[1::],inTree.children[items[0]],headerTable,count)
def updateHeader(nodeToTest,targetNode):
    while (nodeToTest.nodeLink != None):
        nodeToTest=nodeToTest.nodeLink
    nodeToTest.nodeLink=targetNode

上述代码包含3个函数。第一个函数createTree()使用数据集以及最小支持度作为参数构建FP树。树构建过程中会遍历数据集两次。第一次遍历扫描数据集并统计每个元素项出现的频度。所有所有项都不频繁,就不需要进行下一步处理。接下来,对头指针表稍加扩展以便可以保存计数值及指向每种类型第一个元素项的指针。然后创建只包含空集合\phi的根节点。最后,再一次遍历数据集,这次只考虑哪些频繁项。这些项已经进行了排序,然后调用updateTree()方法。

为了让FP树生长,需调用updateTree,其中的输入参数为一个项集。该函数首先测试事务中的第一个元素项是否作为子节点存在。如果存在的话,则更新该元素项的计数;如果不存在,则创建一个新的treeNode并将其作为一个子节点添加到树中。这是,头指针表也要更新以指向新的节点。更新头指针表需要调用函数updateHeader()。updateTree()完成的最后一件事是不断迭代调用自身,每次调用时会去掉列表中第一个元素。

最后一个函数是updateHeader(),它确保节点链接指向树中该元素项的每一个实例。从头指针的nodeLink开始,一直沿着nodeLink直到到达链表末尾。这就是一个链表。当处理树的时候,一种很自然的反应就是迭代完成每一件事。当以相同方式处理链表时可能会遇到一些问题,原因是如果链表很长可能会遇到迭代调用的次数限制。

下面,创建一个真正的数据集,用来运行上面的函数,查看运行效果:

def loadSimpDat():
    simpDat=[['r','z','h','j','p'],
             ['z','y','x','w','v','u','t','s'],
             ['z'],
             ['r','x','n','o','s'],
             ['y','r','x','z','q','t','p'],
             ['y','z','x','e','q','s','t','m']]
    return simpDat
def createInitSet(dataSet):
    retDict={}
    for trans in dataSet:
        retDict[frozenset(trans)]=1
    return retDict

下面,实际运行,首先导入数据库实例,然后对数据进行格式化处理:

simpDat=loadSimpDat()
print(simpDat)

接下来,为了函数createTree,需要对上面的数据进行格式化处理:

initSet=createInitSet(simpDat)
print(initSet)

创建FP树:

myFPtree,myHeaderTab=createTree(initSet,3)
print(myFPtree.disp())

上面给出的是元素项及其对应的频率计数值,其中每个缩进表示所处的数的深度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2045544.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【GLM-4微调实战】GLM-4-9B-Chat模型之Lora微调实战

系列篇章&#x1f4a5; No.文章1【GLM-4部署实战】GLM-4-9B-Chat模型本地部署实践指南2【GLM-4部署实战】GLM-4-9B-Chat模型之对话机器人部署测试3【GLM-4部署实战】GLM-4-9B-Chat模型之vLLM部署推理实践4【GLM-4微调实战】GLM-4-9B-Chat模型之Lora微调实战 目录 系列篇章&…

SpringBoot整合SMS短信服务

SpringBoot整合SMS短信服务 概览pom依赖yml配置配置类service 层interfaceimpl controller层 概览 了解阿里云用户权限操作开通阿里云短信服务添加短信模板添加签名编写测试代码编写可复用的微服务接口&#xff0c;实现验证码的发送 pom依赖 <!--aliyun 短信服务--> &l…

【项目方案】IP地址地理解析方案对比与选型

目前&#xff0c;许多项目在用户发布言论时需要解析其 IP 地址&#xff0c;并且在账号管理中也有查看最近登录地的需求。然而&#xff0c;市面上的相关教程通常缺乏全面性&#xff0c;往往只提供一种简单的方法&#xff0c;导致在技术方案选型时难以进行有效的方案对比。本文旨…

前端工程化-05.Vue项目开发流程

一.Vue项目开发流程 import是导入模块&#xff0c;而export是导出模块 以.vue结尾的为vue组件文件&#xff0c;是我们Vue项目开发时经常操作的组件 <template>&#xff1a;模板部分&#xff0c;由他生成HTML代码 相当于vue当中的视图部分 <script>&#xff1a;…

C++:缺省参数、函数重载、引用

目录 一、缺省参数 二、函数重载 三、引用 3.1 引用的概念和定义 3.2 引用的特征 3.3 引用的使用 3.4 const引用 3.5 指针和引用的关系 一、缺省参数 • 缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值&#xff0c;在调用该函数时&#xff0c;如果没有指定实参…

数据结构预备知识

目录 1. 什么是集合框架 2. 什么是数据结构 3. 容器背后对应的数据结构 4. 相关java知识 5. 时间复杂度 6. 空间复杂度 7. 包装类 7.1 装箱和拆箱 7.2 阿里面试题&#xff1a; 8. 泛型 8.1 泛型的语法 8.2 泛型怎样编译 9. 泛型的上界 9.1 语法 9.2 泛型方法 1.…

网络通信要素

网络介绍 定义&#xff1a;将具有独立功能的多台计算机通过通信线路和通信设备连接起来&#xff0c;在网络管理软件及网络通信协议下&#xff0c;实现资源共享和信息传递的虚拟平台。 学习网络的目的&#xff1a; 能够编写基于网络通信的软件或程序&#xff0c;通常来说就是网…

CentOS7下制作openssl1.1.1i RPM包并升级

OpenSSL最新漏洞 OpenSSL官方发布了拒绝服务漏洞风险通告&#xff0c;漏洞编号为CVE-2020-1971 漏洞详情 OpenSSL是一个开放源代码的软件库包&#xff0c;应用程序可以使用这个包来进行安全通信&#xff0c;避免窃听&#xff0c;同时确认另一端连接者的身份。这个包广泛被应…

爆了,20w点赞!收好这6个可以一键替换视频人物的AI工具!(建议收藏)

用 AI 一键替换视频中人物角色的玩法&#xff0c;彻底被网友们带火了&#xff01; 前有机器人插秧、机器人做饭做家务的视频&#xff0c;后有机器人打乒乓球、美女踢足球的视频。 这类视频动辄几万、几十万点赞&#xff0c;流量也太猛了&#xff01; 图片可能不太直观&#x…

时空自回归模型(STAR)及 Stata 具体操作步骤

目录 一、引言 二、文献综述 三、理论原理 四、实证模型 五、稳健性检验 六、程序代码及解释 附录 数据预处理 生成时空权重矩阵 一、引言 时空自回归模型&#xff08;Spatial-Temporal Autoregressive Model&#xff0c;简称 STAR&#xff09;在分析具有时空特征的数…

Java填充PDF并返回填充后PDF文件及对应base64码

前期准备 下载PDF编辑工具&#xff08;Adobe Acrobat 9 Pro&#xff09;&#xff1a; 可以主页关注小程序【白哥Java】回复【PDF编辑软件】即可获取 或者直接联系博主也可 主页如下&#xff1a; 软件使用流程 此处流程为文本域流程 图片或其他大致相同 生成模板PDF样式如下&…

Linux命令行参数与环境变量

目录 命令行参数与环境变量 命令行参数 环境变量及其相关概念 环境变量的相关操作 环境变量的本质 命令行参数与环境变量 命令行参数 我们在使用一些Linux的一些指令时&#xff0c;会有意或无意的使用一些指令参数&#xff0c;例如&#xff1a; ls -al ps -ajx gcc -o …

CVE-2024-38077 微软 RDP 漏洞修复 报错 不适用于你的计算机 解决方法

这一漏洞存在于Windows远程桌面许可管理服务&#xff08;RDL&#xff09;中&#xff0c;该服务被广泛部署于开启Windows远程桌面&#xff08;3389端口&#xff09;的服务器&#xff0c;用于管理远程桌面连接许可&#xff0c;也有文章认为该漏洞实际利用的是135端口。攻击者无需…

【大模型】多模态的原理简述

多模态的原理 多模态模型目前基本就是文生图、图生图、图生视频、文生视频这些&#xff0c;其底层逻辑其实还是先从生图片这一源头。因为毕竟视频也是若干帧的图片组成。 所以在生图片的这个环节上&#xff0c;我们把比较火的这个stablediffusion用的这个diffusion扩散模型理…

企业大数据治理管理平台解决方案(33页PPT)

方案介绍&#xff1a; 本解决方案旨在为企业提供一套从数据采集、存储、处理、分析到应用的全链条大数据治理管理平台。该平台通过集成先进的数据技术和管理理念&#xff0c;帮助企业实现数据的全生命周期管理&#xff0c;提升数据质量&#xff0c;降低数据风险&#xff0c;促…

PX4-Autopolite linux环境下源码编译中遇到的一些问题及相应解决办法

最近在做一个PX4飞控移植的项目&#xff0c;第一次接触到PX4源码&#xff0c;真的是感觉编译起来非常的麻烦&#xff0c;下面我将介绍几个新手比较容易踩坑的点。 &#xff08;我都踩了ㄒ-ㄒ&#xff09; 1.PX4源码要用git clone 从github上克隆来&#xff0c;千万不要直接在g…

谷粒商城实战笔记-170~172-缓存-SpringCache

文章目录 一&#xff0c;170-缓存-SpringCache-自定义缓存配置二&#xff0c;171-缓存-SpringCache-CacheEvict1&#xff0c;删除多个缓存2&#xff0c;删除一个缓存 三&#xff0c;172-缓存-SpringCache-原理与不足 一&#xff0c;170-缓存-SpringCache-自定义缓存配置 上一节…

中国对世界各国的进出口面板数据(2000-2022年)

中国作为全球最大的贸易国之一&#xff0c;其对各国的进出口数据不仅量级庞大&#xff0c;而且蕴含着丰富的经济信息与趋势动向&#xff0c;对于研究全球经济互动、国际贸易格局、产业链分布以及中国自身经济的发展策略具有一定价值。例如&#xff0c;近年来的数据表明&#xf…

对接的广告平台越多,APP广告变现的收益越高?

无论是游戏、社交、工具应用类APP还是泛娱乐类APP&#xff0c;流量变现的方式主要有广告、内购、订阅三种方式。其中&#xff0c;广告变现是门槛最低、适用最广的变现方式。 只要APP有流量&#xff0c;就可以进行广告变现&#xff0c;让APP的流量快速转化为商业价值。作为最常…

什么是张量

张量的基础概念 学习使用pytorc库进行深度学习网络搭建时&#xff0c;张量这个词总是不定时会出现。其实&#xff0c;Pytorch中的所有操作都是在张量的基础上进行的&#xff0c;今天就来了解张量到底是什么 由PyTorch官网官网介绍可知&#xff0c;一个Tensor是一个包含单一数据…