MATLAB实现基于BAG-GRU 装袋集成(BAG)结合门控循环单元(GRU)进行股票价格预测的详细项目实例

请注意此篇内容只是一个项目介绍 更多详细内容可直接联系博主本人 

 或者访问对应标题的完整博客或者文档下载页面(含完整的程序,GUI设计和代码详解)

在金融时间序列建模领域,股价预测始终被视为一项难度极高但又极具实用价值的任务。传统金融理论强调市场的随机性和效率,认为价格走势在很大程度上难以准确预判,但随着数据驱动方法和深度学习技术的迅速发展,越来越多研究逐步证明,在合理的数据预处理、特征构造和模型架构设计条件下,可以在控制风险前提下,从股价及相关因子中挖掘出一定程度上可利用的统计规律,从而为投资决策、风险管理、量化交易等实际业务提供辅助支撑。这一背景使得基于数据挖掘和机器学习的股价预测模型,尤其是使用深度学习网络的序列预测模型,逐渐成为金融工程与人工智能交叉研究的核心方向之一。

在众多时间序列预测模型中,循环神经网络家族因能够对序列数据中的时间依赖关系进行建模而受到广泛关注。传统的RNN在面对长序列数据时易出现梯度消失或梯度爆炸问题,因此衍生出了诸如LSTM和GRU等带门控结构的改进网络,其中GRU通过重置门和更新门机制,在结构上相对精简,同时仍可有效捕捉长期依赖,具有参数更少、收敛更快、易于训练等优势。对于股票价格这一典型的非平稳、噪声较多且存在非线性关系的时间序列,GRU能够在抑制梯度问题的同时更灵活地记忆与遗忘历史信息,因此非常适合作为核心预测模型。

然而,单一神经网络模型往往存在一定的不稳定性和模型偏差。例如,不同的随机初始化、不同的训练子集、不同的超参数组合都可能导致预测性能出现较大波动。同时,股市本身存在结构性变化、阶段性行情风格转换、突发事件等影响因素,导致任何一个单一模型都可能在特定时间段或特定市场环境下出现性能退化。为提升整体模型的稳健性和泛化能力,集成学习思想逐渐引入到深度学习的时间序列预测场景,其中装袋集成(Bagging,装袋)是一种简单而有效的集成策略,通过在不同的自助采样子集上训练多个基学习器,再将各个基学习器的输出进行平均或投票,可显著降低模型方差,提升预测结果的稳定性。

基于上述背景,将Bagging与GRU结合构建BAG-GRU装袋集成模型,用于股票收盘价或收益率的预测,是一个兼具理论研究价值与实践应用意义的方向。Bagging部分主要通过自助采样方式从原始训练集产生多个子数据集,每个子集上单独训练一个GRU子模型,这些子模型拥有相同的网络结构但在参数、样本分布上存在差异,从而形成一个模型“群体”。在预测阶段,将多个GRU子模型对未来股票价格的预测结果进行加权平均或简单平均,使得单个模型的偶然误差在集成层面被相互抵消,从而获得更平滑、更稳定的预测序列。这样的BAG-GRU架构既继承了GRU对时序依赖建模的能力,又融合了Bagging对模型方差的抑制能力,能够更好适应高噪声、非线性和包含异常波动的金融时间序列。

在工程实现层面,MATLAB为金融时间序列分析和深度学习建模提供了较为成熟的工具链。通过Financial Toolbox、Statistics and Machine Learning Toolbox和Deep Learning Toolbox,可以方便地完成数据导入、缺失值处理、特征工程、网络搭建、训练调参、结果可视化等全流程工作。MATLAB R2025b在深度学习方面的基础语法和类接口仍延续了前几代版本的设计,同时对部分图形界面组件与可视化属性进行了调整。基于这种环境实现BAG-GRU项目,既能充分利用成熟的矩阵运算和深度学习函数,也可以通过脚本与函数的方式形成清晰可维护的工程结构。

在实际应用场景中,股票价格预测任务通常需要处理大量历史日线数据、分钟线数据甚至更高频的Tick数据,本项目以日线或小时级别数据为基础,结合常见的开盘价、最高价、最低价、收盘价、成交量以及一些衍生技术指标(如移动平均、RSI、MACD等)构成特征序列,通过滑动窗口方式将连续历史数据映射为“输入序列—目标值”的监督学习样本。通过BAG-GRU模型对目标股票的未来若干时间步(例如1天、3天、5天)的价格或收益率进行连续预测,从而形成可解释的时间序列预测方案,为量化策略回测和实际交易系统提供基础预测信号。

综合上述背景,本项目围绕“基于BAG-GRU装袋集成结合门控循环单元进行股票价格预测”这一核心主题,从理论、算法、工程和应用多个层面展开,既强调模型构建与算法细节,也注重在MATLAB环境下给出完整的可执行实例代码,为后续在不同市场、不同股票或不同频率数据上的推广提供一个结构清晰、逻辑完整、可复用的实现样板。

项目目标与意义

提升股票价格预测的稳定性与泛化能力

本项目的首要目标是构建一个能够在多种市场环境下保持相对稳定预测性能的股票价格预测模型。传统单模型GRU在某一时段内可能表现良好,但在行情结构发生变化时容易出现预测偏差增大、波动性上升等问题。通过在MATLAB环境中实现装袋集成策略,对同一目标股票的历史数据进行多次自助采样,训练多个结构相同但参数不同的GRU子模型,再对其预测输出进行集成,从而显著降低对单一训练集划分和单次随机初始化的依赖程度。集成后的预测结果在统计意义上能够有效减小方差,使得模型在回测与前向预测过程中,对偶然的噪声和样本偏差不再过度敏感,预测曲线更加平滑、稳健。提升稳定性与泛化能力的意义不仅体现在误差指标的改善上,更体现在在真实交易环境中能够更好抵御异常行情与突发冲击,减少由于模型不稳定造成的频繁调参或模型更换,从而降低策略维护成本,增强量化系统运行的连续性和可靠性。

实现基于MATLAB的端到端BAG-GRU建模流程

本项目的第二个目标是基于MATLAB R2025b构建完整的端到端BAG-GRU建模流程,从数据读取、预处理、特征工程、样本构造、模型定义、训练、集成预测到误差评估与结果可视化,形成一套具有较强可操作性的工程化方案。许多深度学习示例往往只给出核心网络部分,而忽略整个工程流程中大量关键的细节处理,例如时间序列的滑动窗口生成、训练集和测试集的时间切分策略、数据归一化与反归一化、批量大小与序列长度选择等。本项目通过详细展示从原始股票CSV文件读入到最终输出预测曲线全过程的MATLAB脚本和函数调用,使得整个BAG-GRU模型不仅在理论上可行,而且在代码层面可以直接运行和调整,便于在实际工作中快速迁移到不同股票、不同时间段或不同市场数据上。这个目标对于金融工程实践者具有现实意义,因为在生产环境中需要的是可复用、可维护、可扩展的完整流程,而不是零散的片段代码。

探索BAG-GRU在不同预测任务和特征组合下的表现

第三个目标是利用BAG-GRU架构,探索在不同预测任务设定和特征组合方案下模型性能的异同,为后续的策略设计提供经验参考。股票价格预测可以有多种任务形式,例如直接预测未来收盘价的回归问题、预测未来收益率的回归问题、预测价格上涨或下跌方向的分类问题,本项目聚焦于回归型价格或收益率预测,但依然可以在模型输入维度和预测步长上进行多种尝试。通过对比只使用收盘价一维特征与加入成交量、技术指标等多维特征的效果,可以定量评估特征扩展对预测性能的贡献;通过设置不同预测步长(如1步、3步、5步)和不同滑动窗口长度,可以分析模型对短期与中期趋势的适应能力差异。通过在MATLAB中实现灵活的参数配置和多组实验,系统地记录和比较不同配置下的误差指标,为后续在实盘系统中选择最合适的预测设定提供数据支持。

为量化投资与风险管理提供可扩展的预测模块

第四个目标是将BAG-GRU预测模型定位为量化投资与风险管理系统中的一个可扩展预测模块,而不仅仅是一个独立的学术示例。在实际量化交易系统中,往往需要在选股、择时、仓位控制、风险预警等多个层级综合利用各种信号和指标。BAG-GRU模型所输出的未来价格或收益率预测值,可以作为构建多因子模型中的一类“预测因子”,也可以为算法交易策略提供辅助的趋势判断依据,从而影响买入、卖出和持仓调整决策。同时,风险管理部门可以利用预测分布与历史实际误差的统计特征,对模型风险进行评估,例如监控预测误差是否在可接受范围内,是否需要重新训练或调整模型。通过在MATLAB中严格实现可重复的训练和预测流程,本项目所构建的BAG-GRU模块能够嵌入到更大的系统架构中,与其他金融数据处理模块协同工作,为机构和个人投资者提供一个可连续演进的、面向实战环境的模型基础。

项目挑战及解决方案

非平稳高噪声金融时间序列的建模挑战与缓解策略

股票价格序列具有显著的非平稳特征,包括趋势变化、波动率聚集、跳跃以及结构性断点等,同时受宏观经济、行业政策、市场情绪和突发事件等多种因素叠加影响,噪声成分较高。传统线性模型如ARIMA等往往难以充分捕捉这类复杂非线性关系,即便深度网络在理论上具有强大的拟合能力,如果数据预处理不当,也容易出现学习到的是噪声而非有效信号的问题。在这种背景下,首先需要在数据层面通过合适的预处理与特征工程缓解非平稳性。例如可以使用收益率代替原始价格作为预测对象,通过对收盘价取对数差分,将绝对价格水平的趋势性部分转化为相对变化,从而提升序列的平稳性。还可以采用滑动标准化、归一化方法,使不同时间段的数据分布更接近。此外,通过引入技术指标与成交量等辅助特征,为模型提供更多与行情状态相关的信息,使GRU网络能借助门控机制在不同市场阶段学习到更合理的状态转移模式。Bagging策略在此处也起到一定缓冲作用,不同子模型在不同采样子集上学习到的模式不完全相同,集成后的结果可以在一定程度上减弱个别子模型因噪声过拟合带来的偏差,从而获得更加稳定的输出。在MATLAB实现时,需要特别注意时间序列的窗口切分要严格保持时间顺序,防止数据泄露,这也是应对非平稳序列建模时的关键工程细节。

深度模型训练不稳定与超参数敏感性的挑战及处理思路

GRU作为一种循环神经网络,训练过程涉及大量参数更新,对初始权重、学习率、批量大小、网络层数和隐含单元数等敏感度较高。如果没有合理的超参数配置与训练策略,模型可能出现收敛缓慢、陷入局部最优、甚至训练发散的情况。对于BAG-GRU装袋集成结构而言,这一挑战被放大为多模型训练的稳定性问题。针对这一挑战,解决方案从几方面展开。首先,在MATLAB中通过系统化的实验设计,对关键超参数进行网格或分层搜索,在合理范围内寻找较优组合,尽量保证每个子模型都能在有限训练周期内稳定收敛。其次,在训练过程中采用适当的学习率调度机制,例如在验证集损失不再明显下降时降低学习率,从而获得更平滑的收敛曲线。再次,Bagging本身通过多模型集成减弱了对单一子模型性能的过度依赖,因此可以适当降低每个子模型的复杂度,如控制网络层数和隐含单元数,以减少过拟合和训练不稳定的风险。为了避免在工程实现中产生过多冗余,MATLAB脚本将以循环形式构建多个GRU网络,并保持统一的训练选项配置,通过固定随机种子和有效控制训练轮数,使整个训练过程可重复、可复现。这样既保证了集成模型整体性能,又在一定程度上缓解了深度网络在金融数据上的训练敏感性问题。

MATLAB环境下实现BAG-GRU模型的工程复杂度与兼容性问题

在MATLAB R2025b环境中实现BAG-GRU模型,需要同时兼顾深度学习网络的定义与训练、时间序列处理、可视化展示等多个模块。工程复杂度主要体现在:一是需要手动管理多个GRU子网络的构建和训练状态,二是需要根据R2025b的接口规范合理使用figure与uicontrol进行简单交互或展示,三是注意版本中特有的一些函数使用限制和属性变更。例如在深度学习网络上,采用layerGraph或layer数组构建序列网络,利用trainNetwork进行训练,避免使用已经不再推荐的接口。在图形界面和可视化上,使用经典figure和axes组合,而不是依赖被限制的UI组件。集成预测层面需要设计合理的数据结构保存多个子模型及其预测输出,在预测阶段实现批量推理与结果聚合。针对这些工程挑战,MATLAB实现方案将采用模块化脚本结构,将数据预处理、模型建立、训练和预测分别封装为独立代码段,通过清晰的变量命名和注释提高可读性;同时在关键步骤中设置断点式可视化,例如训练前后绘制归一化后的实际价格与预测价格曲线,利用colormap(fig, turbo)控制颜色映射,确保与R2025b的可视化规范一致。通过这种方式,在保证功能完备的前提下,有效控制工程复杂度,并在版本兼容性方面规避潜在错误,使BAG-GRU项目具备长期维护和扩展的基础。

项目模型架构

数据预处理与时间序列样本构造架构

BAG-GRU模型的整体架构自底向上可划分为若干层,其中最底层是数据预处理与样本构造部分,这一部分直接决定后续GRU网络接收到的输入形式与质量。在股票价格预测任务中,原始数据通常以CSV格式存储,包含交易日期、开盘价、最高价、最低价、收盘价、成交量等列。首先需要在MATLAB中使用readtable或readmatrix读入数据,通过排序和重复日期检查,确保时间顺序的完整与一致。针对缺失值,可采用前向填充或删除所在行的策略,根据缺失比例与时间段重要性进行选择。为了增强模型对变化率而非绝对价格的敏感度,可以从收盘价计算对数收益率,将价格序列转换为更接近平稳的收益率序列。接着,利用归一化函数对多维特征进行缩放,常用方法包括min-max归一化或z-score标准化,目的是避免不同量纲特征在网络训练时影响不均衡。时间序列样本构造采用滑动窗口机制,将连续的L个时间步作为输入序列,将第L+1个时间步的目标值作为预测对象,从而构成一对一的监督学习样本。在MATLAB中,可以通过for循环遍历时间序列长度,将每个窗口对应的特征子矩阵存入三维数组或cell数组中,这样便于后续使用trainNetwork进行序列回归训练。数据划分方面,应按照时间顺序将前一部分作为训练集,中间一小部分作为验证集,最后一段最新数据作为测试集,严禁使用随机打乱方式,以避免未来信息泄露到训练阶段,确保评估结果具有真实意义。

GRU单模型结构设计与门控机制原理

BAG-GRU结构的核心基础单元是GRU子模型,GRU(Gated Recurrent Unit)通过门控机制来控制信息在时间上的传递与遗忘。单个GRU单元包含两个主要门:重置门和更新门。重置门用于控制当前输入与上一时刻隐藏状态的融合程度,当重置门值较小时,模型倾向于忽略过去信息,更关注当前输入;更新门用于平衡上一时刻隐藏状态与当前候选状态的权重,当更新门接近1时,模型更倾向于保留过去记忆,从而有助于捕捉长期依赖。在具体网络结构设计上,单个GRU子模型一般包含输入层、一个或多个GRU层、一个全连接回归输出层以及回归损失层。在MATLAB中可以采用sequenceInputLayer定义输入层维度,使用gruLayer设置隐藏单元数量并启用合适的权重初始化方式,然后配合fullyConnectedLayer将GRU最后一个时间步的隐藏状态映射到标量输出,再通过regressionLayer定义损失函数为均方误差。为了防止过拟合,可以在GRU层与全连接层之间加入dropoutLayer,通过随机丢弃部分神经元节点来提升泛化能力。单个GRU模型的深度和宽度需要结合数据量和任务复杂度来选择,一般在金融时间序列中,1至2层GRU、中等数量的隐藏单元即可取得较好效果,过深的网络在样本有限情况下可能带来过拟合风险。

装袋集成(Bagging)策略与多模型结构组织方式

在单模型GRU结构之上,BAG-GRU采用装袋集成策略构建一个多子模型集成框架。Bagging的核心思想是通过自助采样(Bootstrap)从原始训练集生成多个具备相同大小但样本组合不同的子训练集,每个子训练集上独立训练一个基学习器,最终对各个基学习器的输出进行平均或投票。应用于股票价格预测时,在MATLAB中可通过对训练样本索引执行带放回随机采样的方式生成不同子集索引,然后根据这些索引构建对应的训练数据块。多个GRU子模型可以采用相同的网络结构和训练选项,但由于训练数据不同以及随机初始化的差异,训练出的参数也各不相同。在结构组织上,可以使用cell数组或结构数组保存各个子模型对象,方便统一管理与调用。例如定义一个长度为nModels的cell,每个元素存放一个训练好的网络。预测阶段,将测试序列输入到每个子模型中,收集所有预测结果,再按模型维度进行平均。这样一方面通过分散个别模型的误差降低整体方差,另一方面不同子模型可以对数据的不同子结构产生侧重,这种多样性是集成学习取得性能提升的关键。Bagging对模型偏差的影响较小,但在减小方差方面非常有效,对于金融价格预测这种高度不确定的任务,方差控制往往比单点最优预测更为重要,因此BAG-GRU结构在这一点上具有天然优势。

模型训练、推理与误差评估流程架构

在整体架构中,模型训练与推理评估部分起到承上启下的作用。训练阶段需要循环遍历所有子模型,对每个子模型执行训练过程,包括数据选择、网络构建、超参数设置和训练调用。MATLAB中可以使用trainingOptions设置优化算法(如adam)、mini-batch大小、最大轮数、初始学习率等参数,同时指定验证数据与验证频率,以监控模型在训练过程中的泛化情况。训练过程中可视化训练与验证损失曲线,方便判断是否存在过拟合或欠拟合。推理阶段则将训练好的子模型应用于测试集,将每个时间步的输入序列喂入网络获得预测值。由于使用的是回归任务,应在输出层直接获得数值预测结果,并根据是否使用了归一化,在输出侧进行反归一化,将预测值还原为实际的价格或收益率。在误差评估方面,可以计算常见指标,如均方误差(MSE)、均方根误差(RMSE)、平均绝对误差(MAE)以及平均绝对百分比误差(MAPE),全面衡量预测效果。对于BAG-GRU集成输出,可同时对单个子模型和集成平均结果进行对比评估,以直观体现集成策略的收益。此外,可以通过绘制真实价格与预测价格随时间变化的曲线,结合误差指标,判断模型在不同时间区间内的表现是否稳定,是否存在某些特殊阶段预测偏差特别大,从而为后续模型优化提供直观依据。

MATLAB R2025b环境下的实现特点与约束适配架构

MATLAB R2025b在深度学习和可视化方面具有一定的版本特性与约束,项目架构在设计时对这些特性进行了适配。在图形界面层面,避免使用R2025b中受限的高级UI组件,如uilabel、uieditfield和uigridlayout,而是采用传统figure和uicontrol构建简单界面,例如用于展示训练过程或设置参数的按钮和文本标签,使项目在该版本下运行更加稳定。在可视化上,ColorbarVisible属性不再使用,色图设置通过colormap函数直接作用于figure对象,如colormap(figHandle, turbo),并使用axes对象绘制预测曲线与真实曲线。在机器学习部分,注意R2025b对于fitrlinear、fitrnet等传统回归函数的参数限制,但由于项目主要依赖深度学习网络,这部分限制更多是背景性约束,只在扩展模型对比实验时需要关注。对于深度学习网络,在R2025b中依旧可以通过layer数组或layerGraph定义GRU序列网络,使用trainNetwork进行训练,dlnetwork等高级接口虽可用于自定义训练循环,但在本项目中采用标准高层接口即可。通过这些适配与架构设计,本项目在R2025b环境下无需依赖被限制的特性即可完成BAG-GRU模型的构建与运行,确保稳定性与可移植性,同时为后续在其他版本或平台上迁移提供清晰结构参考。

项目模型描述及代码示例

数据读取与基础预处理示例
clc; clear; close all; % 清空命令窗口、工作区变量并关闭所有图窗,保证后续运行环境干净
dataTable = readtable('stock_data.csv'); % 从当前工作目录读取股票历史数据表,文件需包含日期和OHLCV等列
dataTable = sortrows(dataTable,'Date'); % 按日期列升序排序,确保时间顺序从早到晚排列正确
dataTable = rmmissing(dataTable); % 删除含有缺失值的行,避免缺失样本影响GRU训练过程
closePrice = dataTable.Close; % 提取收盘价列数据作为核心价格序列,用于构造目标或计算收益率
volume = dataTable.Volume; % 提取成交量列数据作为辅助特征,刻画市场活跃程度
logRet = diff(log(closePrice)); % 计算相邻交易日对数收益率,将价格序列转换为相对变化序列
logRet = [0; logRet]; % 在序列首部补一个0,保持收益率序列与原始价格长度一致
featMat = [closePrice logRet volume]; % 构造特征矩阵,包含收盘价、对数收益率和成交量三种特征
featMat = filloutliers(featMat,'linear'); % 对特征矩阵中的异常值进行线性插值修正,减弱极端值对训练的干扰
[numSamples,numFeat] = size(featMat); % 获取样本数量与特征维度,用于后续窗口划分与网络输入大小设置
trainRatio = 0.7; % 设置训练集比例为70%,用于确定时间序列划分边界
valRatio = 0.15; % 设置验证集比例为15%,用于训练过程中监控泛化性能
testRatio = 0.15; % 设置测试集比例为15%,用于最终性能评估
trainEnd = floor(numSamples * trainRatio); % 计算训练集结束索引位置,基于总样本数量和比例
valEnd = floor(numSamples * (trainRatio + valRatio)); % 计算验证集结束索引位置,将中间一段划分为验证集
featTrain = featMat(1:trainEnd,:); % 提取训练集特征数据块,用于模型拟合
featVal = featMat(trainEnd+1:valEnd,:); % 提取验证集特征数据块,用于训练过程调优
featTest = featMat(valEnd+1:end,:); % 提取测试集特征数据块,用于独立评估模型效果
[targetScalerMean,targetScalerStd] = deal(mean(featTrain(:,1)),std(featTrain(:,1))); % 记录训练集中收盘价均值和标准差,用于后续归一化与反归一化
normFeatTrain = (featTrain - mean(featTrain))./std(featTrain); % 使用z-score方法对训练特征矩阵进行标准化,提升数值稳定性
normFeatVal = (featVal - mean(featTrain))./std(featTrain); % 使用训练集均值和标准差对验证集进行同样标准化,保证缩放一致
normFeatTest = (featTest - mean(featTrain))./std(featTrain); % 使用训练集统计量对测试集进行标准化,避免信息泄露
滑动窗口构造序列样本示例
winLen = 20; % 设置时间窗口长度为20,表示以过去20个时间步的特征预测下一步目标
horizon = 1; % 设置预测步长为1,即预测窗口末尾之后第1天的收盘价
[XTrainSeq,YTrainSeq] = deal({}); % 初始化训练输入序列cell和目标输出cell,便于存储变长序列
[XValSeq,YValSeq] = deal({}); % 初始化验证输入序列cell和目标输出cell,用于验证数据集
[XTestSeq,YTestSeq] = deal({}); % 初始化测试输入序列cell和目标输出cell,用于测试数据集
trainSeries = normFeatTrain; % 将归一化训练特征矩阵作为训练时间序列数据源
valSeries = normFeatVal; % 将归一化验证特征矩阵作为验证时间序列数据源
testSeries = normFeatTest; % 将归一化测试特征矩阵作为测试时间序列数据源
trainTargetRaw = featTrain(:,1); % 使用原始训练收盘价作为训练目标基础,用于反归一化误差计算
valTargetRaw = featVal(:,1); % 使用原始验证收盘价作为验证目标基础
testTargetRaw = featTest(:,1); % 使用原始测试收盘价作为测试目标基础
for i = 1:(size(trainSeries,1) - winLen - horizon + 1) % 循环遍历训练序列索引,构造所有可能的窗口样本
    seqInput = trainSeries(i:(i+winLen-1),:)'; % 取当前窗口内的特征数据并转置为[numFeat x winLen],符合sequenceInputLayer格式
    seqTarget = trainTargetRaw(i+winLen+horizon-1); % 对应目标为窗口末尾之后第horizon步的原始收盘价
    XTrainSeq{end+1} = seqInput; % 将当前输入序列矩阵追加到训练输入cell中
    YTrainSeq{end+1} = seqTarget; % 将当前目标标量追加到训练输出cell中
end % 结束训练集窗口构造循环
for i = 1:(size(valSeries,1) - winLen - horizon + 1) % 循环遍历验证序列索引,构造验证窗口样本
    seqInput = valSeries(i:(i+winLen-1),:)'; % 提取验证集当前窗口特征并转置为[numFeat x winLen]
    seqTarget = valTargetRaw(i+winLen+horizon-1); % 对应目标为验证集窗口末尾之后第horizon步收盘价
    XValSeq{end+1} = seqInput; % 将验证输入序列矩阵追加到验证输入cell中
    YValSeq{end+1} = seqTarget; % 将验证输出标量追加到验证输出cell中
end % 结束验证集窗口构造循环
for i = 1:(size(testSeries,1) - winLen - horizon + 1) % 循环遍历测试序列索引,构造测试窗口样本
    seqInput = testSeries(i:(i+winLen-1),:)'; % 提取测试集当前窗口特征并转置为[numFeat x winLen]
    seqTarget = testTargetRaw(i+winLen+horizon-1); % 对应目标为测试集窗口末尾之后第horizon步收盘价
    XTestSeq{end+1} = seqInput; % 将测试输入序列矩阵追加到测试输入cell中
    YTestSeq{end+1} = seqTarget; % 将测试输出标量追加到测试输出cell中
end % 结束测试集窗口构造循环
单个GRU网络结构定义与说明示例
inputSize = numFeat; % 设置输入特征维度为特征矩阵列数,与sequenceInputLayer的输入大小保持一致
numHiddenUnits = 64; % 设置GRU隐藏单元数量为64,在复杂度和训练时间之间取得折中
layers = [ ... % 定义深度学习网络层数组,用于构建序列回归模型
    sequenceInputLayer(inputSize) ... % 序列输入层,接收长度可变的[numFeat x time]输入序列
    gruLayer(numHiddenUnits,'OutputMode','last') ... % GRU层,输出最后一个时间步的隐藏状态用于回归预测
    dropoutLayer(0.2) ... % Dropout层,以0.2概率随机丢弃部分神经元,减缓过拟合风险
    fullyConnectedLayer(1) ... % 全连接层,将隐藏状态映射为一个标量输出,对应未来一步收盘价
    regressionLayer]; % 回归层,使用均方误差损失函数进行回归任务训练
miniBatchSize = 32; % 设置小批量大小为32,在收敛速度和稳定性之间取平衡
maxEpochs = 80; % 设置最大训练轮数为80,在金融时间序列场景通常足以收敛
initialLearnRate = 1e-3; % 设置初始学习率为0.001,保持训练过程平稳而不过快震荡
options = trainingOptions('adam', ... % 指定优化算法为adam,对循环网络训练具有较好鲁棒性
    'MaxEpochs',maxEpochs, ... % 设定训练过程最大的遍历数据轮数
    'MiniBatchSize',miniBatchSize, ... % 指定每次参数更新所使用的小批量样本数量
    'InitialLearnRate',initialLearnRate, ... % 设置初始学习率,影响梯度更新步长
    'GradientThreshold',1, ... % 设置梯度阈值为1,在反向传播时对梯度进行裁剪避免梯度爆炸
    'Shuffle','never', ... % 不在每个epoch打乱样本顺序,保持时间序列的自然顺序
    'ValidationData',{XValSeq,YValSeq}, ... % 指定验证集数据,用于监控训练过程中模型泛化性能
    'ValidationFrequency',floor(numel(XTrainSeq)/miniBatchSize), ... % 指定验证频率大约为每个epoch验证一次
    'Verbose',false, ... % 关闭详细命令行输出,使训练过程更简洁
    'Plots','training-progress'); % 启用训练过程可视化窗口,展示损失曲线与验证性能变化
装袋集成多GRU模型训练示例
nModels = 5; % 设置装袋集成中子模型数量为5,在性能和训练时间之间取得折衷
bagNets = cell(nModels,1); % 初始化cell数组用于保存每个训练好的GRU子模型
numTrainSamples = numel(XTrainSeq); % 获取训练样本数量,用于自助采样生成索引
for m = 1:nModels % 循环遍历每个子模型索引,依次训练多个GRU网络
    bootstrapIdx = randi(numTrainSamples,[numTrainSamples,1]); % 使用带放回随机采样在训练样本索引上生成自助采样索引向量
    XTrainBag = XTrainSeq(bootstrapIdx); % 根据自助索引从训练输入cell中取出对应样本构成子训练集输入
    YTrainBag = YTrainSeq(bootstrapIdx); % 根据自助索引从训练目标cell中取出对应样本构成子训练集输出
    net_m = trainNetwork(XTrainBag,YTrainBag,layers,options); % 调用trainNetwork在当前子训练集上训练GRU网络
    bagNets{m} = net_m; % 将当前训练好的GRU网络存入cell数组中便于后续集成预测
end % 完成所有子模型训练循环
集成预测与结果反归一化示例
numTestSamples = numel(XTestSeq); % 获取测试样本数量,用于预分配存放预测结果的矩阵
predAll = zeros(numTestSamples,nModels); % 初始化预测结果矩阵,每列对应一个子模型,每行对应一个测试样本
for m = 1:nModels % 循环遍历每个子模型索引,计算其在测试集上的预测输出
    net_m = bagNets{m}; % 从cell数组中取出当前子模型GRU网络
    pred_m = predict(net_m,XTestSeq,'MiniBatchSize',1); % 使用predict函数对测试输入序列逐个推理,批大小设为1保证时间顺序不受影响
    predAll(:,m) = pred_m(:); % 将当前子模型的预测结果转为列向量并填入预测矩阵对应列
end % 完成所有子模型在测试集上的预测
predBagMean = mean(predAll,2); % 对每个测试样本在各子模型预测结果上取均值,形成装袋集成的最终预测
trueTest = cell2mat(YTestSeq(:)); % 将测试集真实收盘价目标cell合并为列向量,便于误差计算
rmseBag = sqrt(mean((predBagMean - trueTest).^2)); % 计算集成预测结果的均方根误差,衡量总体预测精度
maeBag = mean(abs(predBagMean - trueTest)); % 计算集成预测结果的平均绝对误差,衡量平均偏差规模
mapeBag = mean(abs((predBagMean - trueTest)./trueTest)) * 100; % 计算集成预测的平均绝对百分比误差,反映相对误差水平
fprintf('BAG-GRU Test RMSE: %.4f, MAE: %.4f, MAPE: %.2f%%\n',rmseBag,maeBag,mapeBag); % 在命令窗口输出集成模型在测试集上的误差指标
MATLAB图形展示真实值与预测结果示例
fig1 = figure; % 创建一个新的图窗对象用于展示预测曲线与真实曲线
ax1 = axes(fig1); % 在图窗中创建坐标轴对象,用于绘制时间序列曲线
plot(ax1,1:numTestSamples,trueTest,'b','LineWidth',1.5); % 在坐标轴上绘制真实收盘价序列,使用蓝色线条表示
hold(ax1,'on'); % 保持当前坐标轴内容,使后续绘图叠加在同一图中
plot(ax1,1:numTestSamples,predBagMean,'r','LineWidth',1.5); % 在同一坐标轴上绘制装袋集成预测序列,使用红色线条表示
xlabel(ax1,'Test Sample Index'); % 设置横轴标签为测试样本索引,便于观察预测在时间上的分布
ylabel(ax1,'Close Price'); % 设置纵轴标签为收盘价,对应真实与预测的数值含义
title(ax1,'BAG-GRU Ensemble Prediction vs True Close Price'); % 设置图表标题为装袋GRU集成预测对比真实收盘价
legend(ax1,{'True','BAG-GRU Ensemble'},'Location','best'); % 添加图例区分真实曲线与预测曲线,放置在最佳位置
colormap(fig1,turbo); % 为当前图窗设置turbo色图,符合R2025b可视化规范并提升整体视觉效果
grid(ax1,'on'); % 打开坐标轴网格线,便于对比不同时间点的预测偏差

更多详细内容请访问
http://金融预测MATLAB实现基于BAG-GRU装袋集成(BAG)结合门控循环单元(GRU)进行股票价格预测的详细项目实例(含完整的程序,GUI设计和代码详解)_MATLAB时间序列预测代码资源-CSDN下载  https://download.csdn.net/download/xiaoxingkongyuxi/90242167

https://download.csdn.net/download/xiaoxingkongyuxi/90242167

https://download.csdn.net/download/xiaoxingkongyuxi/90242167

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐