分析FP -Growth代码运行内存太大而无法运行的原因

news2024/9/20 8:35:41

🏆本文收录于《CSDN问答解惑-专业版》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

问题描述

  分析FP -Growth代码运行内存太大而无法运行的原因。下面FP-Growth算法是我的主算法调用的一个算法,请帮我分析以下代码运行内存太大而无法运行的原因,并给出修改(其中输入变量Dataset的维度可能在1000左右):

function [Freq,Freq_weight] = FPGrowth(FrontNo,Weight,Dataset,MST)
  NumEvent=1;
  T = cell(1,1);
  [nRows,~]=size(Dataset);
  for i = 1:nRows
      c = find(Dataset(i,:)); 
      if (isempty(c))
       continue; %空行,重新读下一行
      end
      T{NumEvent,1}=c;
      NumEvent = NumEvent+1;
  end
  NumEvent = NumEvent-1;
  %存放当前频繁项,item
L=zeros(1,2);
%第一次扫描Dataset,统计每一个候选项,并存在二维数组中
%对所有item进行统计,并按支持度递减排序  
NumEvent=size(T,1);
for i=1:NumEvent
    for j=1:length(T{i})
        %寻找当前项在L中是否已经存在
        result=find(L(:,1)==T{i}(1,j));
        if isempty(result)
            %如不存在,则新建一行,支持度为1
            L=cat(1,L,[T{i}(1,j),1]); %串联数组
        else
            %如存在,则支持度加1
            L(result,2)=L(result,2)+1;
        end
    end
end
%将L的第一行赋空
L(1,:)=[];
%按照支持度递减排序,
L=sortrows(L,-2);%L:所有项的降序排列
%idx = L(:, 2)/NumEvent < MST;
%L(idx, :) = [];
%存储FP树
tree=cell(1,2);
%第二次扫描事务数据库Dataset,构造FP树,
for i=1:NumEvent
    L_temp=[];
    %把每一个事务中的item按照其支持度进行排序
    for j=1:length(T{i})
        result=find(L(:,1)==T{i}(1,j));
        if isempty(result)==0
            L_temp=cat(1,L_temp,L(result,:));
        end
    end
    if ~isempty(L_temp)
      L_temp=sortrows(L_temp,-2);
      L_temp=(L_temp(:,1))';
      tree=treeFunc(L_temp,tree,1,i);      
    end
end
%进行模式挖掘
%对L按支持度的升序重新排序
L=sortrows(L,2);
%对L的每一项进行频繁项的挖掘
%最终的频繁项
freqItems=cell(1,1);
%频繁项计数
n=1;
%临时频繁项存储
freqItems_temp=cell(1,1);
for i=1:size(L,1)-1
    frequentItem=cell(1,1);
    item=[];
    %找出所有包含L(i,1)项
    frequentItem=ruleMining(L(i,1),tree,item,frequentItem);
    frequentItem(1,:)=[];
    if isempty(frequentItem)
        continue;
    end
    %构造条件树
    conditionTree=cell(1,2);
    conditionItem=zeros(1,2);
    for j=1:size(frequentItem,1)
        if size(frequentItem{j,1},2)~=0
            flag_2=0;
            p=0;
            %conditionTree的行代表在条件树起始节点null下,有几个分支
            if size(conditionTree{1,1},2)~=0
                for x=1:size(conditionTree,1)
                    if conditionTree{x,1}==frequentItem{j,1}(1,1)
                        conditionTree{x,2}(1,2)=conditionTree{x,2}(1,2)+frequentItem{j,1}(1,2);
                        flag_2=1;
                        p=x;
                        break;
                    end
                end                
            end
 
            if flag_2==0
                p=size(conditionTree,1)+1;
                conditionTree{p,1}=frequentItem{j,1}(1,1);
                conditionTree{p,2}=[frequentItem{j,1}(1,1),frequentItem{j,1}(1,size(frequentItem{j,1},2))];
                if size(conditionTree{1,1},2)==0
                    conditionTree(1,:)=[];
                    p=p-1;
                end
            end
            if size(conditionTree{p,2},2)==0
                conditionTree{p,2}=conditionItem;
                conditionItem=conditionTree{p,2};
            else
                conditionItem=conditionTree{p,2};
            end
 
            %验证conditionItem是否已经存在,如存在则直接将频繁项的数量可以直接相加
            for  m=2:size(frequentItem{j,1},2)-1
                flag=0;
                for n=1:size(conditionItem,1)
                    if conditionItem(n,1)==frequentItem{j,1}(1,m)
                        conditionItem(n,2)=conditionItem(n,2)+frequentItem{j,1}(1,size(frequentItem{j,1},2));
                        flag=1;
                        break;
                    end
                end
                if flag==0
                    conditionItem=cat(1,conditionItem,[frequentItem{j,1}(1,m),frequentItem{j,1}(1,size(frequentItem{j,1},2))]);
                end
            end
            conditionTree{p,2}=conditionItem;
        end
    end
    %对生成的条件树进行最小支持度过滤,
    for k=1:size(conditionTree,1)
        %对支持度小于MST的进行过滤
        conditionItem=conditionTree{k,2};   
        if isempty(conditionItem)
            continue;
        end
        result=find(conditionItem(:,2)/NumEvent<MST);
        row=unique(result);
        conditionItem(row,:)=[];        
        %对剩余item进行组合,需要把当前的
        result=find(conditionItem(:,1)==L(i,1));        
        row=unique(result);
        currentItem=conditionItem(row,:);
        conditionItem(row,:)=[];
        %取出所有item项
        c=conditionItem(:,1)';
        c_temp=cell(1,1);
        %对Item进行组合,并生成频繁项
        for m=1:length(c)
            %组合
            C=nchoosek(1:1:length(c),m);
            %取最小值
            for p=1:size(C,1)
                cItem=currentItem;
                for q=1:size(C,2)
                    cItem=cat(1,cItem,conditionItem(C(p,q),:));
                end
                %求支持度最小的项
                [x,y]=min(cItem(:,2));
                %得到频繁项
                freqItems_temp{n,1}=cItem(:,1)';
                fItem=cat(2,cItem(:,1)',cItem(y,2));
                freqItems{n,1}=fItem;
                n=n+1;
            end
         end
    end
end
%------------------对重复的频繁项进行合并----------------------------------
%临时频繁项集,与上面的频繁项集基本一致,只是少了最后一列的支持度计数,目的
%是为了比较两个频繁项是否一致,以便进行合并
freqItems = freqItems(~cellfun('isempty', freqItems));
freqItems_temp = freqItems_temp(~cellfun('isempty', freqItems_temp));
while size(freqItems_temp,1)>1
    for i=1:size(freqItems_temp,1)-1
        flag=0;
        for j=i+1:size(freqItems_temp,1)
            if isequal(freqItems_temp{i,1},freqItems_temp{j,1})
                %将临时频繁项的重复项进行合并
                freqItems_temp(j,:)=[];
                %将重复的频繁项最后的一列的支持度计数进行合并
                freqItems{i,1}(1,size(freqItems{i,1},2))=freqItems{i,1}(1,size(freqItems{i,1},2))+freqItems{j,1}(1,size(freqItems{j,1},2));
                %将频繁项中的重复项清除
                freqItems(j,:)=[];
                flag=1;
                break;
            end
        end
        if flag==1
            break;
        end
     end
     if i==size(freqItems_temp,1)-1
         break;
     end
end
i = size(freqItems_temp,1)-1;
j = i+1;
if i>0 && isequal(freqItems_temp{i,1},freqItems_temp{j,1})
    freqItems_temp(j,:)=[];
    freqItems{i,1}(1,size(freqItems{i,1},2))=freqItems{i,1}(1,size(freqItems{i,1},2))+freqItems{j,1}(1,size(freqItems{j,1},2));
    freqItems(j,:)=[];
end
%显示频繁项集
%对每个频繁项集中的元素升序排列,方便后续权重更新
Freqset = freqItems_temp;
Freqset = cellfun(@(x) sort(x), freqItems_temp, 'UniformOutput', false);
disp(Freqset);
%%求每个频繁项来自的事务数据索引T_idx,及在种群(Weight)中的索引Pop_idx,并更新频繁项集的权重
T_idx   = cell(size(Freqset));
Pop_idx = cell(size(Freqset));
Freq_weight =zeros(size(Freqset,1),size(Dataset,2));
for i = 1:numel(Freqset)
    for j = 1:numel(T)
        if isequal(Freqset{i,1}, intersect(Freqset{i,1}, T{j}))
           T_idx{i,1} = [T_idx{i,1} j];
        end
    end
    indices = find(FrontNo==1);
    Pop_idx{i,1} = indices(1,T_idx{i,1});
    for k = 1:size(Freqset{i,1},2)
        SelectWeights = Weight(Pop_idx{i,1},Freqset{i,1}(1,k));
        Freq_weight(i,Freqset{i,1}(1,k)) = mean(SelectWeights);
    end
end
 
%%将实数矩阵转换为0,
% 创建全零矩阵
Freq = zeros(size(Freqset, 1), size(Dataset, 2));
 
% 对于每一行,将数据中的整数值对应的逻辑索引设为 1
for i = 1:size(Freqset, 1)
    logicalIndexes = false(1, size(Dataset, 2));
    % 遍历该行数据中的每个整数值,将其对应的逻辑索引设为 1
    for j = 1:numel(Freqset{i})
        logicalIndexes(Freqset{i}(j)) = true;
    end
    % 将该行数据中未包含的维度对应的逻辑索引设为 0
    logicalIndexes(setdiff(1:size(Dataset, 2), Freqset{i})) = false;
    % 将该行逻辑索引赋值给逻辑矩阵
    Freq(i, :) = logicalIndexes;
end
 
% 输出逻辑矩阵
Freq
end

如上问题有来自我自身项目开发,有的收集网站,有的来自读者…如有侵权,立马删除。

解决方案

  如下是上述问题的解决方案,仅供参考:

  FP-Growth算法在处理大规模数据集时可能会消耗大量内存,这主要是因为以下几个原因:

  1. 使用cell数组存储事务:在您的代码中,TfreqItems等变量使用cell数组来存储事务集合。Cell数组在MATLAB中是非常灵活的,但同时也是内存消耗大户。每个事务都是一个独立的数组,这会导致大量的内存分配。

  2. 频繁项集的存储方式freqItems使用二维数组来存储频繁项集,其中包含事务标识和支持度。如果频繁项集很大,这将消耗大量内存。

  3. 重复的内存分配和释放:在代码中,多次使用catsortrows等函数,这些操作可能涉及到重复的内存分配和释放,增加了内存的消耗。

  4. 权重更新部分的循环:在权重更新部分,多重循环嵌套可能导致对大型数据集的处理效率低下。

为了减少内存消耗,您可以尝试以下优化方法:

  1. 优化事务存储:考虑使用其他数据结构,如矩阵或表(table),来存储事务数据,以减少内存使用。

  2. 减少cell数组的使用:尽量避免使用cell数组,或者在必要时再转换为cell类型。

  3. 优化频繁项集的存储:考虑使用更加紧凑的数据结构来存储频繁项集,例如使用结构体数组(struct array)。

  4. 避免重复的内存操作:尽量减少使用catsortrows等可能导致大量内存分配的操作。

  5. 使用内置函数:尽可能使用MATLAB内置函数,它们通常经过优化,比自定义实现更高效。

  6. 分批处理:如果数据集非常大,考虑将数据分批处理,而不是一次性加载到内存中。

  7. 内存清理:在循环结束后,及时清理不再使用的变量,使用clearclearvars命令释放内存。

  8. 分析内存使用:使用MATLAB的memory函数来分析内存使用情况,找出内存消耗的瓶颈。

  9. 并行计算:如果可能,使用MATLAB的并行计算工具箱来加速处理过程。

请注意,这些只是一些通用的建议,具体的优化方案需要根据实际的代码和数据集来定制。如果您不熟悉MATLAB的内存管理和优化技巧,可能需要进一步学习或寻求专业帮助。

  希望如上措施及解决方案能够帮到有需要的你。

  PS:如若遇到采纳如下方案还是未解决的同学,希望不要抱怨&&急躁,毕竟影响因素众多,我写出来也是希望能够尽最大努力帮助到同类似问题的小伙伴,即把你未解决或者产生新Bug黏贴在评论区,我们大家一起来努力,一起帮你看看,可以不咯。

  若有对当前Bug有与如下提供的方法不一致,有个不情之请,希望你能把你的新思路或新方法分享到评论区,一起学习,目的就是帮助更多所需要的同学,正所谓「赠人玫瑰,手留余香」。

☀️写在最后

  ok,以上就是我这期的Bug修复内容啦,如果还想查找更多解决方案,你可以看看我专门收集Bug及提供解决方案的专栏《CSDN问答解惑-专业版》,都是实战中碰到的Bug,希望对你有所帮助。到此,咱们下期拜拜。

码字不易,如果这篇文章对你有所帮助,帮忙给 bug菌 来个一键三连(关注、点赞、收藏) ,您的支持就是我坚持写作分享知识点传播技术的最大动力。

同时也推荐大家关注我的硬核公众号:「猿圈奇妙屋」 ;以第一手学习bug菌的首发干货,不仅能学习更多技术硬货,还可白嫖最新BAT大厂面试真题、4000G Pdf技术书籍、万份简历/PPT模板、技术文章Markdown文档等海量资料,你想要的我都有!

📣关于我

我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云2023年度十佳博主,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿哇。


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

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

相关文章

随记 - 2024 年 4 月 12 日

写在前面 444 字 | 生活 | 经历 | 感触 正文 或许因为压力大&#xff0c;亦或者简单的糖分不足&#xff0c;今晚好想吃面包和蛋糕。 蛋糕吃不完也买不起&#xff0c;面包还是可以。 实在饿&#xff0c;出门了。 导航两家西点店&#xff0c;关门。怏怏地找另一家。 在十点前&a…

效果炫酷的3D翻转书特效WordPress主题模板MagicBook主题v1.19

正文&#xff1a; MagicBook是一款支持3D翻书特效的书籍WordPress主题。支持可视化页面搭建&#xff0c;3D菜单&#xff0c;完全自适应设计,WPML多语言支持。 这款主题一定会让你爱不释手。虽然他是英文的&#xff0c;但不可不承认的是&#xff0c;它优雅的设计会让你愿意花时…

[Linux]将一个文件复制到多个文件夹下

一、简介 本文介绍了在linux下如何使用cp命令将一个文件复制到多个文件夹、多个文件复制到一个文件夹和多个文件复制到多个文件夹下。 二、代码 假设初始时test/文件夹的结构如下&#xff1a; 1. 将一个文件复制到多个文件夹 a.命令示例 将file1复制到目录des_dir1/&#…

【PGCCC】pg_bestmatch.rs:使用 BM25 提升您的 PostgreSQL 文本查询#PCA

这是一个 PostgreSQL 扩展&#xff0c;它将最佳匹配 25 分数 (BM25) 文本查询的强大功能引入您的数据库&#xff0c;从而增强您执行高效和准确的文本检索的能力。此扩展允许用户从文本生成 BM25 统计稀疏向量&#xff0c;利用 BM25 在各种基准测试任务中经过验证的性能。 为什…

8.16 QT

1.思维导图 2 将day1做的登录界面升级优化【资源文件的添加】 2> 在登录界面的登录取消按钮进行一下设置&#xff1a; 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5…

《SPSS零基础入门教程》学习笔记——03.变量的统计描述

文章目录 3.1 连续变量&#xff08;1&#xff09;集中趋势&#xff08;2&#xff09;离散趋势&#xff08;3&#xff09;分布特征 3.2 分类变量&#xff08;1&#xff09;单个分类变量&#xff08;2&#xff09;多个分类变量 3.1 连续变量 &#xff08;1&#xff09;集中趋势 …

使用 Python 解密加密的 PDF 文件

使用 Python 进行 PDF 文件加密-CSDN博客文章浏览阅读89次&#xff0c;点赞2次&#xff0c;收藏2次。定义一个名为的函数&#xff0c;该函数接受三个参数&#xff1a;输入的 PDF 文件路径input_pdf、输出的加密 PDF 文件路径output_pdf和密码password。https://blog.csdn.net/q…

django中的MESSAGE组件

文章目录 message组件1 使用配置2 设置值3 读取值4 源码分析 message组件 1 使用配置 INSTALLED_APPS [# django.contrib.admin,# django.contrib.auth,# django.contrib.contenttypes,# django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,"…

AI编程工具合集【请按需收藏】

成长路上不孤单&#x1f60a;【14后小学生一枚&#xff0c;C爱好者&#xff0c;持续分享所学&#xff0c;如有需要欢迎收藏转发&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;】 关于【AI编程工具合集】 在编程领域&#xff0c…

C ICU webassembly库编译

准备环境 在本机搭建Linux环境_本地单机搭建linux系统-CSDN博客 C wasm 使用教程-CSDN博客 法一 git clone https://github.com/mabels/icu.git git checkout -b release-65-1 git diff -p wasm32-start..remotes/origin/wasm32 | patch -p1 cd icu4c/source ./runConfigu…

C#工具库-NPOI

一、简介 NPOI是一个基于c#语言的&#xff0c;开源的&#xff0c;能够在不安装Microsoft Office组件的条件下读写Microsoft Office 的库。前身是Java的POI库,有“先贤”将其翻译成了c#语言的库&#xff0c;而这种由java到c#库的演变并非个例&#xff0c;比如DotNetty之于Netty,…

云动态摘要 2024-08-17

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 注册阿里云免费领云服务器_云服务器ECS_阿里云 阿里云 2024-08-14 云上试用新玩法&#xff0c;个人享300元免费额度&#xff0c;企业享660元免费额度&#xff0c;多种规格随心试 [免费体验…

恒创科技:云服务器的备份和快照哪个更好?

云服务器的备份和快照都是为了保护数据和恢复系统状态的重要手段&#xff0c;但它们有不同的应用场景和特点。在本指南中&#xff0c;我们将探讨这些数据管理方法之间的差异、它们的优点和局限性。 什么是备份? 想象一下&#xff0c;备份就是数据的“时间胶囊”。它们就像老相…

蓝盆花:神秘而迷人的自然之美

一、蓝盆花的形态特征 蓝盆花是多年生草本植物&#xff0c;植株高度通常在30 – 80厘米之间。茎直立&#xff0c;黄白色或带紫色&#xff0c;具棱&#xff0c;自基部分枝&#xff0c;节间长6 – 12厘米&#xff0c;疏或密被贴伏白色短柔毛。 蓝盆花的叶形态多样。基生叶成丛&a…

Nginx 核心配置详解

章节 1 NGINX 的源码安装 2 NGINX 核心配置详解 3 NGINX 之 location 匹配优先级 4 NGINX 基础参数与功能 目录 1 配置文件说明 1.1 nginx 配置文件格式说明 1.2 Nginx 主配置文件的配置指令方式&#xff1a; 1.3 主配置文件结构&#xff1a;四部分 1.4 nginx 文件作用解…

1. 数据结构——顺序表的主要操作

1. 内容 顺序表的初始化、插入、删除、按值查找、输出以及其时间复杂度的计算。 2.代码 #include<stdio.h> #include<stdlib.h> //函数结果状态代码 #define OK 1 #define OVERFLOW -2 #define ERROR 0 #define MAXSIZE 100typedef int ElemType; //顺序表每个…

Vue.js入门系列(九):表单数据处理、过滤器及常用指令

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

Linux环境开发工具【yum与vim】

&#x1f308;个人主页&#xff1a;Yui_ &#x1f308;Linux专栏&#xff1a;Linux &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;数据结构专栏&#xff1a;数据结构 文章目录 1.Linux软件包管理器yum1.1 快速使用yum 2. Linux编辑器-vim的使用2.1 vim的基本…

机器学习——XGBoost

目录 一、初识XGBoost 1. 介绍 2. 使用 XGBoost 的方法 &#xff08;1&#xff09;直接使用xgboost库自己的建模流程 &#xff08;2&#xff09;使用xgboost库中的sklearn的API 3. XGBoost的三大板块 4. 提升集成算法 5. 建模流程 二、模型常用参数 1. n_estimators …

Leetcode每日刷题之611.有效三角形的个数(C++)

1. 思路解析 根据题意我们可知&#xff0c;我们需要在指定数组中找出任意三个数并判断是否可以组成一个三角形&#xff0c;即任意两数之和大于第三个数&#xff0c;任意两数之差小于第三个数&#xff0c;如果有数组元素相同的数组&#xff0c;由于取出的元素只是数值相同而实际…