项目介绍 MATLAB实现基于BAG-LSTM 装袋集成(BAG)结合长短期记忆网络(LSTM)进行股票价格预测(含模型描述及部分示例代码)专栏近期有大量优惠 还请多多点一下关注 加油 谢谢 你的鼓励
MATLAB实现基于BAG-LSTM 装袋集成(BAG)结合长短期记忆网络(LSTM)进行股票价格预测的详细项目实例
请注意此篇内容只是一个项目介绍 更多详细内容可直接联系博主本人
或者访问对应标题的完整博客或者文档下载页面(含完整的程序,GUI设计和代码详解)
金融市场中的股票价格序列兼具高度非线性、显著噪声和结构性非平稳等特征,传统的线性时间序列模型例如AR、ARIMA在处理这类复杂动态行为时往往力不从心。在过去较长一段时间内,技术分析和基本面分析是证券投资中最常见的手段,但二者在量化程度、可复现性和可扩展性方面存在天然局限;随着数据规模的爆炸式增长以及算力成本的下降,基于机器学习和深度学习的量化预测逐渐成为重要的研究方向。长短期记忆网络(LSTM)作为一种适用于处理时间序列数据的循环神经网络结构,在捕捉长期依赖关系、缓解梯度消失和梯度爆炸问题方面具有天然优势,已经被广泛应用在语音识别、自然语言处理、金融预测等领域之中。
在金融时间序列任务中,单一模型往往存在过拟合、模型偏差大、对训练样本选取较为敏感等问题。尤其是在股票价格预测场景中,数据本身噪声极大,不同历史窗口中蕴含的市场结构可能存在显著差异。同一个LSTM模型在不同训练子集上训练得到的参数差异可能较大,从而导致预测结果不稳定。集成学习通过构建多个基模型并进行集体决策,能够在一定程度上降低方差、减轻过拟合,并提升整体的鲁棒性,而装袋集成(Bagging)作为其中最经典的一类方法之一,通过自助采样(bootstrap sampling)构建多份训练子集,并在这些子集上分别训练一组基学习器,从而得到一组合成模型。将装袋思想与LSTM结合,构建“BAG-LSTM”结构,可以有效融合深度时序建模的优势与集成学习的稳健性。
在现实应用中,股票市场受到宏观经济指标、行业景气、公司基本面、资金流动性以及市场情绪等多种因素共同影响,而这些因素的变化不仅体现在价格序列本身,还隐含于成交量、波动率、K线形态以及各类技术指标之中。对于单一LSTM模型而言,一次性处理过多输入特征往往可以带来表达能力提升,但也容易加剧训练不稳定和参数冗余问题。装袋集成的思想可以从特征层面和样本层面共同引入随机性:一方面,在样本层面通过自助采样生成多份时间序列子集;另一方面,在特征层面可以选择在不同子模型中使用不同组合的特征或不同的窗口长度。这样得到的一组LSTM子网络在数据视角、特征视角以及结构视角上形成多样性,进而在预测阶段采用平均或加权平均的方式融合结果,有助于减少模型对单一局部模式的过度依赖,提高对未知样本的泛化能力。
在MATLAB环境中实现BAG-LSTM股票价格预测项目,有着多个层面的现实意义。一方面,MATLAB在矩阵运算、信号处理、可视化以及深度学习工具箱的集成上具有良好的一体化优势,适合搭建完整的数据导入、特征工程、模型设计、训练监控、结果分析、可视化展示的统一工作流。另一方面,与一些通用脚本环境不同,MATLAB的工具箱中提供了大量成熟的统计分析和金融工具,便于在项目中同时融合如技术指标、波动率建模、风险评估等模块,从而更贴近实际投研场景。利用MATLAB R2025b版本的深度学习功能,可以较为方便地构建多路LSTM子网络,组织成装袋集成结构,并通过脚本控制训练过程,实现自动化批量训练与评估。
本项目的背景还体现在市场实践层面。当前量化投资领域已经从早期以简单技术指标和规则策略为主,逐步转向深度学习、强化学习、多智能体博弈等更复杂的技术方向。对于许多研究者而言,如何在工程实践中稳定实现一个可以落地的、同时兼顾预测精度与稳定性的深度学习模型,是一个既现实又具有挑战性的问题。BAG-LSTM结构在精度提升和风险控制之间提供了一种平衡方案:不追求过度复杂的单体网络,而是通过多模型集成来提升整体表现,有利于在真实交易策略中进行回测验证和风险控制。与此同时,本项目通过详细展示各个模块的构建方法,例如数据预处理、样本生成、网络架构设计、装袋集成策略、模型训练与调参,以及关键MATLAB代码示例,为相关研究提供可复现的技术路径。
此外,项目背景还涵盖了对模型可解释性和鲁棒性的关注。金融监管环境和投资者风险偏好对模型透明度提出了更高要求,单一复杂深度模型往往难以解释预测结果背后的逻辑,而基于集成的BAG-LSTM可以通过分析不同子模型的输出差异、敏感度以及在不同市场阶段的表现,从侧面提高整体方案的可解释性。也可以通过控制装袋集成中基模型数量、采样策略以及融合方式,来研究不同结构对结果稳定性的影响,从而为后续的模型简化、策略实盘部署提供决策依据。综上,本项目选取BAG-LSTM作为股票价格预测工具,立足于金融时间序列的复杂性、模型稳健性提升的现实需求以及MATLAB环境下工程实现的可行性,具有明确的研究背景和应用价值。
项目目标与意义
精细化建模股票价格动态行为的目标
本项目首先聚焦的核心目标是实现对股票价格时间序列的精细化建模,使预测结果能够较为充分地反映市场在历史阶段中蕴含的多尺度动态行为。股票价格变化并不是简单的线性过程,而是包含趋势、季节性、短期波动、极端跳跃等多种成分,这些成分可能由宏观经济周期、政策变动、行业景气度、市场情绪波动等多重因素交织而成。基于LSTM的时序建模能力,可以在长时间窗口上捕捉不同时间尺度的依赖关系,同时利用门控机制过滤掉部分噪声影响。本项目通过设置合理的滑动窗口长度与预测步长,将历史价格、成交量以及技术指标等信息构造成多维时间序列输入,从而让LSTM能够在训练过程中学习到短期波动与长期趋势之间的相互作用。装袋集成策略的引入,则通过多个子模型在不同训练子集上的独立学习,增加了整体模型对不同阶段市场结构的适应性,从而避免单一模型过度拟合某一特定时间区间,提升对未来价格走势的刻画精度。
提高预测稳定性与抗噪声能力的意义
金融市场数据噪声极大,且噪声成分往往与真实有效信息交织在一起,传统单模深度网络容易在训练过程中吸收过多噪声,从而对训练样本的偶然模式过度敏感,导致预测结果在时间维度上表现出不稳定和高波动特征。本项目将装袋集成机制引入LSTM网络体系,通过构建多组基于自助采样的训练子集,使每一个LSTM子模型在略有差异的数据视角下进行学习。这种差异在一定程度上使模型集合对个别异常样本、极端行情或短暂噪声模式的过度记忆得到削弱。当对未来时刻进行预测时,采用子模型输出的平均或加权平均作为最终预测值,可以有效平滑单个模型可能出现的极端预测,表现为整体预测曲线更加平滑、稳定、对异常数据点不那么敏感。这种稳定性对于后续的交易策略设计意义重大,因为任何过于剧烈波动的预测结果都会放大策略持仓调整频率和交易成本,有可能在实盘中削弱真实收益。通过BAG-LSTM结构,项目旨在以相对温和的方式提升预测质量,同时增强对噪声干扰的抵抗能力,从而更适配实际的量化交易环境。
构建可复现的MATLAB深度学习金融研究范式
另一个重要目标是形成一套在MATLAB环境中可复现、可扩展的深度学习金融时间序列研究范式,降低项目在实施层面上的工程门槛,使研究者可以在经过清晰的项目结构和完整代码示例的基础上,快速地进行二次开发。本项目不只关注模型本身的理论结构,更注重从数据导入、预处理、特征工程、训练样本构造、网络搭建、训练调参、结果可视化与评估的整个流程环节,形成完整的脚本和组织方式。MATLAB R2025b版本在深度学习工具箱、可视化功能以及金融相关工具箱方面提供了较为成熟的支持,通过精心设计的脚本结构,可以在不依赖复杂GUI组件的前提下,用figure和uicontrol实现基本的参数输入和结果展示,满足研究与教学场景中的交互需求。通过本项目形成的一套工作流范式,研究者可以方便地替换数据源、调整特征组合或尝试不同的网络结构(例如在部分子模型中加入双向LSTM或Attention层),实现灵活扩展,从而在保证整体结构清晰的情况下开展多样化实验。
为多种金融决策与风险管理场景提供技术支撑
项目的最后一个重要目标在于,通过BAG-LSTM股票价格预测模型,为多种金融决策与风险管理场景提供技术支撑和方法论参考。预测模型本身可以直接用于生成股票收盘价、开盘价或一定时间跨度后的价格预期,用于指导趋势跟随策略、均值回归策略或多因子量化策略中的价格预期模块。此外,预测结果的误差分布和残差特征,对于构建风险控制指标具有重要意义,例如可以根据预测误差在不同波动区间的表现,动态调整仓位或止损水平。集成结构带来的稳定性和鲁棒性,使得模型更适合在高频或中频交易策略中作为辅助决策工具,而不仅仅是离线研究用的分析器。特别是在面对极端市场行情时,通过观察子模型预测结果之间的分歧程度,可以从侧面反映当前市场是否处于结构突变期,从而为风险预警提供额外信息。通过这一项目,可为实际的资产配置、行业轮动、单票择时以及组合风险管理等多个环节提供可落地的技术基础,为金融机构、研究人员以及工程人员在复杂时间序列建模方面提供参考范式。
项目挑战及解决方案
股票时间序列非平稳与结构突变带来的挑战及应对
股票价格时间序列存在强烈的非平稳特性,平均值和方差在不同时间阶段可能发生显著漂移,而且在政策变动、经济危机或突发事件出现时,价格序列会出现结构性突变,这种变化可能导致历史数据与未来数据分布不再一致。传统线性模型往往依赖平稳性假设,在面对这类特征时表现不佳。即使是LSTM这类非线性模型,也可能在训练阶段过于依赖某一时间段的模式,从而导致在新阶段表现失真。此类挑战不仅影响预测精度,还会导致模型在极端行情下失效,增加实际交易风险。应对这一问题的方案之一,是在数据预处理阶段对序列进行适度差分、对数变换或收益率转换,使长期趋势与短期震荡适度分离,缓解非平稳影响。同时,在训练集与验证集划分时,需要保证覆盖不同市场阶段,包括牛市、熊市和震荡市,使模型能够接触到多样化的模式。装袋集成结构中,每个子模型在自助采样时会从不同时间段抽取子样本,形成不同的训练视角,从而提高整体系统对结构突变的适应性。在训练过程中还可以通过早停策略、正则化和梯度裁剪控制模型的复杂度,使网络不会过度记忆特定时间段的细节,而是更关注稳定出现的结构性规律。此外,可以在后续扩展中引入滚动训练或在线更新机制,让模型在时间推进中逐步接收最新样本,提高对近期市场状态的响应能力。
深度网络过拟合与参数敏感问题的挑战及应对
LSTM网络由于参数量较大,容易在有限样本上产生过拟合,尤其在股票价格序列这种噪声主导的场景中,过拟合问题更加突出。模型可能过度学习偶然形态,比如某几天的剧烈波动模式被重复强化,从而在未来预测时表现为不合理的价格跳动。此外,网络的超参数(包括隐藏层单元数、层数、学习率、批量大小等)对最终效果的影响非常明显,如果调参不当,可能出现训练损失下降但验证损失上升、训练不收敛或收敛速度极慢等现象。本项目在应对这一挑战时,通过多个层面进行处理。首先,在网络设计方面保持结构适度简洁,采用一到两层LSTM配合小规模全连接层,避免盲目堆叠过多层数。其次,在训练过程中添加dropout层和L2正则(在MATLAB对应为WeightRegularization配置等方式),抑制过度拟合某些局部特征。在装袋集成框架下,通过多个子模型在不同采样子集上训练,每个子模型都是相对“弱”的深度学习器,组合后形成较“强”的整体预测器,从而在一定程度上缓解单模型过拟合。此外,在MATLAB R2025b中,通过合适的训练选项设置(如合理的初始学习率、梯度阈值、mini-batch大小等),配合验证集早停监控,可以在训练过程中动态防止模型走向过拟合。对于超参数敏感问题,可以采用网格搜索或有限范围内的人工调参,同时在集成结构中允许不同子模型使用略有差异的超参数组合,以增强模型多样性和稳健性。
MATLAB工程实现与版本规范约束的挑战及应对
在MATLAB R2025b中实现BAG-LSTM股票预测项目,需要面对一定的工程实现挑战和版本规范约束。首先,R2025b版本对部分界面控件和深度学习API做出了调整,例如不再鼓励使用某些App Designer组件,需要采用figure与uicontrol的传统方式实现交互界面;部分可视化功能(如ConfusionMatrixChart)在用法上也有明显变化。其次,深度学习框架中对于dlnetwork、dlarray等结构的更新方式有特定限制,某些旧版本示例中的layerVisitor和dlupdate用法已不再适用,需要采取新的编程模式。再者,在其他统计学习函数中,例如fitrlinear、fitrnet等,部分参数命名和取值范围有新规定,稍有不慎便可能引发运行错误。为应对这些工程层面的挑战,本项目在设计初期充分考虑R2025b的最新规范,采用官方推荐的深度学习网络定义方式,例如使用layerGraph配合sequenceInputLayer、lstmLayer、fullyConnectedLayer和regressionLayer构建网络,同时通过trainingOptions函数配置训练超参数,避免使用已废弃或限定用法的接口。在可视化方面,利用标准的figure和axes对象结合plot函数展示价格真实值与预测值曲线,并在需要设置颜色映射时,按照R2025b中colormap的规范调用方式,例如使用colormap(gcf,turbo)对当前图窗设置色图,而不对ConfusionMatrixChart对象直接调用colormap,从源头规避版本错误。界面交互若有需要,通过uicontrol创建简单的文本框、按钮和下拉菜单,而不依赖uilabel等新式组件,以保证脚本在当前版本中的稳定运行。这种对版本细节的把握,使得项目在工程层面保持可靠性,为后续扩展打下坚实基础。
项目模型架构
数据预处理与特征构造模块
模型架构的起点在于数据预处理与特征构造模块。股票原始数据一般包括日期、开盘价、收盘价、最高价、最低价、成交量等基础字段,这些字段需要通过清洗、对齐和缺失值处理后,转化为适合作为LSTM输入的数值型矩阵。在预处理阶段,首先需要按时间顺序整理数据,确保时间间隔一致,处理停牌、除权除息等事件带来的价格跳变。其次,可以将原始价格序列转化为对数收益率、日收益率或归一化价格,减少尺度差异和趋势性影响。对于成交量、换手率等指标,可以使用对数变换或标准化处理,使其分布更加集中,便于网络学习。
在特征构造方面,可以引入多种技术指标作为附加特征,例如移动平均线(MA)、指数移动平均线(EMA)、相对强弱指数(RSI)、移动平均收敛散度(MACD)、布林带等。这些指标在一定程度上提取了价格和成交量的局部统计特征,有助于LSTM网络理解更丰富的市场状态。构造好特征后,需要将时间序列按照固定长度的滑动窗口切分为样本,例如用过去N天的多维特征预测第N+1天的收盘价或收益率。MATLAB中可以通过矩阵切片与循环灵活组织这些样本,最终形成一个细分为训练集和验证集的样本集合。数据预处理和特征构造模块为后续BAG-LSTM集成提供统一、规范的输入格式,是整个架构的基础。
单个LSTM子模型结构与原理
每一个基学习器即单个LSTM子模型,是BAG-LSTM集成中的核心组成单元。LSTM的基本结构包括输入门、遗忘门和输出门,以及内部的记忆单元,这种结构设计旨在解决传统循环神经网络在处理长序列时容易出现的梯度消失和梯度爆炸问题。输入门决定当前输入与之前隐藏状态的信息在多大程度上写入记忆单元,遗忘门控制历史记忆的保留与遗忘,输出门则决定从记忆单元中输出多少信息到当前隐藏状态。通过反向传播算法训练,LSTM能够自动学习到在不同时间尺度上保留和遗忘哪些信息,从而较好地建模长期依赖。
在本项目中,每一个LSTM子模型通常包括一个sequenceInputLayer用于接收时间步和特征维度结构的数据,随后是一个或多个lstmLayer(可以设置是否返回序列),再接入dropoutLayer、fullyConnectedLayer和regressionLayer组成完整的回归网络。sequenceInputLayer定义输入数据的特征维度,lstmLayer负责提取时间序列中的动态特征,dropoutLayer在训练期随机丢弃部分神经元,以减弱过拟合,fullyConnectedLayer将高维隐藏表示映射到标量输出,regressionLayer用作回归任务的损失层,通常采用均方误差作为损失函数。在训练过程中,通过Adam或SGDM等优化算法调整网络权重,使预测结果尽可能逼近真实价格或收益率。单个LSTM子模型结构的合理设计,对整体BAG-LSTM集成的性能有决定性影响,因此在隐藏单元数、层数和正则化参数设置方面需要兼顾表达能力与泛化能力。
装袋集成策略与多子模型结构设计
装袋集成(Bagging)的核心思想是通过自助采样产生多个训练子集,在每个子集上训练一个相对独立的基学习器,然后将这些基学习器的输出进行平均或投票,从而获得整体预测。对于回归任务,例如股票价格预测,通常采用简单平均或加权平均的方式聚合各子模型的输出。本项目将装袋集成与LSTM结合,构成BAG-LSTM结构。在具体实现中,首先根据原始训练样本集合,通过自助采样生成若干份训练子集。每一份子集的大小可以与原训练集相同,也可以略小,通过在样本选择上引入重复和遗漏,以增加子模型之间的差异性。随后,对每一份训练子集构建一个独立的LSTM网络实例,这些网络的结构可以相同,也可以在隐藏单元数、dropout比例等方面设置轻微差异,以进一步增强模型多样性。
在训练阶段,每个LSTM子模型只在对应的子集上进行训练,互不影响。训练完成后,对于同一时间点的预测,所有子模型都会给出各自的预测值,将这些预测值取平均即可得到最终预测结果。这种结构的直观好处在于,某些子模型可能在特定样本子集上过拟合,而其他子模型在不同子集上表现更稳健,平均操作可以在一定程度上抵消极端情况的影响。多子模型结构设计还可以与特征子集抽样结合,例如在某些子模型中加入更多技术指标特征,在另一些子模型中采用更简化的特征集合,通过多视角学习提升整体性能。MATLAB环境中可以通过编写脚本循环构建网络、训练并保存子模型,实现灵活的装袋集成策略。
预测结果融合与输出模块
在完成多个LSTM子模型训练之后,需要设计预测结果融合模块,将子模型输出转换成最终可用的预测结果。对于单一预测时刻t,将所有子模型在t时刻的预测值组成一个向量,通过计算算术平均可以得到一个较为平滑的预测值;如果在训练过程中观察到某些子模型在验证集表现更好,则可以基于验证集误差构造加权平均,将表现较优的子模型赋予更高权重,这样可以进一步减少表现较差子模型对整体结果的负面贡献。预测结果可以是未来某一日的收盘价,也可以是未来若干日的收益率、本项目主要以单步预测为示例,便于展示BAG-LSTM结构的基本工作方式,但在实际中完全可以扩展到多步预测场景。
输出模块除了提供数值预测外,还应配合可视化展示和误差分析功能。通过绘制实际价格和预测价格的时间序列曲线,可以直观对比模型的拟合情况和对趋势的追踪能力。还可以计算均方误差、平均绝对误差、对称平均绝对百分比误差等指标,对模型性能进行量化评估。在MATLAB R2025b中,可以使用标准plot函数在同一坐标系下绘制多条曲线,并采用图例区分真实值与预测值,同时使用colormap(gcf,turbo)设置统一色图风格,使整体展示更具美观性和一致性。通过输出模块,可以为后续策略回测提供直观输入,也方便对不同参数配置或模型结构进行对比分析。
扩展与优化模块的结构布局
在基础BAG-LSTM结构之外,模型架构还应保留充分空间用于扩展与优化。扩展模块可以包括多种方向,例如引入注意力机制增强对关键时间步的关注、加入多任务学习结构同时预测价格和波动率、构建多资产联合模型捕捉联动效应等。在MATLAB中,这些扩展可以通过layerGraph对象灵活组合不同类型的网络层完成,例如在LSTM层之后添加自注意力层对时间步进行加权处理,从而让模型更聚焦于对未来影响更大的历史片段。另一个重要扩展方向是多尺度建模,可以为不同时间尺度(如短期、中期、长期)分别构建LSTM子网络,再在高层进行特征融合,这与BAG-LSTM的多子模型结构在理念上是相通的,只是在采样策略和结构配置上更具针对性。
优化模块则关注训练效率和预测性能提升,可以在训练过程中引入学习率动态调整、早停机制、批量归一化等技术,以加快收敛速度并增强泛化能力。还可以设计脚本对不同超参数组合进行系统试验,通过记录每个组合下的验证集误差,选取表现最佳的配置。另外,对于工程部署,优化模块还可以包含模型压缩与加速,如将训练好的多子模型权重保存为文件,在预测阶段集中载入并进行批量推理,减少重复加载开销。通过合理的扩展与优化,可以使BAG-LSTM架构在股票价格预测的不同实战场景中具备更强的适应能力和可持续演进能力。
项目模型描述及代码示例
数据导入与基础预处理示例 clc; clear; close all; % 清空命令行窗口、清除变量并关闭所有图窗,保证后续运行环境干净 dataFile = 'stock_data.csv'; % 指定包含股票历史数据的CSV文件名,假定文件已准备好放置在当前工作路径 rawTbl = readtable(dataFile); % 使用readtable读取CSV文件为表格格式,便于按列名称访问价格和成交量等字段 rawTbl = sortrows(rawTbl,'Date'); % 按日期字段升序排序,确保时间序列顺序正确,避免后续切片出现乱序 closePrice = rawTbl.Close; % 从表格中提取收盘价列,作为预测目标的基础价格序列 volume = rawTbl.Volume; % 提取成交量列,用作辅助特征以反映市场活跃度 closePrice = fillmissing(closePrice,'linear'); % 对收盘价中的缺失值使用线性插值填补,避免出现NaN影响训练 volume = fillmissing(volume,'previous'); % 对成交量缺失值向前填充,保持时间连续性并减少异常断点 ret = diff(log(closePrice)); % 计算对数收益率序列,减少价格尺度和趋势影响,突出相对变化 ret = [0; ret]; % 在首位补零以保持收益率序列长度与原价格序列一致,方便对齐其他特征 volNorm = (volume - mean(volume)) / std(volume); % 对成交量进行标准化处理,使其均值为零方差为一,有利于网络训练 priceNorm = (closePrice - mean(closePrice)) / std(closePrice); % 对收盘价进行标准化,降低不同量纲之间的差异 dataMat = [priceNorm ret volNorm]; % 将标准化价格、收益率和成交量组合成多维特征矩阵,每一行对应一个时间点 技术指标特征构造与样本窗口生成示例 winMA = 5; % 设置移动平均线窗口长度为5日,用于构造短期趋势特征 ma5 = movmean(priceNorm,[winMA-1 0]); % 计算5日移动平均,使用过去4日加当前日的平均值表示短期平滑价格 winMA2 = 20; % 设置较长周期的移动平均窗口长度为20日,用于刻画中期趋势 ma20 = movmean(priceNorm,[winMA2-1 0]); % 计算20日移动平均,突出中期趋势变化特征 rsiLen = 14; % 设置RSI指标的计算周期长度为14日,这是常用的技术分析参数 deltaP = [0; diff(closePrice)]; % 计算相邻交易日收盘价变化量,用于拆分为上涨和下跌部分 gain = max(deltaP,0); % 将价格上涨部分提取为正收益,跌价部分置零,用于RSI中平均涨幅计算 loss = max(-deltaP,0); % 将价格下跌部分提取为正值,上涨部分置零,用于RSI中平均跌幅计算 avgGain = movmean(gain,[rsiLen-1 0]); % 使用移动平均计算14日平均涨幅,平滑短期波动 avgLoss = movmean(loss,[rsiLen-1 0]); % 使用移动平均计算14日平均跌幅,与平均涨幅一起构成RSI rs = avgGain ./ (avgLoss + eps); % 计算相对强弱RS,分母加eps防止平均跌幅为零导致除零错误 rsi = 100 - 100 ./ (1 + rs); % 按标准公式将RS转换为RSI指数,数值范围在0到100之间 rsiNorm = (rsi - nanmean(rsi)) / nanstd(rsi); % 对RSI进行标准化处理,减小数值尺度差异并处理可能的NaN featureMat = [dataMat ma5 ma20 rsiNorm]; % 将基础特征与技术指标合并形成最终特征矩阵,进一步丰富输入信息 featureMat = fillmissing(featureMat,'nearest'); % 对特征矩阵中的残余缺失值使用最近邻插值填补,避免NaN进入网络 seqLen = 20; % 设置LSTM输入序列长度为20个时间步,即用过去20天数据预测下一天 numSamples = size(featureMat,1) - seqLen; % 根据序列长度计算可构造的样本数量,最后seqLen行用于预测目标 Xall = cell(numSamples,1); % 创建单元数组存放每个样本的输入序列,适配LSTM的序列输入格式 Yall = zeros(numSamples,1); % 创建向量存放每个样本对应的目标输出值,这里使用标准化收盘价 for i = 1:numSamples % 遍历所有可构造样本的起始位置,逐个生成时间窗口 Xall{i} = featureMat(i:i+seqLen-1,:).'; % 将从i到i+seqLen-1的特征数据转置为特征×时间格式,符合sequenceInputLayer需求 Yall(i) = priceNorm(i+seqLen); % 将窗口结束后的下一日标准化价格作为预测目标,实现一步前瞻预测 end % 结束样本构造循环,完成所有输入输出对的准备 单个LSTM回归网络结构与训练示例 numFeatures = size(featureMat,2); % 计算输入特征维度数量,为sequenceInputLayer提供输入大小 numHidden = 64; % 设定LSTM隐藏单元数为64,在表达能力和计算开销之间取得平衡 layers = [ ... % 使用方括号构建层数组,定义从输入到输出的网络结构 sequenceInputLayer(numFeatures) ... % 第一层为序列输入层,其输入大小等于特征维度数 lstmLayer(numHidden,'OutputMode','last') ... % 添加LSTM层,只输出最后一个时间步的隐藏状态用于回归 dropoutLayer(0.2) ... % 添加dropout层,随机丢弃20%神经元以降低过拟合风险 fullyConnectedLayer(1) ... % 添加全连接层,将隐藏状态映射为单一标量输出(预测价格) regressionLayer]; % 添加回归层,使用均方误差损失用于连续值预测任务 trainRatio = 0.8; % 设置训练集比例为80%,剩余20%作为验证集用于监控过拟合 numTrain = floor(numSamples * trainRatio); % 根据比例和样本总数计算训练样本数量 idx = randperm(numSamples); % 生成随机排列索引,用于打乱样本顺序避免时间偏置 idxTrain = idx(1:numTrain); % 选取前numTrain个索引作为训练集样本编号 idxVal = idx(numTrain+1:end); % 剩余索引作为验证集样本编号,用于训练过程评估 XTrain = Xall(idxTrain); % 根据训练索引提取训练输入序列集合 YTrain = Yall(idxTrain); % 根据训练索引提取训练目标值向量 XVal = Xall(idxVal); % 根据验证索引提取验证输入序列集合 YVal = Yall(idxVal); % 根据验证索引提取验证目标值向量 opts = trainingOptions('adam', ... % 选择Adam优化算法,具备自适应学习率和较好收敛特性 'MaxEpochs',50, ... % 设置最大训练轮数为50,防止训练时间过长 'MiniBatchSize',32, ... % 设置小批量大小为32,在稳定性和速度之间平衡 'InitialLearnRate',1e-3, ... % 设定初始学习率为0.001,适中且不易造成梯度爆炸 'GradientThreshold',1, ... % 启用梯度裁剪阈值为1,避免梯度过大导致不稳定 'Shuffle','every-epoch', ... % 每个训练轮前打乱训练样本顺序,增加随机性 'ValidationData',{XVal YVal}, ... % 指定验证集数据,用于训练过程中的性能监控 'ValidationFrequency',20, ... % 每间隔20个mini-batch在验证集上评估一次误差 'Verbose',false, ... % 关闭详细命令行输出,使训练信息简洁 'Plots','none'); % 不在训练过程中自动绘制训练曲线,由后续手动绘图分析 netSingle = trainNetwork(XTrain,YTrain,layers,opts); % 使用trainNetwork函数基于指定结构和选项训练单个LSTM回归网络 装袋集成训练多LSTM子模型示例 numBags = 5; % 设置装袋集成中的子模型数量为5个,平衡多样性与训练时间 bagNets = cell(numBags,1); % 创建单元数组用于存放每一个训练好的LSTM子模型 bagIdx = cell(numBags,1); % 创建单元数组记录每个子模型对应的训练样本索引,便于后续分析 for b = 1:numBags % 循环遍历每一个子模型编号,从1到numBags逐个训练 bootIdx = randi(numTrain,numTrain,1); % 使用自助采样从训练集索引中有放回抽取numTrain个样本编号 XBoot = XTrain(bootIdx); % 根据自助采样索引提取对应的训练输入序列形成该子模型的训练子集 YBoot = YTrain(bootIdx); % 根据自助采样索引提取对应的训练目标值形成该子模型的标签 bagIdx{b} = bootIdx; % 将当前子模型使用的自助采样索引记录下来,以备分析或可视化 netB = trainNetwork(XBoot,YBoot,layers,opts); % 使用与单模型相同的网络结构和训练选项训练当前子模型 bagNets{b} = netB; % 将训练完成的子模型网络对象存入bagNets方便后续集成预测 end % 完成所有BAG-LSTM子模型的训练循环,使得每个子模型在不同数据子集上学习 集成预测与结果可视化示例 numVal = numel(XVal); % 获取验证集样本数量,用于后续预测数组的维度定义 predBag = zeros(numVal,numBags); % 创建矩阵存放所有子模型在验证集上的预测结果,行对应样本列对应子模型 for b = 1:numBags % 遍历每个已训练的LSTM子模型,依次对验证集执行预测 netB = bagNets{b}; % 取出当前子模型网络对象,准备用于预测操作 predBag(:,b) = predict(netB,XVal); % 对验证集输入序列进行预测,将输出向量存入对应列 end % 结束所有子模型的预测循环,得到完整集成预测矩阵 predMean = mean(predBag,2); % 对每个验证样本在所有子模型预测上的结果取平均,得到集成预测值 mseSingle = mean((predict(netSingle,XVal) - YVal).^2); % 计算单一LSTM模型在验证集上的均方误差评价基准 mseBag = mean((predMean - YVal).^2); % 计算BAG-LSTM集成预测在验证集上的均方误差,用于对比效果 figure; % 新建图窗用于绘制验证集真实值与预测值对比曲线 plot(YVal,'k','LineWidth',1.2); hold on; % 绘制验证集真实目标值曲线,使用黑色线条表示 plot(predMean,'r','LineWidth',1.2); % 绘制集成预测值曲线,使用红色线条突出显示 legend({'True','BAG-LSTM'},'Location','best'); % 添加图例区分真实值与BAG-LSTM预测曲线,并自动优化位置 xlabel('Validation Sample Index'); % 设置横轴标签为验证样本索引,表明横坐标含义 ylabel('Normalized Price'); % 设置纵轴标签为标准化价格,说明数值单位和处理方式 title(sprintf('Single MSE=%.4f, BAG MSE=%.4f',mseSingle,mseBag)); % 在标题中展示单模型与集成模型的均方误差进行直观对比 colormap(gcf,turbo); % 将当前图窗的色图设置为turbo,提高整体视觉效果并匹配R2025b规范用法 grid on; % 打开网格线,便于观察预测曲线与真实曲线的局部差异 单步预测到原始价格还原示例 muPrice = mean(closePrice); % 计算原始收盘价的均值,在标准化还原过程中作为偏移量使用 sigmaPrice = std(closePrice); % 计算原始收盘价的标准差,用于将标准化预测逆变换为真实价格尺度 YValPrice = YVal * sigmaPrice + muPrice; % 将验证集标准化目标值还原为原始收盘价数值,以便直观解释 predPrice = predMean * sigmaPrice + muPrice; % 将集成预测的标准化结果还原为原始价格,便于后续策略设计 figure; % 新建图窗展示还原后的价格曲线对比 plot(YValPrice,'k','LineWidth',1.2); hold on; % 绘制真实收盘价曲线,使用黑色线条表示真实市场走势 plot(predPrice,'b','LineWidth',1.2); % 绘制BAG-LSTM预测价格曲线,使用蓝色线条显示模型预测走势 legend({'True Price','Predicted Price'},'Location','best'); % 添加图例区分真实价格与预测价格 xlabel('Validation Sample Index'); % 设定横轴标签为验证样本索引,方便与前一图窗对齐对应 ylabel('Price'); % 设置纵轴标签为价格,表明当前图中数值为真实货币单位或价格单位 title('BAG-LSTM Stock Price Prediction (Back-Transformed)'); % 添加标题说明图意,强调为逆标准化后的价格预测结果 grid on; % 打开网格,提高价格曲线的可读性,便于观察局部偏差和趋势拟合程度 简单界面参数控制与再训练示例 fig = figure('Name','BAG-LSTM Control','NumberTitle','off'); % 创建新图窗作为简单控制面板窗口并取消默认编号显示 uicontrol('Style','text','Position',[20 200 120 20],'String','Num Bags:'); % 在图窗中放置文本标签,提示用户输入子模型数量 editBags = uicontrol('Style','edit','Position',[150 200 80 25],'String','5'); % 创建文本输入框,用于设定装袋子模型数量初始值为5 uicontrol('Style','text','Position',[20 160 120 20],'String','Epochs:'); % 创建文本标签提示训练轮数参数,方便交互修改 editEpochs = uicontrol('Style','edit','Position',[150 160 80 25],'String','30'); % 创建训练轮数输入框,初始设置为30轮 btnTrain = uicontrol('Style','pushbutton','Position',[20 120 210 30], ... % 创建按钮控件触发重新训练过程并占据较宽区域 'String','Train BAG-LSTM','Callback',@(~,~)disp('Trigger retrain here')); % 为按钮指定回调函数,此处示例中仅输出提示文本 movegui(fig,'center'); % 将控制面板窗口移动到屏幕中央位置,提升使用体验和可见性