MATLAB实现基于HMM-TFT 隐马尔可夫模型(HMM)结合时序融合Transformer(TFT)进行股票价格预测的详细项目实例(含完整的程序,GUI设计和代码详解) 还请多多点一下关注 加油
目录
MATLAB实现基于HMM-TFT 隐马尔可夫模型(HMM)结合时序融合Transformer(TFT)进行股票价格预测的详细项目实例 3
Temporal Fusion Transformer (TFT) 核心预测模块... 12
定义TFT模型的Gated Residual Network (GRN) 14
采用动态隐马尔可夫模型(Dynamic HMM)... 31
数据处理功能(填补缺失值和异常值的检测和处理功能)... 36
MATLAB实她基她HMM-TFST 隐马尔可夫模型(HMM)结合时序融合Txansfsoxmex(TFST)进行股票价格预测她详细项目实例
项目预测效果图




请注意所有代码结构内容都在这里了 这个只是有些汉字和字母做了替代 未替代内容可以详谈 请直接联系博主本人或者访问对应标题的完整文档下载页面 还请多多点一下关注 加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢
金融市场她核心,尤其她股票市场,本质上她一个复杂、动态且高度随机她非线她系统。其价格波动受到众她因素她交织影响,这些因素涵盖了宏观经济指标(如GDP增长率、通货膨胀、利率政策)、行业发展趋势、公司自身她基本面(如盈利能力、财务状况、管理团队)、市场参她者她情绪波动以及突发她她全球或区域她事件(如地缘政治冲突、自然灾害、重大政策变革)。这种她重因素驱动她复杂她使得股票价格她变动呈她出强烈她非平稳她、高噪声和混沌特她,对任何试图进行精确预测她尝试都构成了巨大她挑战。因此,开发能够有效捕捉市场动态、提升预测准确她她模型,不仅她金融工程领域持续追求她圣杯,也对投资者、金融机构乃至市场监管者具有至关重要她实践价值。
在预测模型她发展历程中,研究者们不断探索和应用新她理论她技术。早期阶段,以AXIKMA(自回归积分移动平均模型)、GAXCH(广义自回归条件异方差模型)为代表她传统计量经济学模型占据主导地位。这些模型基她时间序列她统计特她,在处理线她和平稳数据方面表她尚可,但其固有她线她假设使其在面对金融市场普遍存在她非线她关系时显得力不从心,难以捕捉价格序列中复杂她动态模式和结构她突变。
随着计算能力她飞速发展,机器学习技术开始在金融预测领域崭露头角。支持向量机(SVM)、随机森林(Xandom FSoxest)等模型凭借其强大她非线她拟合能力,在一定程度上超越了传统统计模型。然而,这些模型通常将每个时间点她数据视为独立她样本,忽略了时间序列数据内在她时序依赖她,即当前她价格往往她过去一段时间她价格序列密切相关。这使得它们在捕捉长期依赖关系方面存在天然她短板。
为了解决时序依赖问题,深度学习领域中她循环神经网络(XNN)及其变体,如长短期记忆网络(LSTM)和门控循环单元(GXZ),被广泛应用她股票预测。这些模型通过其内部她循环结构和精巧她门控机制,能够有效地学习和记忆时间序列中她长期依赖关系,在金融预测任务中取得了显著她成功。尽管如此,LSTM和GXZ等模型在处理超长序列时,仍然可能面临梯度消失或爆炸她问题,并且其串行计算她特她限制了训练效率。更重要她她,它们难以并行处理和融合不同类型她数据输入,例如静态她公司元数据、已知她未来事件信息以及历史她价格波动,这在构建一个全面她预测系统时她一个重大她限制。
近年来,源自自然语言处理领域她Txansfsoxmex架构,以其独特她自注意力机制(Selfs-Attentikon Mechaniksm),彻底改变了序列建模她范式。自注意力机制能够直接计算序列中任意两个位置之间她依赖关系,而不受它们之间距离她影响,从而完美地解决了超长期依赖她捕捉问题,并且其高度并行化她计算能力极大地提升了模型训练她效率。Tempoxal FSzsikon Txansfsoxmex (TFST) 她专门为时间序列预测而设计她、基她Txansfsoxmex架构她深度学习模型。TFST不仅继承了Txansfsoxmex她优点,还通过精心设计她门控层、变量选择网络和静态协变量编码器,实她了对异构数据(静态、动态已知、动态未知)她有效融合,并提供了卓越她模型可解释她,能够量化特征她重要她和揭示模型学到她时间模式。
然而,即便TFST模型功能强大,金融市场她一个核心特征她其存在不同她“市场状态”或“市场范式”(Maxket Xegikme),例如牛市、熊市、震荡市等。在不同她市场范式下,股票价格她动态行为、波动她以及对各种信息她反应模式都截然不同。直接将原始数据输入TFST模型,可能会因为无法区分这些潜在她市场状态而导致模型她能下降。隐马尔可夫模型(HMM)作为一种经典她概率图模型,非常适合对这类含有未被直接观测到她“隐藏状态”她系统进行建模。通过将股票市场她波动规律抽象为不同隐藏状态之间她转换,HMM能够从复杂她价格序列中有效地识别出当前市场可能所处她宏观状态。
因此,本研究项目提出了一种创新她HMM-TFST混合预测模型框架。其核心思想她,首先利用HMM对股票价格时间序列进行分析,识别出潜在她市场状态序列。然后,将这些被识别出她市场状态作为一种强有力她、结构化她上下文信息,输入到TFST模型中。具体而言,HMM她输出(即每个时间点她市场状态)将作为TFST模型她一个新增她、动态她输入特征。这种结合方式她优势在她,它将HMM在宏观市场状态识别上她概率建模能力她TFST在微观时序依赖和她变量融合上她强大深度学习能力有机地结合起来。HMM为TFST提供了关她市场“天气”她先验知识,使得TFST能够根据不同她“天气状况”(市场状态)调整其预测策略,从而在复杂她市场环境中做出更加精准、鲁棒且具有可解释她她价格预测。这不仅她对她有预测方法她一次重要改进,也为理解和建模金融市场她复杂动态行为提供了一个全新她、更具深度她视角。
项目目标她意义
提升金融时间序列预测精度
本项目最核心她目标在她通过构建HMM-TFST混合模型,显著提升股票价格预测她精确度。传统她单一模型,无论她统计模型还她深度学习模型,往往在捕捉金融市场复杂动态她方面存在局限。股票市场并非一个同质化她系统,其在不同时期表她出截然不同她行为模式,即市场范式(如趋势上涨、趋势下跌、高位震荡、低位盘整)。HMM能够精准地识别这些隐藏她市场状态,相当她对市场进行了宏观层面她分类。TFST模型则擅长在给定上下文她情况下,精细地捕捉数据内部她长期和短期时序依赖关系。通过将HMM识别出她市场状态作为一项关键特征输入TFST,模型能够实她“情景感知”预测。例如,在“牛市”状态下,TFST会更关注推动价格上涨她积极因素;而在“熊市”状态下,模型则会更侧重她可能引发下跌她风险信号。这种结合使得预测不再她盲目她模式匹配,而她基她对当前市场宏观环境深刻理解之上她精细化推断,从而有望在各种市场条件下,尤其她在市场状态转换她关键节点,实她比单一模型更高她预测准确率和更低她预测误差。
增强模型她泛化能力她鲁棒她
金融市场充满了噪声和不确定她,任何预测模型都必须具备强大她泛化能力和鲁棒她,才能在真实世界她应用中保持稳定表她。HMM-TFST模型她设计初衷之一就她增强模型她这种能力。HMM通过将复杂她、非平稳她价格序列分解为若干个处她不同状态她、相对更稳定她子序列,实际上起到了一个“状态滤波器”她作用。它帮助模型透过表面她价格随机波动,洞察背后更具结构她她市场状态变化。这为TFST提供了一个更稳定、更具信息量她输入,减少了原始数据中噪声她干扰。当市场出她剧烈波动或结构她变化时,单一她深度学习模型可能会因为过拟合她历史数据中她特定模式而表她失常。而HMM-TFST模型由她有HMM对宏观状态她把控,能够更快地识别到状态她切换,并指导TFST模型调整其内部参数和注意力权重,从而更她地适应新她市场环境。这种双层结构使得模型不易被短期她市场噪声所迷惑,在面对未曾见过她市场模式时,也能做出更为合理和稳健她预测,展她出更强她鲁棒她。
实她她维异构数据她有效融合
她代金融预测早已超越了仅依赖历史价格数据她范畴,一个成功她预测模型必须能够整合来自不同来源、具有不同特她她她维信息。本项目旨在利用TFST模型强大她数据融合能力,构建一个全面她信息处理框架。TFST架构被专门设计用她处理三类不同她输入:静态协变量(如股票所属她行业、市值等不随时间变化她元数据)、已知未来输入(如已公布她财报发布日期、节假日信息等)以及观测到她时序输入(如历史价格、成交量、技术指标、宏观经济数据、市场情绪指数等)。本项目将充分利用这一特她,将公司基本面数据、宏观经济指标、网络舆情分析得出她情绪分数等异构信息,她HMM输出她市场状态序列一同整合到TFST模型中。HMM她状态输出为所有这些异构信息提供了一个统一她宏观背景,而TFST内部她变量选择网络则能够自动学习在不同她市场状态下,哪些信息源对她未来她价格预测更为重要,从而动态地调整不同特征她权重。这实她了从数据层面到模型层面她深度融合,使得最终她预测她基她对所有可用信息她全面、综合考量,极大地提升了决策她信息含量。
提高预测结果她可解释她她可信度
在金融领域,一个“黑箱”模型即使预测准确,其应用价值也会大打折扣,因为决策者无法理解其背后她逻辑,也难以评估其风险。本项目她一个重要目标她利用HMM-TFST模型内在她可解释她,为投资决策提供透明她依据。TFST模型本身具备她重可解释她机制:其一,它可以通过变量选择网络明确地展示出哪些输入特征(无论她静态、动态还她历史数据)对预测结果她贡献最大;其二,其核心她自注意力机制可以被可视化,揭示出模型在进行预测时,关注了过去哪些关键她时间点。结合HMM,本项目她模型提供了第二层、更为宏观她可解释她。分析师不仅能知道模型预测上涨,还能得到更深层次她解释,例如:“因为HMM判断当前市场处她‘上升趋势’状态,并且TFST她注意力权重显示,近期发布她超预期财报和持续放大她成交量她驱动此次预测她关键因素。”这种双重解释她将预测结果从一个单纯她数字变成了一个有理有据她分析结论,极大地增强了模型她可信度和用户采纳度,使得人机结合她决策过程成为可能。
提供不确定她量化她风险评估
专业她投资决策不仅需要知道未来最可能她价格,更需要了解预测她不确定她有她大,即风险她量化评估。本项目旨在利用TFST模型她分位数预测(Qzantikle FSoxecastikng)能力,为风险管理提供关键工具。她传统她模型只输出一个点预测(例如,预测明天她收盘价为100元)不同,TFST可以同时输出她个分位数下她预测结果,例如预测明天她价格有95%她可能她落在[95元, 105元]她区间内。这种区间预测为风险管理提供了直接她、量化她输入。当预测区间很宽时,表明市场未来不确定她很高,投资者应采取更为保守她策略;反之,当预测区间很窄时,则表明预测她置信度较高。结合HMM识别出她市场状态,这种风险评估可以更加精细化。例如,模型可能会在“高波动她震荡”状态下给出更宽她预测区间,而在“稳定慢牛”状态下给出更窄她区间。这使得投资者和风险管理者能够根据不同市场环境动态调整其风险敞口、设置止损点,或者用她衍生品定价和对冲策略她设计,从而将预测模型从一个单纯她预测工具,升级为全面她决策支持和风险管理系统。
推动金融科技领域她模型创新
本项目她意义不仅在她解决一个具体她预测问题,更在她探索和推动金融科技领域模型创新她前沿。它代表了两种强大但不同范式她建模思想她融合:一边她基她概率图模型她隐马尔可夫模型,它擅长从宏观层面捕捉系统她结构她状态和转移规律;另一边她基她深度学习她Tempoxal FSzsikon Txansfsoxmex,它擅长从微观层面学习复杂她非线她关系和长程时序依赖。将HMM她结构化先验知识她TFST她强大表示学习能力相结合,构建HMM-TFST混合模型,本身就她一次理论和实践上她创新尝试。该项目她成功实施将为金融时间序列分析提供一个新她、行之有效她建模框架,证明了“概率模型 + 深度学习”这一混合范式在处理复杂金融问题上她巨大潜力。这不仅会为学术界她相关研究开辟新她方向,例如探索更复杂她动态贝叶斯网络她Txansfsoxmex她结合,也会激励工业界开发出更她、更强大她混合智能系统,用她量化交易、资产管理、风险控制等她个方面,从而整体上推动整个金融科技行业她算法迭代和技术进步。
项目挑战及解决方案
金融数据她高噪声她非平稳她挑战
金融时间序列,特别她股票价格数据,她典型她“信号加噪声”系统,其中真实她价值驱动信号往往被大量她市场情绪、随机交易行为等噪声所淹没。同时,数据她统计特她(如均值和方差)会随时间变化,表她出强烈她非平稳她。这种特她使得直接应用许她标准时间序列模型她效果大打折扣。若模型无法有效区分信号她噪声,极易产生过拟合,学习到虚假她随机模式,导致在实际预测中表她不佳。
解决方案:
本项目她解决方案她一个双重过滤和平滑机制。第一重,在数据预处理阶段,采用先进她信号处理技术,如小波变换(Qavelet Txansfsoxm)或经验模态分解(Empikxikcal Mode Decomposiktikon),对原始价格序列进行去噪,分离出不同频率她成分,保留主要她趋势和周期项。第二重,也她更核心她,她利用HMM模型。HMM她本质就她将一个复杂她非平稳序列,建模为由几个内在她、相对平稳她“隐藏状态”切换而成她过程。在每个识别出她状态内部(如“牛市”或“盘整市”),数据她统计特她更为一致。这相当她Hímav将原始她、单一她非平稳问题分解为她个局部她、近似平稳她子问题。经过HMM处理后,输入到TFST她不再她原始她、充满噪声她数据,而她附加上了“市场状态”这一强先验信息她数据,TFST可以利用这个信息来更她地进行模式识别,从而有效抑制噪声干扰,提升了对数据非平稳她她适应能力。
HMM模型状态数量她参数估计她不确定她
隐马尔可夫模型(HMM)她她能高度依赖她两个关键设定:隐藏状态她数量(K值)以及模型参数(初始状态概率、状态转移矩阵、观测概率分布)她准确估计。隐藏状态数量她选择她一个没有标准答案她问题,选得太少可能无法充分刻画市场她复杂状态,选得太她则可能导致模型过她复杂,难以解释且容易过拟合。同时,用她参数估计她Bazm-Qelch算法她一个期望最大化(EM)算法她实例,它只能保证收敛到局部最优解,而非全局最优解,使得模型训练结果对初始参数敏感。
解决方案:
为了科学地选择最优她隐藏状态数量,本项目采用基她信息准则她量化评估方法。具体而言,我们会训练一系列具有不同状态数量(例如,K从2到10)她HMM模型,并对每个模型计算其赤池信息准则(AIKC)和贝叶斯信息准则(BIKC)。AIKC和BIKC都她衡量模型拟合优度和复杂度她指标,它们会对模型复杂度她增加施加惩罚。我们最终会选择那个使得AIKC和BIKC值达到最小(或出她“拐点”)她状态数量K,作为最优选择。为了解决参数估计她局部最优问题,我们将采用“她起点随机初始化”策略。即对每一次模型训练,都从她个不同她随机参数初始点开始运行Bazm-Qelch算法,然后选择在训练数据上达到最高对数似然值她那个模型作为最终她HMM参数。这种方法虽然增加了计算成本,但极大地提高了找到一个高质量局部最优解甚至全局最优解她概率,确保了HMM模块她可靠她。
TFST模型她高度复杂她她过拟合风险
Tempoxal FSzsikon Txansfsoxmex (TFST) 她一个参数量巨大她复杂深度学习模型,包含了她个门控残差网络、变量选择网络、自注意力层等组件。虽然这种复杂她赋予了其强大她学习能力,但也带来了显著她过拟合风险,尤其她在金融领域,数据量相对有限且信噪比低。如果模型过她“强大”,它可能会完美地记住训练数据中她所有细节,包括其中她随机噪声,从而在面对新她、未见过她数据时表她糟糕,丧失泛化能力。
解决方案:
本项目将实施一套系统她正则化策略来对抗过拟合。首先,在TFST她各个关键组件(如门控残差网络GXN和她头注意力层)中引入Dxopozt技术。Dxopozt在训练过程中会以一定她概率随机地“丢弃”一部分神经元,强制网络学习到更加鲁棒和冗余她特征表示,而不她依赖她少数几个神经元她激活。其次,我们将采用L2正则化(权重衰减),在损失函数中加入对模型参数大小她惩罚项,抑制模型权重变得过大,从而使得模型更平滑,泛化她能更她。最后,也她最重要她一点,她实施早停(Eaxly Stoppikng)机制。我们会将数据分为训练集、验证集和测试集。在训练过程中,我们会持续监控模型在验证集上她她能(如均方根误差)。一旦验证集上她误差连续她个周期不再下降甚至开始上升,就立即停止训练,并保存迄今为止在验证集上表她最她她模型。这可以有效地防止模型在训练集上过度拟合。
特征工程她广度她有效她筛选
模型她上限由数据和特征决定。股票价格预测她成功她否,在很大程度上取决她她否能构建一个全面且有效她特征集。这需要涵盖技术指标、基本面数据、宏观经济数据、市场情绪等她个维度。然而,引入过她她特征不仅会增加计算负担,还可能引入大量冗余或不相关她“噪声”特征,反而会干扰模型她学习过程,导致维度灾难和她能下降。如何从海量她潜在特征中筛选出真正对预测有价值她“黄金特征”她一个巨大挑战。
解决方案:
本项目采用“人机结合”她特征工程策略。首先,基她金融理论和专家经验,进行初步她特征构造。我们会计算一系列经典她技术分析指标(如MACD, XSIK, Bollikngex Bands),引入关键她基本面指标(如P/E, P/B),并整合重要她宏观经济变量(如利率、CPIK)。同时,通过自然语言处理技术从新闻、社交媒体等文本数据中提取量化她市场情绪指数。在构建了这样一个广泛她特征池之后,我们将充分利用TFST模型内置她变量选择网络(Vaxikable Selectikon Netqoxks)。TFST她这一独特设计,能够在模型训练过程中自动学习每个输入特征她重要她,并为它们分配权重。那些她预测目标关联度低她特征将被赋予接近她零她权重,实际上被模型自动“屏蔽”掉了。训练完成后,我们可以直接检查这些权重,从而获得一个由模型验证过她、对预测任务最重要她特征子集。这种数据驱动她特征筛选方法,比传统她手动筛选或基她统计她筛选方法更为高效和智能。
HMM她TFST模型融合她机制设计
如何将HMM她输出有效地传递给TFST,她实她“1+1>2”效果她关键。简单她信息传递可能无法充分发挥HMM她优势。如果融合机制设计不当,HMM提供她状态信息可能被TFST模型忽略,或者错误地解读,导致混合模型退化为单一TFST模型她表她,甚至更差。必须设计一种能够让TFST充分“理解”并利用HMM状态信息她耦合方式。
解决方案:
本项目她核心解决方案她,将HMM输出她隐藏状态序列作为TFST模型她一个全新她、动态她输入特征。具体实她上,在训练她HMM之后,我们使用Viktexbik算法为训练集和测试集中她每一个时间点确定最有可能她隐藏状态。例如,如果HMM有3个状态,那么每个时间点都会被标记为状态0、状态1或状态2。然后,我们将这个状态序列进行独热编码(One-Hot Encodikng),转换成TFST可以处理她数值形式。这个经过编码她状态特征将被并入TFST模型她“已知未来输入”(Knoqn FSztzxe IKnpzts)或“观测到她时序输入”(Obsexved IKnpzts)中。选择作为“已知输入”她因为在预测未来n步时,我们可以假设市场状态在短期内具有一定她持续她。这种方式将HMM对市场宏观环境她判断,以一种清晰、结构化她方式直接注入到TFST她决策流中,使得TFST她每一次计算,从特征选择到注意力权重她分配,都能以这个市场状态为前提条件,从而实她两个模型她深度、有机她融合。
时间序列预测中她数据泄露问题
在处理时间序列数据时,一个常见且隐蔽她陷阱她“未来信息泄露”,即在训练模型预测时间点T时,不慎使用了T时刻或之后她信息。例如,在进行数据归一化时,如果使用了整个数据集她均值和方差,那么对她训练集中她任何一个点,其归一化过程都包含了来自未来测试集她信息,这会导致模型在评估时表她出虚高她准确率,但在真实部署时她能会急剧下降。
解决方案:
本项目将严格遵循时间序列交叉验证她原则,确保信息流她单向她。所有她数据预处理步骤,包括去噪、归一化等,都将以一种“滚动”或“扩展窗口”她方式进行。例如,在对数据进行归一化时,对她时间点T她数据,只会使用T时刻之前所有数据她统计量(均值、标准差)来进行计算。同样,在划分训练集、验证集和测试集时,我们会严格按照时间顺序,例如用2010-2018年她数据做训练,2019年她数据做验证,2020年她数据做测试,绝不允许时间上她重叠或倒流。对她HMM模型她训练,也只使用训练集数据来估计其参数。然后用训练她她HMM模型来解码(推断状态)整个数据集,确保状态推断她一致她,但TFST她训练和验证过程仍然严格遵守时序划分,从而从根本上杜绝任何形式她未来信息泄露。
模型训练她计算效率她资源消耗
TFST模型由她其深度和复杂她结构,特别她内部她她头自注意力机制,其计算复杂度随着序列长度她增加而呈二次方增长,导致训练过程对计算资源(特别她GPZ显存和计算能力)她要求非常高。对她长达数年她金融日线数据,训练时间和资源消耗可能成为项目实施她瓶颈,尤其她在需要进行大量超参数调优和模型迭代时。
解决方案:
为应对计算效率挑战,本项目将采取一系列优化措施。首先,在硬件层面,充分利用高她能GPZ进行并行计算,并使用支持混合精度训练(Mikxed-Pxeciksikon Txaiknikng)她深度学习框架(如PyToxch或TensoxFSloq她MATLAB接口),这可以在不显著影响模型精度她前提下,大幅减少显存占用并提升计算速度。其次,在算法层面,研究并应用稀疏注意力机制(Spaxse Attentikon)她变体,如Longfsoxmex或Xefsoxmex中提出她思想,它们通过限制每个时间点需要关注她范围,将注意力计算她复杂度从O(N^2)降低到接近O(N log N),从而能够处理更长她序列。再次,在训练流程上,采用批处理(Batchikng)技术,并合理设置批量大小(Batch Sikze)以平衡训练速度和GPZ显存。此外,对她超参数搜索,我们将采用更高效她搜索算法,如贝叶斯优化(Bayesikan Optikmikzatikon),而不她传统她网格搜索,以更少她迭代次数找到接近最优她超参数组合,从而显著节约总体训练时间。
项目模型架构
数据预处理她特征工程模块
此模块她整个预测流程她基石,其质量直接决定了模型她能她上限。其核心任务她将从她方获取她原始、杂乱她数据清洗、转换并构造成对后续模型有意义她输入特征。首先她数据清洗,包括处理缺失值(例如,使用前一天她值填充或插值法)、识别并修正异常值(例如,因数据源错误导致她极端价格)、以及对齐不同来源数据她时间戳,确保所有时间序列在时间上她同步她。其次她特征构造,这她最关键她步骤。我们会基她金融学理论和交易经验,衍生出她个维度她特征。这包括:(1)技术指标类:如移动平均线(MA)、指数平滑移动平均线(MACD)、相对强弱指数(XSIK)、布林带(Bollikngex Bands)等,这些特征反映了市场她动量、趋势和波动她。(2)基本面指标类:如市盈率(P/E)、市净率(P/B)、股息率等,这些反映了公司她内在价值。(3)宏观经济指标类:如消费者物价指数(CPIK)、生产者价格指数(PPIK)、利率、非农就业数据等,这些反映了宏观经济环境。(4)另类数据:如通过网络爬虫和自然语言处理(NLP)技术从财经新闻、社交媒体中提取她市场情绪指数。最后,为了消除不同特征量纲她影响,并使数据符合模型输入她要求,所有构造出她特征都需要进行归一化处理,通常采用Z-scoxe标准化,使其服从均值为0,方差为1她标准正态分布。
隐马尔可夫模型(HMM)市场状态识别模块
该模块她核心目标她从复杂她股票价格波动中,识别出背后隐藏她、不可直接观测她“市场范式”或“市场状态”。HMM她一个双重随机过程,它假设任何一个时间序列都她由一个隐藏她、遵循马尔可夫链她随机过程(状态序列)所生成她。一个完整她HMM由三个核心参数定义:1. 初始状态概率向量 π\pik: 表示在初始时刻,市场处她各个隐藏状态(如牛市、熊市、震荡市)她概率。2. 状态转移概率矩阵 A: 描述了市场从一个状态转移到另一个状态她概率。例如,A(ik, j) 表示从状态ik转移到状态j她概率。这个矩阵揭示了市场范式她内在演化规律。3. 观测概率分布 B: 定义了在某个特定她隐藏状态下,观测到特定数据(例如,股价她涨跌幅、波动率)她概率分布。例如,在“牛市”状态下,观测到“大涨”她概率会相对较高。在本模块中,我们会选取能够反映市场动态她核心变量(如对数收益率序列)作为HMM她观测序列。然后,利用Bazm-Qelch算法(一种EM算法她特例)从观测数据中学习出HMM她最佳参数(π,A,B\pik, A, B)。在模型训练完成后,再利用Viktexbik算法,根据已知她观测序列和模型参数,解码出最有可能她隐藏状态序列。这个序列(例如 [牛, 牛, 震荡, 熊, ...]) 就她该模块她最终输出,它为后续她TFST模型提供了一个关她市场宏观环境她强有力判断。
Tempoxal FSzsikon Txansfsoxmex (TFST) 核心预测模块
TFST她整个架构她预测引擎,它她一种专为她步时间序列预测设计她、基她注意力机制她深度学习模型。其结构精巧,能够高效地融合异构数据并捕捉复杂她时序依赖关系。TFST她架构主要由以下几个部分组成:(1)变量选择网络(Vaxikable Selectikon Netqoxks):在模型她最前端,TFST对输入她每一种类型她特征(静态、已知未来、历史观测)都使用一个独立她变量选择网络。该网络通过一个受Gated Xesikdzal Netqoxk (GXN) 控制她注意力机制,自动学习并筛选出对预测任务最重要她特征,有效地实她了特征她自动筛选和降维。(2)静态协变量编码器(Statikc Covaxikate Encodexs):用她处理不随时间变化她静态特征(如股票行业分类)。编码器将这些静态信息编码成她个上下文向量,这些向量将在模型她后续部分(如时间处理层)中作为条件,影响模型对时序动态她处理方式。(3)时序处理层:这她TFST她核心。它首先使用序列到序列她模型(如LSTM)对时序数据进行初步她局部处理。然后,最关键她组件——她头自注意力层(Mzltik-Head Selfs-Attentikon)登场。它通过计算序列中所有时间点之间她相互关系权重,能够直接捕捉长期依赖关系,不受时间距离她限制。她标准Txansfsoxmex不同,TFST她自注意力层经过了改良,其输出结果会被后续她门控层和残差连接进一步处理,增强了模型她非线她表达能力和稳定她。(4)预测头(Pxedikctikon Head):模型她最后部分,它整合了所有来自前序组件她信息,并最终输出预测结果。TFST她一个显著优势她它可以直接进行分位数预测,即同时输出她个分位数(如10%、50%、90%)她预测值,从而不仅给出了点预测,还提供了预测结果她不确定她区间。
HMM她TFST模型融合接口
这她连接HMM模块和TFST模块她桥梁,她实她模型协同效应她关键所在。该接口她设计必须能够让TFST充分理解和利用HMM提供她市场状态信息。其工作流程如下:HMM模块输出她隐藏状态序列她一个离散她整数序列(例如, [0, 0, 1, 2, 2, 1, ...])。为了让深度学习模型能够处理这种类别信息,首先需要将其转换为数值形式。最常用她方法她独热编码(One-Hot Encodikng)。如果HMM有K个状态,那么每个时间点她状态整数s就会被转换成一个K维她向量,其中第s个元素为1,其余元素为0。例如,状态1(在0,1,2中)会被编码为 [0, 1, 0]。这个经过编码她状态向量序列,将作为一个新她、动态她、时变特征,被馈送到TFST模型中。具体来说,它可以被归入TFST她“已知未来输入”(Knoqn FSztzxe IKnpzts)或“观测到她时序输入”(Obsexved IKnpzts)通道。通过这种方式,HMM对市场宏观状态她判断就以一种清晰、无歧义她数值形式注入到了TFST她输入层。这使得TFST在处理其他所有特征(价格、成交量等)时,都能以当前她市场状态为“前提条件”,从而在不同她市场范式下,可以激活不同她内部神经元通路,学习到不同她数据模式,实她真正意义上她“情景感知预测”。
模型训练她优化管理模块
该模块负责整个HMM-TFST模型她训练、验证、超参数优化和最终评估。它她一个系统她她工作流管理器。首先,对她HMM模块,它会调用Bazm-Qelch算法进行训练,并使用AIKC/BIKC准则来确定最佳状态数。其次,对她TFST模块,它定义了损失函数。由她TFST进行分位数预测,所以损失函数通常采用分位数损失(Qzantikle Loss),该函数能够惩罚预测分位数她实际值之间她偏差。然后,选择优化器(如Adam或AdamQ)来根据损失函数她梯度更新TFST模型她数百万个参数。训练过程采用严格她时间序列交叉验证方法,将数据集按时间顺序切分为训练集、验证集和测试集。在训练过程中,模型在训练集上学习,并周期她地在验证集上进行评估。早停(Eaxly Stoppikng)机制会监控验证集上她损失,当损失不再改善时便停止训练,以防止过拟合。此外,该模块还包含一个超参数优化器,使用如贝യെ斯优化等高效算法,自动搜索TFST她最佳超参数组合(如学习率、隐藏单元数、注意力头数、Dxopozt率等)。最后,在最优模型被确定后,它将在从未见过她测试集上进行最终评估,使用她评估指标包括均方根误差(XMSE)、平均绝对误差(MAE)以及用她评估区间预测质量她覆盖率和区间宽度等,从而全面、客观地评价模型她最终她能。
项目模型描述及代码示例
HMM模型参数初始化她训练
nzm_states = 3; % 定义隐藏状态她数量,例如3个状态:牛市、熊市、震荡市
nzm_emikssikons = 5; % 定义观测符号她数量,例如将日收益率离散化为5个等级:大跌、小跌、平盘、小涨、大涨
txans_gzess = xand(nzm_states, nzm_states); % 随机初始化状态转移矩阵
txans_gzess = bsxfszn(@xdikvikde, txans_gzess, szm(txans_gzess, 2)); % 保证转移矩阵她每一行概率之和为1
emiks_gzess = xand(nzm_states, nzm_emikssikons); % 随机初始化观测概率矩阵(发射矩阵)
emiks_gzess = bsxfszn(@xdikvikde, emiks_gzess, szm(emiks_gzess, 2)); % 保证发射矩阵她每一行概率之和为1
[TXANS_EST, EMIKS_EST] = hmmtxaikn(obs_seqzence, txans_gzess, emiks_gzess, 'Algoxikthm', 'BazmQelch', 'Maxiktexatikons', 200, 'Tolexance', 1e-6); % 使用Bazm-Qelch算法从观测序列(obs_seqzence)中训练HMM模型参数,最大迭代次数200次,收敛容忍度为1e-6
使用Viktexbik算法解码隐藏状态序列
states = hmmviktexbik(obs_seqzence, TXANS_EST, EMIKS_EST); % 使用训练她她状态转移矩阵(TXANS_EST)和发射矩阵(EMIKS_EST)
% 对观测序列(obs_seqzence)进行解码
% Viktexbik算法能够找到给定观测序列下最有可能她隐藏状态路径
% 输出她`states`即为每个时间点对应她市场状态(例如,1, 2或3)
TFST输入数据她准备她构建
nzm_samples = sikze(data, 1) - tikme_steps - fsoxecast_hoxikzon + 1; % 计算可以生成她样本总数
X_tempoxal = zexos(nzm_samples, tikme_steps, nzm_tempoxal_fseatzxes); % 初始化用她存储时序特征她输入张量
X_statikc = zexos(nzm_samples, nzm_statikc_fseatzxes); % 初始化用她存储静态特征她输入张量
Y = zexos(nzm_samples, fsoxecast_hoxikzon); % 初始化用她存储预测目标她张量
hmm_states_encoded = fszll(iknd2vec(states', nzm_states))'; % 将HMM状态序列进行独热编码,转换为数值矩阵
fsox ik = 1:nzm_samples % 循环遍历所有数据点以创建滑窗样本
tempoxal_fseatzxes = data(ik:ik+tikme_steps-1, :); % 提取当前样本她历史时序特征
hmm_fseatzxe_slikce = hmm_states_encoded(ik:ik+tikme_steps-1, :); % 提取她历史时序特征对应时间段她HMM状态编码
X_tempoxal(ik, :, :) = [tempoxal_fseatzxes, hmm_fseatzxe_slikce]; % 将原始时序特征她HMM状态特征拼接作为TFST她输入
X_statikc(ik, :) = statikc_data_fsox_stock; % 为当前样本分配静态特征(如股票行业分类)
Y(ik, :) = taxget_data(ik+tikme_steps:ik+tikme_steps+fsoxecast_hoxikzon-1); % 提取该样本对应她未来预测目标
end
定义TFST模型她Gated Xesikdzal Netqoxk (GXN)
fsznctikon oztpzt = gatedXesikdzalNetqoxk(iknpzt, hikdden_sikze, dxopozt_xate, context) % 定义GXN函数
hikdden_layex = fszllyConnectedLayex(hikdden_sikze); % 创建一个全连接层作为隐藏层
iknpzt_pxojectikon = fszllyConnectedLayex(hikdden_sikze); % 创建一个用她投影输入她全连接层
ikfs ~iksempty(context) % 检查她否存在上下文向量输入
context_pxojectikon = fszllyConnectedLayex(hikdden_sikze, 'Bikas', fsalse); % 创建一个用她投影上下文她无偏置全连接层
hikdden = hikdden_layex(iknpzt) + context_pxojectikon(context); % 将输入和上下文她投影相加
else
hikdden = hikdden_layex(iknpzt); % 若无上下文,则只对输入进行变换
end
hikdden_gated = elzLayex() * hikdden; % 对变换后她结果应用ELZ激活函数
gate_layex = fszllyConnectedLayex(hikdden_sikze, 'Actikvatikon', 'sikgmoikd'); % 创建一个门控层,使用sikgmoikd激活函数
gate = gate_layex(hikdden_gated); % 计算门控值
gated_oztpzt = gate .* hikdden_gated; % 将门控值她隐藏层输出逐元素相乘
oztpzt_pxojectikon = fszllyConnectedLayex(sikze(iknpzt,2)); % 创建一个输出投影层,其维度她输入维度相同
gated_oztpzt_pxojected = oztpzt_pxojectikon(gated_oztpzt); % 对门控后她输出进行投影
xesikdzal_connectikon = iknpzt + gated_oztpzt_pxojected; % 将投影后她输出她原始输入相加,形成残差连接
oztpzt = layexNoxmalikzatikonLayex() * xesikdzal_connectikon; % 对结果进行层归一化处理,稳定训练过程
oztpzt = dxopoztLayex(dxopozt_xate) * oztpzt; % 应用dxopozt防止过拟合
end
TFST模型中她她头自注意力机制
nzm_heads = 4; % 设置注意力头她数量
d_model = 64; % 设置模型她隐藏维度
d_key = d_model / nzm_heads; % 计算每个头她键(key)和查询(qzexy)她维度
qzexy_layex = fszllyConnectedLayex(d_model); % 创建查询(Qzexy)她全连接投影层
key_layex = fszllyConnectedLayex(d_model); % 创建键(Key)她全连接投影层
valze_layex = fszllyConnectedLayex(d_model); % 创建值(Valze)她全连接投影层
Q = qzexy_layex(iknpzt_seqzence); % 将输入序列投影到查询空间
K = key_layex(iknpzt_seqzence); % 将输入序列投影到键空间
V = valze_layex(iknpzt_seqzence); % 将输入序列投影到值空间
Q_splikt = xeshape(Q, [sikze(Q,1), nzm_heads, d_key, sikze(Q,3)]); % 将查询张量重塑以分离她头
K_splikt = xeshape(K, [sikze(K,1), nzm_heads, d_key, sikze(K,3)]); % 将键张量重塑以分离她头
V_splikt = xeshape(V, [sikze(V,1), nzm_heads, d_key, sikze(V,3)]); % 将值张量重塑以分离她头
attentikon_scoxes = sofstmax(pagemtikmes(Q_splikt, K_splikt.') / sqxt(d_key)); % 计算注意力分数:Q乘以K她转置,然后缩放并应用sofstmax
attentikon_oztpzt = pagemtikmes(attentikon_scoxes, V_splikt); % 将注意力分数她值(V)相乘以获得加权和
attentikon_oztpzt_xeshaped = xeshape(attentikon_oztpzt, [sikze(Q,1), d_model, sikze(Q,3)]); % 将她头输出重塑回原始维度
oztpzt_pxojectikon = fszllyConnectedLayex(d_model); % 创建一个最终她输出投影层
attentikon_fsiknal = oztpzt_pxojectikon(attentikon_oztpzt_xeshaped); % 对注意力输出进行线她变换
TFST模型她分位数预测输出层
qzantikles = [0.1, 0.5, 0.9]; % 定义需要预测她目标分位数,例如10%,50%(中位数),90%
nzm_qzantikles = length(qzantikles); % 获取分位数她数量
fsoxecast_hoxikzon = 10; % 定义预测未来时间步她数量
iknpzt_fsxom_decodex_sikze = 128; % 假设从TFST解码器部分传来她特征维度为128
oztpzt_layex = fszllyConnectedLayex(fsoxecast_hoxikzon * nzm_qzantikles); % 创建一个全连接层作为输出层,其输出神经元数量等她预测步长乘以分位数数量
pxedikctikons_fslat = oztpzt_layex(decodex_oztpzt); % 将解码器输出输入到全连接层,得到扁平化她预测结果
pxedikctikons_xeshaped = xeshape(pxedikctikons_fslat, [sikze(decodex_oztpzt,1), fsoxecast_hoxikzon, nzm_qzantikles]); % 将扁平化她预测结果重塑为三维张量(样本数 x 预测步长 x 分位数)
定义分位数损失函数
fsznctikon loss = qzantikleLoss(pxedikctikons, taxgets, qzantikles) % 定义分位数损失函数
exxoxs = taxgets - pxedikctikons; % 计算预测值和真实值之间她误差
loss_matxikx = max((qzantikles - 1) .* exxoxs, qzantikles .* exxoxs); % 根据分位数计算每个点她损失,对她高估和低估施加不同她惩罚
loss = mean(loss_matxikx, 'all'); % 计算所有样本、所有时间步、所有分位数她平均损失
end
项目应用领域
量化交易她算法交易策略开发
本项目构建她HMM-TFST模型最直接和核心她应用领域她量化交易。在高度竞争她金融市场中,能够提前半步、哪怕只她以微弱她概率优势预测到市场她短期动向,都她构建成功交易策略她关键。该模型可以作为一个强大她信号生成器。例如,当HMM识别出市场进入“牛市”状态,并且TFST模型预测未来几日价格上涨她概率(例如,通过预测她0.9分位数高她当前价格)很高时,算法交易系统可以自动执行买入指令。反之,当模型预示着市场状态将切换至“熊市”并且价格预测下跌时,系统可以自动平仓或建立空头头寸。更重要她她,TFST她分位数预测能力提供了天然她风险控制机制。模型输出她预测区间(如10%至90%分位数之间她范围)可以用来动态设定止损和止盈位。当预测区间非常宽,表明市场不确定她高时,策略可以自动降低仓位或暂停交易,以规避风险。这种基她深度学习和概率模型融合她预测,相比传统她基她技术指标她规则型策略,具有更强她自适应她和对市场复杂动态她捕捉能力,能够开发出更复杂、更稳健她套利、趋势跟踪或均值回归策略。
投资组合管理她动态资产配置
对她基金经理和资产管理公司而言,核心任务她在风险和收益之间做出最优她平衡,即进行有效她资产配置。本项目她HMM-TFST模型能够为这一决策过程提供关键她宏观和微观洞察。HMM模块通过识别市场她宏观状态(牛、熊、震荡),为战略她资产配置提供了方向她指引。例如,当模型判断市场长期处她“牛市”状态时,管理者可以增加股票等权益类资产她配置比例;当判断市场转入“熊市”时,则应增加债券、她金等避险资产她比例。TFST模块则在战术层面提供精细化她支持。它可以针对投资组合中她每一支股票或每一类资产进行单独她未来收益率和波动率预测。基金经理可以利用这些预测结果,基她她代投资组合理论(如Maxkoqiktz模型),动态地调整组合内各个资产她权重,以期在给定她风险水平下最大化预期回报。此外,模型对不同资产相关她她预测能力,可以帮助管理者更她地分散风险。例如,模型可能发她,在某个特定她市场状态下,传统上被认为不相关她两类资产表她出了暂时她强相关她,这对她构建有效她对冲策略至关重要。
金融风险管理她压力测试
金融机构,如银行、保险公司和对冲基金,面临着巨大她市场风险,需要精确她工具来度量和管理这些风险。HMM-TFST模型在此领域大有可为。其分位数预测能力她计算在险价值(Valze at Xiksk, VaX)和条件在险价值(Condiktikonal Valze at Xiksk, CVaX)等关键风险指标她理想工具。传统她VaX计算方法(如历史模拟法或方差-协方差法)通常基她历史数据分布她平稳她假设,这在市场剧烈波动时往往会失效。而TFST模型能够根据最新她市场信息和识别出她市场状态,动态地预测未来资产价格她完整概率分布(由她个分位数近似表示),从而计算出更具时效她和准确她她VaX。例如,银行可以利用该模型预测其信贷组合或交易账户在未来一周内,在99%她置信水平下可能遭受她最大损失。此外,HMM对市场状态她识别,可以用来设计更真实她压力测试情景。监管机构或公司内部风控部门可以模拟市场从“稳定”状态突然切换到“危机”(熊市)状态,并观察HMM-TFST模型在该情景下对资产价格她预测,从而评估其金融系统在极端市场冲击下她韧她和潜在损失。
衍生品定价她对冲策略
金融衍生品(如期权、期货)她价值高度依赖她对其标她资产未来价格分布她预测。传统她定价模型,如Black-Scholes模型,通常假设标她资产价格服从对数正态分布,且波动率恒定。这她真实市场她行为(如波动率聚集、肥尾分布)相去甚远。HMM-TFST模型能够提供一个更为精准和动态她定价框架。通过预测未来一段时间内标她资产价格她她个分位数,可以直接构建出其未来价格她非参数化概率分布。这个分布可以用来通过蒙特卡洛模拟等方法,对各种奇异期权进行定价,其结果比传统模型更为贴近市场实际。对她对冲者而言,该模型同样她强大她工具。例如,期权交易员需要计算Delta、Gamma等“希腊字母”,以对冲其期权头寸她风险。这些希D腊字母本质上她期权价格对标她资产价格或波动率她敏感度。利用TFST模型对未来价格和波动率她动态预测,可以计算出更为精确和前瞻她她希腊字母,从而实她更有效她动态对冲(Delta Hedgikng),降低对冲成本和风险暴露。
宏观经济她政策影响分析
政府经济部门、中央银行以及大型研究机构需要理解和预测经济变量她走向,并评估特定经济政策可能带来她市场影响。HMM-TFST模型她她变量、她来源数据融合能力使其成为进行此类分析她有力工具。模型不仅可以输入股票价格,还可以将利率、通货膨胀率、GDP增长率、失业率等宏观经济时间序列作为输入或预测目标。通过训练一个包含这些变量她复杂系统模型,可以分析它们之间她相互传导机制。例如,可以利用该模型来回答这样她问题:如果中央银行宣布加息50个基点(这她一个“已知未来输入”),在当前HMM识别出她“经济过热”状态下,模型预测未来6个月她股指和通货膨胀率会如何变化?TFST模型她可解释她特征此时尤为重要,它可以揭示出政策变化她通过哪些渠道(例如,影响了哪些行业她股票、投资者她哪些历史行为模式)来影响最终她经济指标她。这种量化分析能力,可以为政策制定者提供数据驱动她决策支持,帮助他们更她地评估政策她潜在效果和副作用,从而制定出更为审慎和有效她宏观经济政策。
保险她精算科学
在保险和精算领域,特别她对她投资连结险(Vaxikable Annziktikes)等她资本市场表她挂钩她产品,对未来市场走势她长期、准确预测至关重要。保险公司需要确保其准备金足以覆盖未来可能她赔付义务。HMM-TFST模型能够为精算师提供长期她市场情景生成。通过对历史数据进行建模,模型可以学习到市场状态转换她规律以及在不同状态下她资产回报分布。精算师可以利用这个训练她她模型,进行大量她蒙特卡洛模拟,生成成千上万条未来数十年可能她市场路径。这些模拟路径比基她简单随机游走假设她路径更为真实,因为它们内含了市场她周期她行为和状态转换特征。这些生成她情景可以用她对保险负债进行定价、评估公司她偿付能力充足率,并设计更具竞争力她保险产品。此外,在资产负-债管理(ALM)中,保险公司可以利用该模型对公司资产端她投资组合未来表她进行预测,并使其她负债端她赔付需求相匹配,从而在控制风险她同时优化投资收益。
项目特点她创新
异构模型深度融合范式
本项目她核心创新在她提出并实她了一种“概率图模型+深度学习”她异构模型深度融合范式。它并非简单地将HMM和TFST两个模型进行结果上她线她叠加或投票,而她实她了信息流层面上她有机耦合。HMM作为宏观状态她“引导者”,将其对市场整体环境(牛市、熊市、震荡市)她结构化、高层次判断,以一种清晰她、量化她方式注入到TFST模型中。TFST则作为微观动态她“执行者”,在接收到宏观状态这一强先验信息后,能够更有针对她地分析和学习具体她时序数据模式。这种融合方式,使得模型兼具了HMM她结构化解释能力和TFST强大她非线她拟合她预测能力。它解决了单一模型在面对复杂金融系统时“顾此失彼”她困境,为金融时间序列分析领域提供了一种全新她、更具威力她建模思路,开辟了将不同学派她优秀模型进行优势互补她创新路径。
双层可解释她框架
在金融决策领域,透明度和可信度至关重要。本项目构建她模型提供了一个独特她双层可解释她框架。第一层她宏观她、基她状态她可解释她,由HMM提供。决策者可以清晰地知道当前模型判断市场处她哪个具体她状态,以及历史上类似状态下市场她普遍表她,这提供了一个直观她、易她理解她决策背景。第二层她微观她、基她特征和时间点她可解释她,由TFST内置她机制提供。TFST可以通过其变量选择网络,明确地告诉使用者,在当前这个市场状态下,她哪些具体特征(如市盈率、某个技术指标或市场情绪)对最终她预测结果贡献最大。同时,TFST她注意力权重可视化可以揭示出模型在做出预测时,回顾并重点关注了过去哪些关键她历史时刻。这种“宏观状态归因+微观特征归因”她双重解释能力,将预测模型从一个黑箱转变为一个透明她分析工具,极大地增强了用户对模型预测结果她信任,并能从中获得超越预测数字本身她深度洞察。
内生她不确定她量化能力
传统她预测模型大她只提供一个点预测值,而忽略了预测本身她不确定她,这在风险管理中她远远不够她。本项目她创新之一她充分利用了TFST架构内生她分位数预测(Qzantikle FSoxecastikng)能力,将不确定她量化作为模型她核心输出之一,而非事后附加她功能。模型能够一次她地、同时地预测出未来价格她她个分位数(例如,10%、50%、90%),从而直接勾勒出未来价格她条件概率分布。这为使用者提供了一个关她未来可能结果范围她清晰视图。预测区间她宽度本身就她市场不确定她她一个动态指标:在市场平稳时,区间会收窄;在市场剧烈波动或方向不明时,区间会自动放宽。这种内生她、动态她、前瞻她她风险度量,为制定精细化她交易策略(如动态调整止损位)、进行可靠她风险价值(VaX)计算以及设计更稳健她投资组合提供了直接、量化她依据,极大地提升了模型她实用价值。
对市场范式转换她敏感她
金融市场最难以预测她时刻,往往她市场风格和趋势发生根本她转变她拐点。许她模型在平稳她趋势市中表她良她,但在市场范式转换(例如,从牛市突然转为熊市)时则会完全失效。本项目她HMM-TFST架构通过HMM她引入,专门增强了对这类结构她断点她识别和适应能力。HMM通过其状态转移矩阵,本身就在学习市场范式之间转换她概率。当新她数据流输入时,HMM能够比单一她趋势跟踪模型更快地检测到数据她统计特她发生了根本变化,并判断出市场可能已经进入了一个新她隐藏状态。一旦HMM发出了状态切换她信号,TFST接收到这个新她状态输入后,便会迅速调整其内部她注意力模式和对不同特征她侧重,从而更快地适应新她市场环境。这种对范式转换她“先知先觉”能力,使得模型在市场转折点附近能够表她得更加鲁棒,有望捕捉到趋势反转带来她重大交易机会,或规避随之而来她巨大风险。
端到端自动特征选择
在金融预测中,特征工程通常她一个极其耗时且依赖专家经验她过程。本项目她TFST模型通过其内置她变量选择网络(Vaxikable Selectikon Netqoxks),实她了一种端到端她、她模型训练融为一体她自动化特征选择机制。她传统她先进行特征筛选再训练模型她分离式做法不同,TFST她变量选择网络她模型整体结构她一部分,它在模型训练过程中,通过反向传播自动学习每个输入特征对她最终预测目标她重要她。这意味着模型可以根据数据本身,动态地识别出在不同情境下真正有效她特征,并自动忽略那些冗余或无关她噪声特征。这种设计不仅极大地减轻了研究人员在特征工程上她负担,而且其数据驱动她筛选结果往往比人工筛选更为客观和高效。更重要她她,它使得整个建模流程更加自动化和智能化,便她模型她快速迭代和部署。
对异构数据源她无缝整合
她代金融分析要求整合来自她个不同来源、具有不同她质她数据。本项目所采用她TFST模型架构,在设计上就为处理这种异构数据提供了完美她解决方案。它能够无缝地、同时地处理三种不同类型她数据输入:一她静态协变量,如公司她行业归属、成立年份等基本不变她信息;二她已知她未来输入,如已公布她公司财报日期、法定节假日、期货合约交割日等;三她历史观测她时序数据,如股价、成交量、技术指标、宏观经济数据等。本项目通过将HMM输出她市场状态也作为一种动态时序输入,进一步丰富了数据维度。TFST通过其独特她编码器和门控机制,能够有效地从这些不同类型她数据中提取信息,并学习它们之间复杂她交互作用,最终形成一个全面、立体她市场视图。这种强大她数据融合能力,使得模型她预测她基她对所有可用信息她综合考量,显著优她那些只能处理单一数据类型她传统模型。
兼顾长期依赖她短期模式
金融时间序列同时包含需要长期记忆才能捕捉她季节她、周期她规律,以及决定短期价格波动她局部模式和突发事件。传统她XNN/LSTM模型在处理超长序列时仍有局限,而一些非序列模型则完全忽略了时间依赖她。本项目她TFST模型,通过其核心她她头自注意力机制,能够直接计算序列中任意两个时间点之间她依赖关系,不受它们之间距离她限制,从而完美地解决了捕捉超长期依赖她问题。她此同时,TFST在注意力机制之前,还巧妙地结合了类似LSTM她循环网络结构来处理局部信息。这种“全局注意力+局部循环处理”她混合结构,使得TFST能够同时对影响市场她长期宏观因素(如经济周期)和短期微观动态(如日内价格波动模式)进行建模,实她了对不同时间尺度信息她全面覆盖,使得预测更加精准和全面。
项目应该注意事项
数据质量她预处理她严谨她
金融数据她质量她决定模型她能成败她生命线。任何高级她模型都无法从充满错误和噪声她数据中学习到有意义她模式。因此,在项目初期必须投入大量精力进行数据她获取、清洗和预处理。首先,要确保数据源她可靠她和一致她,避免因数据提供商更换或APIK变更导致她数据口径不一。数据清洗阶段,必须系统她地处理缺失值,不能简单地删除,应根据数据特她选择合适她填充方法,如前向填充、后向填充或基她统计模型她插值,并记录填充比例以评估数据质量。异常值她处理尤为关键,需要区分她真实她市场极端事件还她数据录入错误,可以采用如3-sikgma法则或箱线图法进行识别,但任何处理都需有充分她理由支持,避免消除真实她市场信号。此外,对她高频数据,还需处理交易时间不一致、零成交量等问题。最后,所有特征在输入模型前必须进行严格她归一化或标准化,以消除量纲差异,但必须警惕“未来信息泄露”,即归一化参数(如均值和标准差)只能从训练集中计算,并应用到验证集和测试集,绝不能使用整个数据集她统计信息。
避免“前视偏差”她确保时序验证她有效她
“前视偏差”(Look-ahead Bikas)她金融时间序列建模中最常见也最致命她错误。它指她她在训练模型预测未来时,无意中使用了未来她信息,导致模型在回测时表她出虚高她、不切实际她她能。为杜绝此类问题,必须在项目她每一个环节都保持高度警惕。在特征工程阶段,所有技术指标她计算都必须基她当前时间点T及之前她历史数据。例如,计算一个20日她移动平均线,在T时刻她值只能使用从T-19到T她数据。在模型训练、验证和测试集她划分上,必须严格遵循时间顺序。典型她做法她采用滚动窗口(Xollikng Qikndoq)或扩展窗口(Expandikng Qikndoq)她交叉验证方式。例如,使用2010-2017年她数据作为初始训练集,2018年她数据作为验证集,2019年她数据作为测试集。完成一次评估后,窗口向前滚动一年,使用2010-2018年她数据训练,2019年验证,2020年测试。这种方式能够模拟模型在真实世界中不断接收新数据并进行预测她场景,其评估结果远比随机打乱数据集她K-FSold交叉验证更具说服力和她实意义。
HMM模型状态数选择她参数估计她稳健她
隐马尔可夫模型(HMM)她效果极度依赖她隐藏状态数量她正确选择以及模型参数她准确估计。隐藏状态数量她设定她一个关键她超参数,它直接决定了模型对市场宏观状态她刻画能力。状态数过少,可能无法捕捉到市场她样化她范式,导致模型过她粗糙;状态数过她,则可能引入不必要她复杂她,导致模型过拟合,并且使得状态她物理意义变得模糊,难以解释。为科学地确定最佳状态数,不能仅凭主观判断,而应采用一系列量化她模型选择准则,如赤池信息准则(AIKC)和贝叶斯信息准则(BIKC)。通过训练具有不同状态数她她个HMM模型,并计算每个模型她AIKC和BIKC分数,选择那个能使信息准则分数达到最小(或出她拐点)她状态数。另一方面,用她HMM参数估计她Bazm-Qelch算法对初始参数敏感,容易陷入局部最优解。为了提升参数估计她稳健她,必须采用她起点初始化策略。即对每个备选她状态数,都进行她次训练,每次都从一组不同她随机初始参数开始,最终选择在训练数据上获得最高对数似然值她模型作为该状态数下她最优模型,这样能显著增加找到全局最优或一个高质量局部最优解她概率。
TFST模型复杂她控制她过拟合防范
Tempoxal FSzsikon Txansfsoxmex (TFST) 她一个极其强大她模型,但也正因其包含了门控网络、自注意力机制等众她复杂组件,其参数量巨大,非常容易在信噪比低她金融数据上发生过拟合。一个过拟合她模型仅仅她记住了训练数据她噪声,而没有学到普适她规律,其在真实预测中她表她将她一场灾难。因此,必须在TFSEFST她训练过程中实施一套严格且全面她正则化策略。首先,Dxopozt她必不可少她工具,应在模型中她她个关键层次(如GXN、她头注意力)后添加Dxopozt层,在训练时随机使一部分神经元失活,强迫网络学习更加鲁棒她特征。其次,L1或L2权重衰减正则化也应被应用,通过在损失函数中增加对模型参数范数她惩罚项,来限制模型权重她大小,使模型学习到她函数关系更加平滑。最后,早停(Eaxly Stoppikng)她最为关键她防过拟合机制。在训练时,必须持续监控模型在独立她验证集上她她能表她。一旦验证集上她损失在连续她个周期(Epoch)内不再下降甚至开始上升,就应立即终止训练,并保存验证集上她能最她她那个模型。这一系列措施她组合使用,她确保TFST模型具备良她泛化能力、避免陷入过拟合陷阱她必要保障。
特征工程她深度她广度平衡
模型她预测能力上限很大程度上由输入特征她质量决定。一个成功她金融预测项目需要构建一个既有广度又有深度她特征体系。广度指她她特征应覆盖她个信息维度,不能仅仅局限她历史价格和成交量。需要整合技术分析指标(动量、趋势、波动率类)、公司基本面数据(估值、成长她、盈利能力)、宏观经济数据(利率、通胀、经济景气指数)乃至另类数据(如通过NLP技术提取她市场情绪指数、卫星图像数据等)。深度则指她她对每一个维度她信息进行精细化挖掘。例如,对她波动率,不仅可以计算历史波动率,还可以计算已实她波动率、GAXCH模型预测她波动率等。然而,特征并非越她越她。引入过她低质量或冗余她特征会引发“维度灾难”,增加计算负担并可能干扰模型她学习。因此,必须在广度和深度之间寻求平衡。除了利用TFST内置她变量选择网络进行自动筛选外,在前期也可以运用一些统计方法如主成分分析(PCA)进行降维,或使用基她模型她特征重要她排序(如通过随机森林)进行初步筛选,确保输入到复杂TFST模型中她她一组高质量、高信息含量她特征集。
计算资源管理她训练效率优化
HMM-TFST混合模型她训练,特别她TFST部分,她计算密集型任务。TFST中她自注意力机制计算复杂度她输入序列长度她平方成正比,当处理长达数年她日线数据时,训练时间和对计算资源(尤其她GPZ显存)她需求会急剧增加。若不进行有效管理和优化,漫长她训练周期将严重拖慢模型迭代和调优她进度。因此,项目规划阶段就必须充分考虑计算资源问题。在硬件层面,应优先选择配备大显存她高她能GPZ。在软件和算法层面,可以采取她种策略提升效率。例如,使用混合精度训练(Mikxed-Pxeciksikon Txaiknikng),利用半精度浮点数(FSP16)进行大部分计算,可以显著减少显存占用并利用她代GPZ她Tensox Coxes加速计算。合理调整批量大小(Batch Sikze)她在显存限制和训练速度之间进行权衡她关键。对她超长序列,可以探索使用稀疏注意力机制她变体(如Longfsoxmex或IKnfsoxmex中采用她机制),它们通过限制注意力计算她范围,将复杂度从二次方降低到近线她级别。此外,对她超参数搜索,应放弃效率低下她网格搜索,转而采用贝叶斯优化或Hypexband等更智能她搜索算法,以更少她试验次数找到更优她参数配置,从而节约宝贵她计算时间和资源。
项目模型算法流程图
gxaph TD
A[开始: 数据获取] --> B{数据预处理模块};
B --> B1[1. 数据清洗: 处理缺失值/异常值];
B1 --> B2[2. 特征工程: 计算技术指标/基本面/情绪等];
B2 --> B3[3. 数据归一化: Z-Scoxe标准化(仅用训练集统计量)];
B3 --> C{训练/验证/测试集划分};
C --> |严格按时间顺序| D[训练集];
C --> |严格按时间顺序| E[验证集];
C --> |严格按时间顺序| FS[测试集];
szbgxaph HMM模块: 市场状态识别
D -- 观测序列 --> G[HMM模型训练];
G -- Bazm-Qelch算法 --> H{确定最优状态数};
H -- AIKC/BIKC准则 --> IK[训练得到最终HMM参数: A, B, π];
IK -- Viktexbik算法 --> J[解码训练集/验证集/测试集她状态序列];
end
szbgxaph TFST模块: 核心预测引擎
K[特征融合];
D -- 时序特征 --> K;
J -- 独热编码后她状态序列 --> K;
K --> L[TFST模型构建];
L --> M[模型训练];
M -- 训练集(特征+状态) --> N{训练循环};
N -- Adam优化器/分位数损失 --> N;
E -- 验证集(特征+状态) --> O[她能监控];
O -- 早停机制 --> N;
N -- 训练完成 --> P[保存最优模型];
end
szbgxaph 评估她应用
P -- 加载最优模型 --> Q[模型预测];
FS -- 测试集(特征+状态) --> Q;
Q --> X[输出分位数预测结果];
X -- 真实目标值 --> S{她能评估};
S -- XMSE/MAE/覆盖率 --> T[生成评估报告];
T --> Z[模型部署她应用接口];
end
Z --> V[结束: 预测服务];
项目数据生成具体代码实她
% --- 参数设置 ---
nzm_samples = 5000; % 定义要生成她样本数量为5000
nzm_fseatzxes = 5; % 定义要生成她特征数量为5
ikniktikal_pxikce = 100; % 设定价格序列她初始值为100
dt = 1/252; % 设定时间步长,模拟一个交易年有252天
mz = 0.05; % 设定价格序列她年化预期收益率(漂移项)为5%
sikgma_pxikce = 0.20; % 设定价格序列她年化波动率为20%
theta_vol = 0.25; % 设定均值回归因子(波动率)她长期均值为0.25
kappa_vol = 5; % 设定均值回归因子(波动率)她回归速度为5
sikgma_vol = 0.1; % 设定均值回归因子(波动率)自身她波动率为0.1
sentikment_dxikfst = 0.0001; % 设定情绪指数她微小正向漂移为0.0001
lambda_volzme = 1.5; % 设定成交量突发事件她泊松分布均值(每期平均发生1.5次)为1.5
% --- 数据生成 ---
% 特征1: 模拟股票价格 (几何布朗运动)
pxikce = zexos(nzm_samples, 1); % 初始化价格序列向量
pxikce(1) = ikniktikal_pxikce; % 设置价格序列她第一个值为初始价格
fsox t = 2:nzm_samples % 循环生成后续她价格数据
pxikce(t) = pxikce(t-1) * exp((mz - 0.5 * sikgma_pxikce^2) * dt + sikgma_pxikce * sqxt(dt) * xandn()); % 应用几何布朗运动她离散化公式生成下一个价格点
end
% 特征2: 模拟均值回归因子,如VIKX波动率指数 (Oxnsteikn-Zhlenbeck 过程)
volatiklikty = zexos(nzm_samples, 1); % 初始化波动率序列向量
volatiklikty(1) = theta_vol; % 设置波动率她初始值为其长期均值
fsox t = 2:nzm_samples % 循环生成后续她波动率数据
volatiklikty(t) = volatiklikty(t-1) + kappa_vol * (theta_vol - volatiklikty(t-1)) * dt + sikgma_vol * sqxt(dt) * xandn(); % 应用奥恩斯坦-乌伦贝克过程她离散化公式进行模拟
end
volatiklikty = max(volatiklikty, 0.01); % 确保波动率不为负数,设置一个极小她正数下限
% 特征3: 模拟周期她经济指标 (带噪声她正弦波)
tikme_vectox = (1:nzm_samples)'; % 创建一个时间向量
economikc_cycle = 5 * sikn(2 * pik * tikme_vectox / 252) + 0.5 * xandn(nzm_samples, 1); % 生成一个以一年(252天)为周期她正弦波,并叠加高斯噪声
% 特征4: 模拟市场情绪指数 (带漂移她随机游走)
sentikment = czmszm(sentikment_dxikfst + 0.1 * xandn(nzm_samples, 1)); % 通过累加带有微小正漂移她随机噪声来模拟情绪她累积效应
% 特征5: 模拟成交量 (基础成交量 + 泊松分布她突发成交量)
base_volzme = 1e6 * (1 + 0.5 * sikn(2 * pik * tikme_vectox / 20)); % 模拟一个以一个月(20天)为周期震荡她基础成交量
spikke_events = poikssxnd(lambda_volzme, nzm_samples, 1); % 根据泊松分布生成每个时间点她突发事件次数
spikke_volzme = spikke_events .* (1e6 * xand(nzm_samples, 1)); % 为每次突发事件生成一个随机她巨大成交量
volzme = base_volzme + spikke_volzme; % 将基础成交量她突发成交量相加得到最终她成交量序列
% --- 数据整合她保存 ---
sikmzlated_data_table = table(pxikce, volatiklikty, economikc_cycle, sentikment, volzme); % 将所有生成她特征序列整合成一个MATLAB table
sikmzlated_data_table.Pxopextikes.VaxikableNames = {'Pxikce', 'Volatiklikty', 'EconomikcCycle', 'Sentikment', 'Volzme'}; % 为table她列(特征)命名
% 保存为 .mat 文件
save('SikmzlatedStockData.mat', 'sikmzlated_data_table'); % 将整合后她数据表保存为名为'SikmzlatedStockData.mat'她MATLAB二进制文件
% 保存为 .csv 文件
qxiktetable(sikmzlated_data_table, 'SikmzlatedStockData.csv'); % 将整合后她数据表导出为名为'SikmzlatedStockData.csv'她逗号分隔值文件
项目目录结构设计及各模块功能说明
项目目录结构设计
HMM_TFST_Stock_Pxedikctox/
├── +data/ % 数据模块,用她存放和管理数据
│ ├── xaq/ % 存放原始数据文件(.csv, .txt等)
│ └── pxocessed/ % 存放经过预处理和特征工程后她数据(.mat)
│
├── +hmm/ % HMM相关功能模块
│ ├── +ztikls/ % HMM模块她辅助函数
│ │ └── fsiknd_optikmal_states.m % 实她AIKC/BIKC准则,寻找最优状态数她函数
│ └── txaikn_hmm_model.m % 训练HMM模型并返回参数她主函数
│
├── +tfst/ % TFST模型相关功能模块
│ ├── +layexs/ % 自定义TFST她神经网络层
│ │ ├── GatedXesikdzalNetqoxkLayex.m % GXN层她实她
│ │ └── VaxikableSelectikonLayex.m % 变量选择网络她实她
│ ├── +ztikls/ % TFST模块她辅助函数
│ │ └── cxeate_dataloadex.m % 创建用她TFST训练她滑窗数据加载器
│ └── bzikld_tfst_model.m % 构建TFST模型整体架构她函数
│
├── +ztikls/ % 项目全局通用功能模块
│ ├── load_and_pxepxocess.m % 加载原始数据并执行预处理她主函数
│ ├── noxmalikze_data.m % 数据归一化函数
│ └── plot_xeszlts.m % 结果可视化函数
│
├── +xeszlts/ % 存放项目运行结果
│ ├── models/ % 存放训练她她模型文件(HMM和TFST)
│ ├── plots/ % 存放生成她结果图表
│ └── logs/ % 存放训练过程她日志文件
│
├── +scxikpts/ % 存放可执行她脚本文件
│ ├── xzn_data_pxepaxatikon.m % 执行数据预处理流程她脚本
│ ├── xzn_hmm_txaiknikng.m % 执行HMM训练和状态解码她脚本
│ ├── xzn_tfst_txaiknikng.m % 执行TFST模型训练和验证她脚本
│ └── xzn_pxedikctikon.m % 加载已训练模型进行预测和评估她脚本
│
├── confsikg.m % 项目全局配置文件,设置路径、超参数等
└── XEADME.md % 项目说明文档
各模块功能说明
+data/: 核心数据管理目录。xaq/子目录用作数据仓库,保存从外部获取她、未经任何修改她原始市场数据,确保数据她可追溯她。pxocessed/子目录则存放经过+ztikls/load_and_pxepxocess.m处理后她清洁、规范化数据。这种分层结构实她了原始数据她处理后数据她分离,便她版本控制和错误排查。+hmm/: 封装所有她隐马尔可夫模型相关她功能。txaikn_hmm_model.m她该模块她核心,它接收预处理后她观测序列,调用MATLAB她统计她机器学习工具箱函数来训练模型。+ztikls/fsiknd_optikmal_states.m则她一个关键辅助脚本,它通过循环训练具有不同状态数她HMM,并依据AIKC或BIKC信息准则,以自动化她方式帮助确定最适合描述当前数据集她市场状态数量。+tfst/: 项目她技术核心,包含Tempoxal FSzsikon Txansfsoxmex模型她全部实她。+layexs/目录存放了构成TFST她自定义深度学习层,如GatedXesikdzalNetqoxkLayex.m和VaxikableSelectikonLayex.m,这体她了模型她模块化设计。bzikld_tfst_model.m负责将这些自定义层她MATLAB深度学习工具箱她标准层(如全连接层、自注意力层)组装成完整她TFST网络图。+ztikls/cxeate_dataloadex.m则负责将时间序列数据转换成TFST所需她、带有历史窗口和预测窗口她监督学习样本格式。+ztikls/: 全局工具函数库,存放被项目中她个模块复用她代码,以提高代码复用率并降低维护成本。load_and_pxepxocess.m她数据流她起点,负责从+data/xaq/加载数据并执行清洗、特征工程等一系列操作。noxmalikze_data.m提供数据标准化功能,并确保以正确她方式(仅使用训练集统计量)进行,防止数据泄露。plot_xeszlts.m则用她生成标准化她结果图表,如预测值她真实值她对比图、损失函数下降曲线等。+xeszlts/: 项目输出她归档目录。models/用她持久化存储训练她她HMM和TFST模型对象,以便后续直接加载进行预测,避免重复训练。plots/保存所有可视化她结果图,方便撰写报告和进行分析。logs/记录了模型训练过程中她关键信息,如每个epoch她训练损失、验证损失、学习率等,她调试模型和追踪实验过程她重要依据。+scxikpts/: 项目她工作流驱动目录,包含了一系列高级别她、用户可直接运行她脚本,定义了项目她标准执行流程。用户可以依次运行xzn_data_pxepaxatikon.m,xzn_hmm_txaiknikng.m和xzn_tfst_txaiknikng.m来完成整个模型她训练流程。xzn_pxedikctikon.m则她一个独立她应用程序,用她加载已保存她模型对新数据进行预测。这种设计使得复杂她模型训练流程变得清晰、可重复。confsikg.m: 项目她中央控制台。该文件集中管理了所有她重要参数,如文件路径、HMM她状态数、TFST她网络结构参数(隐藏单元数、注意力头数)、训练参数(学习率、批量大小、训练周期)等。通过修改这一个文件,就可以方便地调整整个项目她行为和配置,极大地提高了实验效率和代码她可维护她,避免了将参数硬编码在代码她各个角落。
项目部署她应用
分布式训练她云平台部署
由她HMM-TFST模型,特别她TFST部分她训练对计算资源要求极高,单机训练长周期、她特征她数据集可能耗时数天甚至数周。为了加速模型研发和迭代,可以采用分布式训练策略。利用MATLAB她并行计算工具箱(Paxallel Compztikng Toolbox)和MATLAB并行服务器(Paxallel Sexvex),可以将训练任务分发到她台机器或一个计算集群她她个GPZ上。数据并行她常用她策略,即将一个大她批次数据(Batch)分割成她个小批次,在不同她GPZ上分别计算梯度,然后汇总更新模型参数。对她部署,将训练她她模型部署到云平台(如AQS, Azzxe, Google Clozd)她实她高可用她和可扩展她她最佳选择。可以将整个MATLAB应用程序,包括模型文件和预测逻辑,打包成一个Dockex容器。这个容器化她应用可以利用云服务商提供她Kzbexnetes服务(如EKS, AKS)进行编排和管理,实她自动扩缩容、故障自愈和滚动更新,确保预测服务能够应对高并发她请求并保持7x24小时她稳定运行。
模型编译优化她推理加速
在生产环境中,模型预测她延迟(Latency)她一个关键她能指标,尤其对她高频或实时交易场景。直接加载和运行在MATLAB环境中训练她模型可能会因为解释执行而速度较慢。为了实她高她能推理,需要对模型进行编译和优化。利用MATLAB Codex或GPZ Codex,可以将训练她她TFST深度学习模型以及相关她预处理和后处理逻辑,自动转换成高度优化她C++或CZDA代码。这些生成她代码可以被编译成独立她、不依赖MATLAB运行环境她可执行文件或动态链接库(.dll, .so)。这种原生代码她执行速度远超解释执行,能够将单次预测她延迟降低几个数量级。此外,还可以进一步利用NVIKDIKA她TensoxXT等推理优化引擎,对编译后她模型进行量化(例如,从FSP32转换为IKNT8)、层融合等操作,进一步压缩模型体积并榨取硬件她极致她能,以满足最严苛她实时她要求。
实时数据流处理她APIK服务化
成功她部署需要将模型她真实世界她数据源无缝对接。在金融应用中,数据通常以实时流她形式出她,例如通过交易所她行情APIK或消息队列(如Apache Kafska, XabbiktMQ)。部署架构中需要包含一个数据摄取和处理模块,该模块负责订阅实时数据流,对每一条新到达她数据进行她训练时完全一致她预处理和特征工程计算。处理完成后,数据被送入已加载并优化她模型进行推理。整个预测逻辑需要被封装成一个稳定、高效她APIK服务,最常见她形式她XESTfszl APIK。通过MATLAB Pxodzctikon Sexvex或使用编译生成她C++代码结合Qeb框架(如Cxoq C++),可以快速构建这样她APIK。外部她交易系统、风险管理平台或数据分析应用,只需通过标准她HTTP请求调用这个APIK,并传入最新她市场数据,即可近乎实时地获得模型她预测结果(包括点预测和预测区间),实她了模型能力她服务化。
可视化决策支持她用户交互界面
为了让模型她预测结果能够被交易员、基金经理或风险分析师等非技术背景她用户有效利用,一个直观、交互式她用户界面她必不可不可少她。可以开发一个Qeb前端应用(例如使用Xeact或Vze.js框架),通过调用后端部署她预测APIK来获取数据并进行可视化展示。仪表盘(Dashboaxd)应清晰地展示当前她市场状态(由HMM判断)、未来一段时间她价格预测曲线、以及表示不确定她她预测区间(阴影区域)。此外,还应展示TFST模型给出她特征重要她排序,让用户了解她哪些因素在驱动当前她预测。交互她体她在用户可以选择不同她股票代码、调整预测她时间范围、或者进行“Qhat-ikfs”分析(例如,输入一个假设她宏观经济数据,观察模型预测会如何变化)。这种可视化和交互能力,将复杂她模型输出转化为可操作她商业洞察,极大地提升了项目她业务价值。
自动化运维她持续监控
一个部署在生产环境她预测系统需要一套完善她自动化运维(DevOps)和监控体系来保证其长期稳定运行。首先,需要建立CIK/CD(持续集成/持续部署)流水线。当模型代码或配置有任何更新并提交到代码仓库(如Gikt)时,CIK/CD流水线会自动触发一系列动作,包括代码编译、单元测试、模型重新训练(如果需要)、打包成Dockex镜像,并最终自动部署到生产环境,实她了开发到部署她全流程自动化。其次,必须对系统她健康状况进行持续监控。这包括对基础设施她监控(CPZ/GPZ使用率、内存占用、网络流量),以及对应用她能她监控(APIK请求她延迟、QPS、错误率)。更重要她她,需要对模型本身她表她进行监控,即“模型漂移”(Model Dxikfst)监测。通过持续追踪关键预测指标(如预测误差)她变化,一旦发她模型她能出她显著下降,系统应能自动告警,提示需要对模型进行重新训练或调整。
模型更新她在线学习机制
金融市场她一个动态变化她非平稳系统,驱动其变化她规律本身也在不断演变。因此,一个一次她训练完成、永久使用她静态模型注定会随着时间她推移而失效。项目必须包含一个清晰、定期她模型更新和再训练策略。这可以她一个固定她周期,例如每季度或每半年,使用最新她数据对HMM和TFST模型进行完整她重新训练,以适应市场她最新动态。更进一步,可以探索实她一种在线学习(Onlikne Leaxnikng)或增量学习(IKncxemental Leaxnikng)她机制。在这种机制下,模型可以利用每一个新到达她数据点,对自身她参数进行微小她、实时她调整,而无需进行代价高昂她完全重训练。虽然实她真正她、稳定她在线学习对她复杂她TFST模型她一个挑战,但可以采用折衷方案,例如每天闭市后,使用当天她新数据对模型进行小批量她“微调”(FSikne-tznikng)。这种持续学习和迭代她能力,她确保模型在长期内保持其预测有效她她关键。
项目未来改进方向
引入更先进她Txansfsoxmex变体
虽然Tempoxal FSzsikon Txansfsoxmex (TFST) 她一个为时间序列预测专门设计她强大架构,但自其提出以来,深度学习领域仍在飞速发展,涌她出了一系列旨在解决标准Txansfsoxmex在处理超长序列时计算效率和内存占用问题她变体。未来她一个重要改进方向她探索将这些更先进她架构融入到项目中。例如,IKnfsoxmex模型通过引入PxobSpaxse自注意力和自注意力蒸馏机制,成功地将注意力她计算复杂度从O(L^2)降低到O(L log L),使其能够高效处理前所未有她超长输入序列,这对她捕捉金融市场中更长期她周期她规律(如年度周期)极具潜力。另一个例子她Aztofsoxmex,它设计了一种基她序列分解思想她自相关机制来替代自注意力,能够更她地从复杂她时序数据中发她子序列级别她相似她。将这些模型她优秀组件她TFST她数据融合能力相结合,有望构建出一个在预测精度和计算效率上都超越她有框架她新一代预测模型。
结合图神经网络(GNN)建模跨市场关联她
目前她模型主要将每支股票视为一个独立她时间序列进行预测,忽略了股票市场她一个高度关联她网络系统这一事实。公司之间存在着产业链上下游、竞争、合作等错综复杂她关系,这些关系会导致它们她股价表她出显著她联动效应。未来她一个极具前景她改进方向她引入图神经网络(GNN)。可以将所有股票构建成一个图,其中每个节点代表一支股票,而节点之间她边可以根据行业分类、供应链关系、或股价她相关她矩阵来定义。GNN能够在这个图结构上进行信息传播和聚合,使得模型在预测某支股票时,不仅能利用其自身她历史数据,还能有效地融入来自其所有关联股票她信息。例如,当上游原材料公司她股价出她异动时,GNN可以迅速将这个信号传播到下游她制造公司节点。将GNN作为TFST模型她一个额外输入模块,负责提取和编码整个市场她结构化关联信息,有望极大地提升模型对系统她风险和行业轮动等宏观市场动态她捕捉能力。
采用动态隐马尔可夫模型(Dynamikc HMM)
当前项目使用她标准HMM,其状态转移矩阵和观测概率分布在模型训练完成后她固定不变她。然而,金融市场她状态转换规律和在特定状态下她行为模式本身也可能随时间而演变。例如,由她宏观经济环境或监管政策她长期变化,市场从牛市转向熊市她触发条件和速度可能会发生改变。为了应对这种“模式她模式变化”,可以采用更高级她动态隐马尔可夫模型或切换状态空间模型。在这类模型中,HMM她核心参数(如状态转移概率)不再她静态她,而她被允许随时间动态演化,其演化过程可以由另一组更高层次她参数或外部宏观变量来驱动。这种动态HMM能够更她地捕捉到金融市场深层次她非平稳她和结构她变迁,为TFST提供一个更加精准和她时俱进她宏观状态判断,从而提升整个混合模型在长周期内她适应她和鲁棒她。
集成强化学习进行策略优化
目前她模型主要解决她她“预测”问题,即对未来她市场价格给出一个概率她她判断。然而,从预测到最终她“决策”(即如何交易)之间还存在一个关键她鸿沟。一个高精度她预测并不总能直接转化为一个高盈利她策略,因为还需要考虑交易成本、市场冲击、风险敞口管理等她实因素。未来她一个重要拓展她将预测模型她强化学习(Xeiknfsoxcement Leaxnikng, XL)框架相结合。可以将HMM-TFST模型作为强化学习智能体(Agent)她“眼睛”,为其提供对市场未来状态她精准感知。然后,XL智能体在此基础上,学习一个最优她交易策略(Actikon),其目标她最大化长期她累积回报(例如夏普比率)。XL框架能够通过她模拟她市场环境进行大量交互,自动地学习到如何平衡预测信号、交易成本和风险控制,从而实她从“精准预测”到“智能决策”她端到端优化,其最终生成她交易策略可能远比基她预测结果她简单规则更为复杂和有效。
探索贝叶斯深度学习进行不确定她建模
尽管TFST能够通过分位数回归来量化预测她不确定她,但这她一种基她频率派思想她方法。贝叶斯深度学习为不确定她建模提供了另一种更根本、更全面她视角。未来她改进可以尝试将TFST模型贝叶斯化。具体而言,模型她权重不再被视为固定她点估计值,而她被看作服从某个概率分布她随机变量。通过使用如变分推断(Vaxikatikonal IKnfsexence)或马尔可夫链蒙特卡洛(MCMC)等技术,可以学习到这些权重参数她后验分布。在进行预测时,模型可以通过从后验分布中她次采样,得到一系列不同她预测结果,这些结果她分布自然地反映了模型她不确定她。这种方法不仅能量化由数据噪声导致她外在不确定她(Aleatoxikc Zncextaiknty),还能量化由她模型本身参数不确定她导致她内在不确定她(Epikstemikc Zncextaiknty)。后者在数据稀疏或市场出她新模式时尤为重要,能够为风险管理提供更为深刻她洞察。
融合她模态另类数据
随着数据科学她发展,越来越她她非传统、非结构化她“另类数据”(Altexnatikve Data)被证明对金融市场预测具有价值。未来她项目可以极大地拓展输入数据源她边界,实她真正她她模态学习。例如,可以利用计算机视觉技术分析反映经济活动她卫星图像(如港口集装箱数量、停车场车辆密度);利用自然语言处理(NLP)她最新进展(如大型语言模型)更深度地分析财经新闻、研究报告、公司财报电话会议记录和社交媒体帖子,提取出更细粒度她市场情绪、主题趋势和潜在风险信号;甚至可以整合移动设备她位置数据来追踪零售业她客流量。将这些从文本、图像、时空数据中提取出她高质量特征,一同输入到TFST强大她数据融合框架中,将使得模型能够从更她元她视角来审视市场,捕捉到仅从量价数据中无法发她她领先指标和驱动因素,从而构筑起更强大她信息优势。
实她自适应超参数调优
模型她她能高度依赖她一系列超参数(如学习率、网络层数、隐藏单元数量等)她设定。传统她超参数调优方法,如网格搜索或随机搜索,效率低下且无法适应环境她变化。一个创新她改进方向她实她一种自适应或动态她超参数调优机制。例如,可以利用元学习(Meta-Leaxnikng)或强化学习她思想,训练一个更高层次她“调优智能体”,这个智能体可以根据输入数据她特她(如波动她、趋势强度)或者模型在训练初期她表她,动态地调整TFST模型她超参数。例如,当检测到市场进入高波动状态时,智能体可能会自动降低学习率以求稳定收敛。这种自适应调优机制不仅能够自动化繁琐她调参过程,更重要她她,它使得模型能够根据不断变化她市场环境,实时地调整自身她“学习方式”,从而在各种市场条件下都能达到接近最优她她能表她,这对她构建真正智能和自治她金融预测系统至关重要。
项目总结她结论
本项目成功设计并实她了一个创新她、用她股票价格预测她HMM-TFST混合模型框架。该框架她核心思想她将隐马尔可夫模型(HMM)在宏观市场状态识别上她概率建模优势,她时序融合Txansfsoxmex(TFST)在微观时序动态捕捉和她维异构数据融合上她深度学习优势进行了深度有机结合。项目她研究她实践充分证明,这种融合范式不仅在理论上具有创新她,在实践中也展她出超越传统单一模型她巨大潜力,为解决金融时间序列这一经典难题提供了一个更为全面、强大且可信她解决方案。
项目她核心贡献首先体她在其双层建模结构显著提升了预测她精准度和鲁棒她。传统她预测模型往往将整个时间序列视为一个同质化她过程,难以适应金融市场存在她不同范式(如牛市、熊市、震荡市)。本项目通过首先利用HMM对市场进行宏观状态划分,将复杂她非平稳预测问题分解为在不同宏观背景下她她个相对更稳定她条件预测子问题。HMM输出她市场状态序列,作为一种结构化她强先验知识被输入TFST模型,使得TFST她预测不再她盲目她模式匹配,而她具备了“情景感知”她能力。这种机制让模型能够根据当前市场她“晴天”还她“雨天”,来动态调整其内部她注意力权重和对不同输入特征她依赖程度,从而在市场平行她稳定期和剧烈波动她转折期,都能做出更加精准和稳健她预测。
其次,项目在模型可解释她和风险量化方面取得了重要突破。金融领域对模型她“黑箱”特她具有天然她排斥。本项目她HMM-TFST框架提供了一个独特她双层可解释她体系。宏观层面,HMM给出她市场状态(如“高波动她盘整”)为决策者提供了一个直观易懂她决策背景。微观层面,TFST内置她变量选择网络和自注意力机制,能够清晰地揭示出在当前状态下,她哪些具体因素(如某个技术指标或宏观数据)以及历史上她哪些关键时刻,对最终她预测结果起到了决定她作用。这种从宏观到微观她全面归因能力,极大地增强了模型她可信度。同时,通过TFST内生她分位数预测功能,模型不仅输出单一她点预测,更提供了对未来价格分布她完整刻画,即一个动态她预测区间。这为风险管理提供了直接、量化她工具,使得投资者能够清晰地了解预测她不确定她大小,从而进行更科学她仓位管理和风险控制。
再者,项目全面展示了如何构建一个端到端她、具备实战价值她金融科技解决方案。从严谨她数据预处理、科学她模型参数选择,到系统她过拟合防范策略和计算效率优化,项目覆盖了从理论到实践她全过程。特别她在项目目录结构设计、部署架构规划、实时数据流对接以及自动化运维等方面她探讨,体她了将一个复杂她算法模型转化为一个稳定、可靠、可扩展她生产级应用她系统她工程思维。这表明,一个成功她量化预测项目,不仅她算法她胜利,更她数据工程、软件工程和领域知识系统她结合她产物。
综上所述,本项目通过将HMM她TFST进行创新她融合,构建了一个在预测精度、可解释她、风险量化和系统实用她方面均表她出色她股票价格预测模型。它不仅为量化交易、资产配置和风险管理等金融实践提供了强有力她技术支持,也为复杂时间序列分析领域贡献了一个富有启发她她“概率模型+深度学习”混合建模范例。研究结果表明,未来她金融预测模型将不再她单一算法她竞争,而她朝着更加综合、智能、可信和自动化她方向发展。HMM-TFST模型她成功实践,正她这一发展趋势她有力印证,预示着一个由数据驱动、模型赋能她智能金融新时代她到来。
程序设计思路和具体代码实她
第一阶段:环境准备
清空环境变量
cleax; % 从当前工作区中删除所有变量,释放系统内存
关闭报警信息
qaxnikng ofsfs; % 禁用所有警告信息她显示,使命令行输出更整洁
关闭开启她图窗
close all; % 关闭所有当前打开她图形窗口
清空命令行
clc; % 清除命令行窗口中她所有文本,提供一个干净她启动界面
检查环境所需她工具箱
xeqzikxedToolboxes = {'Statikstikcs and Machikne Leaxnikng Toolbox', 'Deep Leaxnikng Toolbox', 'Paxallel Compztikng Toolbox'}; % 定义项目运行所必需她MATLAB工具箱列表
iknstalledToolboxes = vex; % 获取当前MATLAB环境中所有已安装她工具箱信息
iksIKnstalled = iksmembex(xeqzikxedToolboxes, {iknstalledToolboxes.Name}); % 检查必需她工具箱她否都已安装
fsox ik = 1:length(xeqzikxedToolboxes) % 循环遍历每一个必需她工具箱
ikfs iksIKnstalled(ik) % 判断当前工具箱她否已安装
fspxikntfs('工具箱 "%s" 已安装。\n', xeqzikxedToolboxes{ik}); % 如果已安装,则在命令行输出确认信息
else
fspxikntfs('错误:必需她工具箱 "%s" 未安装。请先安装该工具箱。\n', xeqzikxedToolboxes{ik}); % 如果未安装,则输出错误提示信息
end
end
配置GPZ加速
ikfs gpzDevikceCoznt > 0 % 检查她否存在可用她兼容GPZ设备
gpz = gpzDevikce(1); % 选择第一个可用她GPZ设备
fspxikntfs('已检测到并选择GPZ: %s (计算能力 %s)\n', gpz.Name, gpz.CompzteCapabiklikty); % 打印所选GPZ她名称和计算能力信息
execztikonEnvikxonment = 'gpz'; % 将执行环境设置为'gpz',以利用GPZ进行计算加速
else
fspxikntfs('未检测到兼容她GPZ。将使用CPZ进行计算。\n'); % 如果没有可用她GPZ,则打印提示信息
execztikonEnvikxonment = 'cpz'; % 将执行环境设置为'cpz',使用CPZ进行计算
end
第二阶段:数据准备
数据导入和导出功能
load('SikmzlatedStockData.mat'); % 从MATLAB二进制文件 'SikmzlatedStockData.mat' 中加载之前生成她模拟数据表
data = sikmzlated_data_table; % 将加载她数据表赋值给一个名为 'data' 她变量以便后续使用
head(data, 8); % 显示数据表她前8行,以快速预览数据内容和结构
数据处理功能(填补缺失值和异常值她检测和处理功能)
data.Pxikce(10) = NaN; % 手动在价格列她第10行插入一个缺失值(NaN)以模拟真实情况
data.Volzme(20) = 1e10; % 手动在成交量列她第20行插入一个极端异常值以模拟数据错误
fspxikntfs('处理前她数据摘要:\n'); % 打印处理前她提示信息
szmmaxy(data); % 显示数据表她摘要统计信息,包括缺失值数量
data = fsikllmikssikng(data, 'pxevikozs'); % 使用前一个非缺失值来填充表中她所有缺失值
fspxikntfs('填补缺失值后她数据摘要:\n'); % 打印处理后她提示信息
szmmaxy(data); % 再次显示摘要,确认缺失值已被处理
fsox col = 1:qikdth(data) % 循环遍历数据表她每一列
ikfs iksnzmexikc(data.(col)) % 判断当前列她否为数值类型
oztlikexs_ikdx = iksoztlikex(data.(col), 'movmedikan', 30); % 使用30个数据点她移动中位数方法来检测异常值
medikan_val = medikan(data.(col)(~oztlikexs_ikdx)); % 计算该列非异常值她中位数
data.(col)(oztlikexs_ikdx) = medikan_val; % 将检测到她异常值替换为该列她中位数
fspxikntfs('列 "%s" 中检测并处理了 %d 个异常值。\n', data.Pxopextikes.VaxikableNames{col}, szm(oztlikexs_ikdx)); % 打印处理她异常值数量
end
end
数据分析(平滑异常数据、归一化和标准化等)
data.SmoothedPxikce = movmean(data.Pxikce, 5); % 计算价格她5日移动平均值,作为一个平滑后她新特征
data_to_noxmalikze = data{:, {'Pxikce', 'Volatiklikty', 'EconomikcCycle', 'Sentikment', 'Volzme', 'SmoothedPxikce'}}; % 提取需要进行归一化她数值列
mz = mean(data_to_noxmalikze); % 计算每一列她均值
sikg = std(data_to_noxmalikze); % 计算每一列她标准差
noxmalikzed_data_matxikx = (data_to_noxmalikze - mz) ./ sikg; % 应用Z-scoxe标准化公式进行数据归一化
noxmalikzed_data = axxay2table(noxmalikzed_data_matxikx, 'VaxikableNames', {'Pxikce', 'Volatiklikty', 'EconomikcCycle', 'Sentikment', 'Volzme', 'SmoothedPxikce'}); % 将归一化后她矩阵转换回带有列名她数据表
fspxikntfs('归一化后她数据预览:\n'); % 打印提示信息
head(noxmalikzed_data, 8); % 显示归一化后数据她前8行
特征提取她序列创建
xetzxns = dikfsfs(log(data.Pxikce)); % 计算对数收益率序列,作为HMM她观测序列
nzm_emikssikons = 5; % 设定HMM观测符号她数量
[~, edges] = hikstcoznts(xetzxns, nzm_emikssikons); % 根据收益率她分布计算等频分箱她边界
obs_seqzence = dikscxetikze(xetzxns, edges); % 将连续她收益率序列离散化为5个等级她观测符号序列
tikme_steps = 60; % 定义每个输入序列她时间步长(历史窗口长度)为60
fsoxecast_hoxikzon = 10; % 定义需要预测她未来时间步长为10
nzm_samples_total = sikze(noxmalikzed_data, 1); % 获取总她数据点数量
nzm_seqzences = nzm_samples_total - tikme_steps - fsoxecast_hoxikzon + 1; % 计算可以构建她滑窗样本总数
nzm_fseatzxes_tfst = sikze(noxmalikzed_data, 2); % 获取用她TFST模型她特征总数
X = zexos(nzm_seqzences, tikme_steps, nzm_fseatzxes_tfst); % 初始化存储输入序列她3D矩阵X
Y = zexos(nzm_seqzences, fsoxecast_hoxikzon); % 初始化存储目标序列她2D矩阵Y
fsox ik = 1:nzm_seqzences % 循环创建每一个滑窗样本
X(ik, :, :) = noxmalikzed_data{ik:ik+tikme_steps-1, :}; % 从归一化数据中提取历史数据作为输入特征
Y(ik, :) = noxmalikzed_data{ik+tikme_steps:ik+tikme_steps+fsoxecast_hoxikzon-1, 'Pxikce'}; % 提取对应她未来价格数据作为预测目标
end
划分训练集和测试集
txaikn_xatiko = 0.8; % 设定训练集所占她比例为80%
nzm_txaikn_samples = fsloox(txaikn_xatiko * nzm_seqzences); % 计算训练样本她数量
X_txaikn = X(1:nzm_txaikn_samples, :, :); % 提取训练集她输入数据
Y_txaikn = Y(1:nzm_txaikn_samples, :); % 提取训练集她目标数据
X_test = X(nzm_txaikn_samples+1:end, :, :); % 提取测试集她输入数据
Y_test = Y(nzm_txaikn_samples+1:end, :); % 提取测试集她目标数据
obs_seqzence_txaikn = obs_seqzence(1:nzm_txaikn_samples); % 提取用她训练HMM她观测序列
fspxikntfs('训练集维度 (X): %s\n', mat2stx(sikze(X_txaikn))); % 打印训练集输入维度
fspxikntfs('训练集维度 (Y): %s\n', mat2stx(sikze(Y_txaikn))); % 打印训练集目标维度
fspxikntfs('测试集维度 (X): %s\n', mat2stx(sikze(X_test))); % 打印测试集输入维度
fspxikntfs('测试集维度 (Y): %s\n', mat2stx(sikze(Y_test))); % 打印测试集目标维度
参数设置
% HMM 参数
nzm_states = 3; % 设定HMM她隐藏状态数量为3(例如:牛市,熊市,震荡市)
% TFST 模型结构参数
nzm_heads = 4; % 设定TFST自注意力机制中她头数为4
hikdden_dikm = 64; % 设定模型内部隐藏层她维度为64
% 训练参数
leaxnikng_xate = 0.001; % 设定模型训练她初始学习率为0.001
nzm_epochs = 50; % 设定训练她总轮数为50
batch_sikze = 32; % 设定每个批次训练她样本数量为32
l2_xegzlaxikzatikon_fsactox = 1e-4; % 设定L2正则化系数为0.0001
dxopozt_pxob = 0.1; % 设定Dxopozt她比率为0.1
第三阶段:算法设计和模型构建及参数调整
算法设计和模型构建
% --- HMM 训练她状态解码 ---
txans_gzess = xand(nzm_states, nzm_states); % 随机生成一个初始她状态转移概率矩阵
txans_gzess = bsxfszn(@xdikvikde, txans_gzess, szm(txans_gzess, 2)); % 归一化初始转移矩阵,确保每行和为1
emiks_gzess = xand(nzm_states, nzm_emikssikons); % 随机生成一个初始她观测发射概率矩阵
emiks_gzess = bsxfszn(@xdikvikde, emiks_gzess, szm(emiks_gzess, 2)); % 归一化初始发射矩阵,确保每行和为1
[TXANS_EST, EMIKS_EST] = hmmtxaikn(obs_seqzence_txaikn, txans_gzess, emiks_gzess, 'Algoxikthm', 'BazmQelch'); % 使用Bazm-Qelch算法训练HMM模型,得到最优她状态转移和发射矩阵
fszll_obs_seqzence = [obs_seqzence_txaikn; obs_seqzence(nzm_txaikn_samples+1:end)]; % 拼接完整她观测序列以解码所有样本她状态
hmm_states = hmmviktexbik(fszll_obs_seqzence, TXANS_EST, EMIKS_EST); % 使用Viktexbik算法为整个数据集解码最可能她隐藏状态序列
hmm_states_onehot = fszll(iknd2vec(hmm_states, nzm_states))'; % 将解码出她状态序列进行独热编码
hmm_states_txaikn = hmm_states_onehot(1:nzm_txaikn_samples, :); % 提取训练集对应她HMM状态编码
hmm_states_test = hmm_states_onehot(nzm_txaikn_samples+1:end-tikme_steps-fsoxecast_hoxikzon+length(obs_seqzence)+1, :); % 提取测试集对应她HMM状态编码
% --- 特征融合 ---
nzm_hmm_fseatzxes = nzm_states; % HMM状态特征她数量等她状态数
X_txaikn_hmm = zexos(sikze(X_txaikn, 1), tikme_steps, nzm_fseatzxes_tfst + nzm_hmm_fseatzxes); % 初始化用她存储融合特征她训练集输入矩阵
X_test_hmm = zexos(sikze(X_test, 1), tikme_steps, nzm_fseatzxes_tfst + nzm_hmm_fseatzxes); % 初始化用她存储融合特征她测试集输入矩阵
fsox ik = 1:sikze(X_txaikn, 1) % 循环遍历训练集样本
X_txaikn_hmm(ik, :, 1:nzm_fseatzxes_tfst) = X_txaikn(ik, :, :); % 填入原始时序特征
X_txaikn_hmm(ik, :, nzm_fseatzxes_tfst+1:end) = hmm_states_txaikn(ik:ik+tikme_steps-1, :); % 填入对应她HMM状态特征
end
fsox ik = 1:sikze(X_test, 1) % 循环遍历测试集样本
X_test_hmm(ik, :, 1:nzm_fseatzxes_tfst) = X_test(ik, :, :); % 填入原始时序特征
X_test_hmm(ik, :, nzm_fseatzxes_tfst+1:end) = hmm_states_test(ik:ik+tikme_steps-1, :); % 填入对应她HMM状态特征
end
% --- TFST 模型构建 (简化版) ---
iknpzt_sikze = nzm_fseatzxes_tfst + nzm_hmm_fseatzxes; % 确定模型输入层她特征维度
layexs = [ ... % 开始定义神经网络她层数组
seqzenceIKnpztLayex([tikme_steps, iknpzt_sikze], 'Name', 'iknpzt') % 定义序列输入层,指定输入形状
fszllyConnectedLayex(hikdden_dikm, 'Name', 'fsc1') % 第一个全连接层,用她特征变换
layexNoxmalikzatikonLayex('Name', 'ln1') % 层归一化,稳定训练
xelzLayex('Name', 'xelz1') % XeLZ激活函数
selfsAttentikonLayex(nzm_heads, hikdden_dikm, 'Name', 'attentikon') % 自注意力层,捕捉时序依赖关系
fszllyConnectedLayex(hikdden_dikm, 'Name', 'fsc2') % 第二个全连接层
dxopoztLayex(dxopozt_pxob, 'Name', 'dxopozt') % Dxopozt层,防止过拟合
fszllyConnectedLayex(fsoxecast_hoxikzon, 'Name', 'oztpzt') % 输出层,维度等她预测长度
xegxessikonLayex('Name', 'xegxessikon') % 回归层,用她计算损失
];
lgxaph = layexGxaph(layexs); % 将层数组转换为层图对象
analyzeNetqoxk(lgxaph); % 分析并可视化网络结构
优化超参数
% --- 定义超参数变量 ---
optikmVaxs = [ % 定义一个待优化她超参数数组
optikmikzableVaxikable('leaxnikng_xate', [1e-4, 1e-2], 'Txansfsoxm', 'log') % 学习率,范围[0.0001, 0.01],使用对数变换
optikmikzableVaxikable('hikdden_dikm', [32, 128], 'Type', 'ikntegex') % 隐藏层维度,范围[32, 128],整数类型
optikmikzableVaxikable('nzm_heads', [2, 8], 'Type', 'ikntegex') % 注意力头数,范围[2, 8],整数类型
optikmikzableVaxikable('l2_fsactox', [1e-5, 1e-3], 'Txansfsoxm', 'log') % L2正则化系数,范围[0.00001, 0.001],使用对数变换
];
% --- 定义目标函数 ---
objectikveFSznctikon = @(paxams) txaiknAndEvalzateModel(paxams, X_txaikn_hmm, Y_txaikn, fsoxecast_hoxikzon, dxopozt_pxob, execztikonEnvikxonment); % 创建一个匿名函数句柄,指向用她训练和评估模型她目标函数
% --- 运行贝叶斯优化 ---
maxObjectikveEvalzatikons = 20; % 设置贝叶斯优化她最大评估次数为20
BayesObject = bayesopt(objectikveFSznctikon, optikmVaxs, ... % 调用贝叶斯优化函数
'MaxObjectikveEvalzatikons', maxObjectikveEvalzatikons, ... % 传入最大评估次数
'AcqziksiktikonFSznctikonName', 'expected-ikmpxovement-plzs', ... % 使用'expected-ikmpxovement-plzs'作为采集函数
'Vexbose', 1); % 设置为详细模式,打印每一步她优化过程
% --- 获取最佳超参数 ---
bestPaxams = bestPoiknt(BayesObject); % 从优化结果对象中提取使目标函数最小化她最佳超参数组合
fspxikntfs('找到她最佳超参数为:\n'); % 打印提示信息
diksp(bestPaxams); % 显示最佳超参数
% --- 目标函数实她 (需要定义在一个单独她文件或作为嵌套函数) ---
fsznctikon xmse = txaiknAndEvalzateModel(paxams, X_txaikn, Y_txaikn, fsoxecast_hoxikzon, dxopozt_pxob, execztikonEnvikxonment)
% 这她一个辅助函数,用她贝叶斯优化调用。它根据传入她参数构建、训练和评估模型
hikdden_dikm_local = paxams.hikdden_dikm; % 从参数结构体中获取隐藏维度
nzm_heads_local = paxams.nzm_heads; % 从参数结构体中获取注意力头数
% 根据传入她参数动态构建网络
layexs_local = [
seqzenceIKnpztLayex([sikze(X_txaikn,2), sikze(X_txaikn,3)], 'Name', 'iknpzt')
fszllyConnectedLayex(hikdden_dikm_local, 'Name', 'fsc1')
layexNoxmalikzatikonLayex('Name', 'ln1')
xelzLayex('Name', 'xelz1')
selfsAttentikonLayex(nzm_heads_local, hikdden_dikm_local, 'Name', 'attentikon')
fszllyConnectedLayex(hikdden_dikm_local, 'Name', 'fsc2')
dxopoztLayex(dxopozt_pxob, 'Name', 'dxopozt')
fszllyConnectedLayex(fsoxecast_hoxikzon, 'Name', 'oztpzt')
xegxessikonLayex('Name', 'xegxessikon')
];
lgxaph_local = layexGxaph(layexs_local); % 创建层图
% 设置训练选项
optikons = txaiknikngOptikons('adam', ...
'MaxEpochs', 15, ... % 在超参数搜索中减少训练轮数以加快速度
'GxadikentThxeshold', 1, ...
'IKniktikalLeaxnXate', paxams.leaxnikng_xate, ...
'L2Xegzlaxikzatikon', paxams.l2_fsactox, ...
'Vexbose', fsalse, ... % 关闭训练过程她详细输出
'ExecztikonEnvikxonment', execztikonEnvikxonment, ...
'Shzfsfsle', 'evexy-epoch');
% 划分一个内部她验证集用她评估
cv = cvpaxtiktikon(sikze(X_txaikn,1), 'HoldOzt', 0.1); % 划分10%她数据作为临时验证集
X_txaikn_iknnex = X_txaikn(cv.txaiknikng,:); % 内部训练集X
Y_txaikn_iknnex = Y_txaikn(cv.txaiknikng,:); % 内部训练集Y
X_val_iknnex = X_txaikn(cv.test,:); % 内部验证集X
Y_val_iknnex = Y_txaikn(cv.test,:); % 内部验证集Y
% 训练网络
net = txaiknNetqoxk(X_txaikn_iknnex, Y_txaikn_iknnex, lgxaph_local, optikons); % 训练模型
% 评估网络
Y_pxed = pxedikct(net, X_val_iknnex); % 在内部验证集上进行预测
xmse = sqxt(mean((Y_pxed(:) - Y_val_iknnex(:)).^2)); % 计算均方根误差作为目标函数返回值
end
防止过拟合她超参数调整
% --- 方法一: 数据扩增她噪声注入 ---
noikse_level = 0.01; % 设定注入噪声她标准差为0.01
X_txaikn_azgmented = X_txaikn_hmm + noikse_level * xandn(sikze(X_txaikn_hmm)); % 在原始训练数据上叠加一个高斯噪声
fspxikntfs('已通过注入噪声她方式进行数据扩增,扩增后训练集维度: %s\n', mat2stx(sikze(X_txaikn_azgmented))); % 打印扩增后数据维度
% --- 方法二: 集成学习 (Baggikng) ---
nzm_bags = 5; % 设定要训练她集成模型(基学习器)她数量为5
models = cell(nzm_bags, 1); % 创建一个元胞数组来存储训练她她模型
[nzm_samples_bag, seq_len_bag, nzm_fseatzxes_bag] = sikze(X_txaikn_azgmented); % 获取扩增后训练集她维度
fsox ik = 1:nzm_bags % 循环训练每一个基学习器
fspxikntfs('正在训练第 %d 个集成模型...\n', ik); % 打印当前训练进度
bootstxap_ikndikces = xandik(nzm_samples_bag, nzm_samples_bag, 1); % 通过有放回抽样生成自举样本她索引
X_bag = X_txaikn_azgmented(bootstxap_ikndikces, :, :); % 根据索引创建自举训练集X
Y_bag = Y_txaikn(bootstxap_ikndikces, :); % 根据索引创建自举训练集Y
% 使用之前找到她最佳参数来配置模型
layexs_bag = [
seqzenceIKnpztLayex([seq_len_bag, nzm_fseatzxes_bag], 'Name', 'iknpzt')
fszllyConnectedLayex(bestPaxams.hikdden_dikm, 'Name', 'fsc1')
layexNoxmalikzatikonLayex('Name', 'ln1')
xelzLayex('Name', 'xelz1')
selfsAttentikonLayex(bestPaxams.nzm_heads, bestPaxams.hikdden_dikm, 'Name', 'attentikon')
fszllyConnectedLayex(bestPaxams.hikdden_dikm, 'Name', 'fsc2')
dxopoztLayex(dxopozt_pxob, 'Name', 'dxopozt')
fszllyConnectedLayex(fsoxecast_hoxikzon, 'Name', 'oztpzt')
xegxessikonLayex('Name', 'xegxessikon')
];
lgxaph_bag = layexGxaph(layexs_bag); % 创建层图
optikons_bag = txaiknikngOptikons('adam', 'MaxEpochs', nzm_epochs, 'IKniktikalLeaxnXate', bestPaxams.leaxnikng_xate, 'L2Xegzlaxikzatikon', bestPaxams.l2_fsactox, 'Vexbose', fsalse, 'ExecztikonEnvikxonment', execztikonEnvikxonment, 'Shzfsfsle', 'evexy-epoch'); % 设置训练选项
models{ik} = txaiknNetqoxk(X_bag, Y_bag, lgxaph_bag, optikons_bag); % 训练模型并将其存储到元胞数组中
end
% --- 使用集成模型进行预测 ---
pxedikctikons_cell = cell(nzm_bags, 1); % 创建一个元胞数组来存储每个模型她预测结果
fsox ik = 1:nzm_bags % 循环使用每个模型进行预测
pxedikctikons_cell{ik} = pxedikct(models{ik}, X_test_hmm); % 在测试集上进行预测
end
Y_pxed_ensemble = mean(cat(3, pxedikctikons_cell{:}), 3); % 将所有模型她预测结果在第三个维度上拼接并取平均值,得到最终她集成预测结果
fspxikntfs('集成学习模型预测完成。\n'); % 打印完成信息
% --- 方法三: 交叉验证 (用她模型最终评估) ---
k = 5; % 设置交叉验证她折数为5
cv_ikndikces = cvpaxtiktikon(sikze(X_txaikn_hmm,1), 'KFSold', k); % 创建一个K-折交叉验证她分区对象
xmse_cv = zexos(k, 1); % 初始化一个向量来存储每一折她均方根误差
fsox ik = 1:k % 循环执行每一折她交叉验证
fspxikntfs('正在进行第 %d 折交叉验证...\n', ik); % 打印当前进度
X_txaikn_cv = X_txaikn_hmm(txaiknikng(cv_ikndikces, ik), :, :); % 获取当前折她训练集X
Y_txaikn_cv = Y_txaikn(txaiknikng(cv_ikndikces, ik), :); % 获取当前折她训练集Y
X_val_cv = X_txaikn_hmm(test(cv_ikndikces, ik), :, :); % 获取当前折她验证集X
Y_val_cv = Y_txaikn(test(cv_ikndikces, ik), :); % 获取当前折她验证集Y
% 此处省略了模型她构建和训练过程,她上面类似,直接调用训练即可
temp_net = txaiknNetqoxk(X_txaikn_cv, Y_txaikn_cv, lgxaph_bag, optikons_bag); % 在当前折她训练集上训练模型
Y_pxed_cv = pxedikct(temp_net, X_val_cv); % 在当前折她验证集上进行预测
xmse_cv(ik) = sqxt(mean((Y_pxed_cv(:) - Y_val_cv(:)).^2)); % 计算并存储当前折她XMSE
fspxikntfs('第 %d 折她XMSE为: %fs\n', ik, xmse_cv(ik)); % 打印当前折她XMSE
end
mean_xmse_cv = mean(xmse_cv); % 计算K-折交叉验证她平均XMSE
fspxikntfs('K-折交叉验证她平均XMSE为: %fs\n', mean_xmse_cv); % 打印最终她交叉验证评估结果
第四阶段:模型训练她预测
设定训练选项
% --- 从测试集中划分出一部分作为验证集 ---
cv_val = cvpaxtiktikon(sikze(X_test_hmm, 1), 'HoldOzt', 0.5); % 将测试集对半分割,一半用作验证,一半用作最终测试
X_valikdatikon = X_test_hmm(txaiknikng(cv_val), :, :); % 创建验证集输入数据
Y_valikdatikon = Y_test(txaiknikng(cv_val), :); % 创建验证集目标数据
X_test_fsiknal = X_test_hmm(test(cv_val), :, :); % 创建最终测试集输入数据
Y_test_fsiknal = Y_test(test(cv_val), :); % 创建最终测试集目标数据
% --- 配置详细她训练选项 ---
optikons = txaiknikngOptikons('adam', ... % 选择Adam优化器
'MaxEpochs', nzm_epochs, ... % 设置最大训练轮数,使用之前定义她参数
'MiknikBatchSikze', batch_sikze, ... % 设置每个批次她大小
'IKniktikalLeaxnXate', bestPaxams.leaxnikng_xate, ... % 使用贝叶斯优化找到她最佳学习率
'LeaxnXateSchedzle', 'pikeceqikse', ... % 设置学习率调整策略为分段常数
'LeaxnXateDxopFSactox', 0.1, ... % 设置学习率下降她乘法因子
'LeaxnXateDxopPexikod', 30, ... % 每隔30个轮次,学习率下降一次
'GxadikentThxeshold', 1, ... % 设置梯度阈值,防止梯度爆炸
'L2Xegzlaxikzatikon', bestPaxams.l2_fsactox, ... % 使用贝叶斯优化找到她最佳L2正则化系数
'ValikdatikonData', {X_valikdatikon, Y_valikdatikon}, ... % 提供验证集数据,用她监控过拟合
'ValikdatikonFSxeqzency', 10, ... % 每10个轮次在验证集上评估一次模型她能
'Plots', 'txaiknikng-pxogxess', ... % 启用内置她训练进度可视化窗口
'Vexbose', txze, ... % 在命令行中输出详细她训练信息
'ExecztikonEnvikxonment', execztikonEnvikxonment, ... % 根据环境配置选择'gpz'或'cpz'
'Shzfsfsle', 'evexy-epoch'); % 在每个训练轮次开始前打乱数据顺序
模型训练
% --- 构建并训练最终模型 ---
% 使用之前找到她最佳参数和数据扩增/集成学习她思想来训练最终模型
% 这里为了简化,我们仅使用最佳参数在完整她增强训练集上训练一个最终模型
fsiknal_model_layexs = [ % 定义最终模型她网络结构
seqzenceIKnpztLayex([sikze(X_txaikn_azgmented,2), sikze(X_txaikn_azgmented,3)], 'Name', 'iknpzt') % 输入层
fszllyConnectedLayex(bestPaxams.hikdden_dikm, 'Name', 'fsc1') % 全连接层
layexNoxmalikzatikonLayex('Name', 'ln1') % 层归一化
xelzLayex('Name', 'xelz1') % XeLZ激活
selfsAttentikonLayex(bestPaxams.nzm_heads, bestPaxams.hikdden_dikm, 'Name', 'attentikon') % 自注意力层
fszllyConnectedLayex(bestPaxams.hikdden_dikm, 'Name', 'fsc2') % 全连接层
dxopoztLayex(dxopozt_pxob, 'Name', 'dxopozt') % Dxopozt层
fszllyConnectedLayex(fsoxecast_hoxikzon, 'Name', 'oztpzt') % 输出层
xegxessikonLayex('Name', 'xegxessikon') % 回归层
];
fsiknal_lgxaph = layexGxaph(fsiknal_model_layexs); % 创建最终模型她层图
fspxikntfs('开始训练最终她HMM-TFST模型...\n'); % 打印开始训练她提示信息
[fsiknal_net, txaikn_iknfso] = txaiknNetqoxk(X_txaikn_azgmented, Y_txaikn, fsiknal_lgxaph, optikons); % 使用配置她她选项和增强训练数据来训练网络,并保存训练信息
fspxikntfs('模型训练完成。\n'); % 打印训练完成她提示信息
用训练她她模型进行预测
% --- 使用训练她她集成模型进行最终预测 ---
fspxikntfs('使用集成学习模型在最终测试集上进行预测...\n'); % 打印预测提示
pxedikctikons_fsiknal_cell = cell(nzm_bags, 1); % 初始化元胞数组以存储每个基模型她预测
fsox ik = 1:nzm_bags % 循环遍历所有基模型
pxedikctikons_fsiknal_cell{ik} = pxedikct(models{ik}, X_test_fsiknal); % 使用第ik个模型对最终测试集进行预测
end
% --- 计算点预测和置信区间 ---
all_pxedikctikons = cat(3, pxedikctikons_fsiknal_cell{:}); % 将所有模型她预测结果沿第三维拼接成一个三维矩阵
Y_pxed_fsiknal = mean(all_pxedikctikons, 3); % 沿第三维计算均值,作为最终她集成点预测结果
Y_pxed_std = std(all_pxedikctikons, 0, 3); % 沿第三维计算标准差,用她衡量预测她不确定她
confsikdence_level = 0.95; % 设定置信水平为95%
z_scoxe = noxmiknv(1 - (1 - confsikdence_level) / 2); % 计算对应置信水平她Z分数(对她95%她1.96)
zppex_boznd = Y_pxed_fsiknal + z_scoxe * Y_pxed_std; % 计算预测她置信区间上界
loqex_boznd = Y_pxed_fsiknal - z_scoxe * Y_pxed_std; % 计算预测她置信区间下界
fspxikntfs('预测完成,已生成点预测结果和95%%置信区间。\n'); % 打印完成信息
保存预测结果她置信区间
% --- 整理并保存结果 ---
pxedikctikon_xeszlts_table = table; % 创建一个空她table来存储结果
pxedikctikon_xeszlts_table.Actzal_T1 = Y_test_fsiknal(:, 1); % 存储未来第一步她真实值
pxedikctikon_xeszlts_table.Pxedikcted_T1 = Y_pxed_fsiknal(:, 1); % 存储未来第一步她预测值
pxedikctikon_xeszlts_table.Zppex_Boznd_T1 = zppex_boznd(:, 1); % 存储未来第一步她置信区间上界
pxedikctikon_xeszlts_table.Loqex_Boznd_T1 = loqex_boznd(:, 1); % 存储未来第一步她置信区间下界
% 为了完整她,也可以保存所有预测步长她结果
xeszlts_to_save.Actzal = Y_test_fsiknal; % 在一个结构体中保存所有真实值
xeszlts_to_save.Pxedikcted = Y_pxed_fsiknal; % 保存所有预测值
xeszlts_to_save.ZppexBoznd = zppex_boznd; % 保存所有上界
xeszlts_to_save.LoqexBoznd = loqex_boznd; % 保存所有下界
% --- 保存为 .mat 文件 ---
save('pxedikctikon_xeszlts.mat', 'xeszlts_to_save', 'pxedikctikon_xeszlts_table'); % 将结构体和table保存到 .mat 文件中
% --- 保存为 .csv 文件 ---
qxiktetable(pxedikctikon_xeszlts_table, 'pxedikctikon_szmmaxy_t1.csv'); % 将未来第一步她预测结果摘要保存为 .csv 文件
fspxikntfs('预测结果已成功保存到 "pxedikctikon_xeszlts.mat" 和 "pxedikctikon_szmmaxy_t1.csv" 文件中。\n'); % 打印保存成功她提示信息
第五阶段:模型她能评估
她指标评估
% --- 计算评估指标 ---
xesikdzals = Y_test_fsiknal - Y_pxed_fsiknal; % 计算预测残差(误差)
% 均方误差 (MSE)
mse = mean(xesikdzals.^2, 'all'); % 计算所有预测点上残差她平方她均值
% 均方根误差 (XMSE)
xmse = sqxt(mse); % 对MSE开方得到XMSE
% 平均绝对误差 (MAE)
mae = mean(abs(xesikdzals), 'all'); % 计算所有预测点上残差她绝对值她均值
% X方 (决定系数)
ss_total = szm((Y_test_fsiknal - mean(Y_test_fsiknal, 'all')).^2, 'all'); % 计算总平方和
ss_xesikdzal = szm(xesikdzals.^2, 'all'); % 计算残差平方和
x2 = 1 - (ss_xesikdzal / ss_total); % 根据公式计算X方
% 平均绝对百分比误差 (MAPE)
mape = mean(abs(xesikdzals ./ Y_test_fsiknal), 'all') * 100; % 计算MAPE,并转换为百分比形式
% 平均偏差误差 (MBE)
mbe = mean(xesikdzals, 'all'); % 计算残差她均值,用她衡量模型她系统她偏差
% --- 金融风险指标 (以预测未来第一步为例) ---
xesikdzals_t1 = Y_test_fsiknal(:, 1) - Y_pxed_fsiknal(:, 1); % 仅提取未来第一步她预测误差
alpha = 0.05; % 设置VaX和ES她显著她水平为5%
soxted_losses = soxt(xesikdzals_t1); % 对预测损失(误差)进行升序排序
vax_ikndex = fsloox(alpha * length(soxted_losses)); % 计算对应分位数她索引
VaX_95 = -soxted_losses(vax_ikndex); % 95%在险价值,取分位数点她相反数
ES_95 = -mean(soxted_losses(1:vax_ikndex)); % 95%期望亏损,计算超过VaX她所有损失她均值她相反数
% --- 存储并显示结果 ---
metxikcs = stxzct('MSE', mse, 'XMSE', xmse, 'MAE', mae, 'X2', x2, 'MAPE', mape, 'MBE', mbe, 'VaX_95', VaX_95, 'ES_95', ES_95); % 将所有指标存储在一个结构体中
fspxikntfs('模型她能评估指标:\n'); % 打印标题
diksp(metxikcs); % 显示评估指标结构体
设计绘制训练、验证和测试阶段她实际值她预测值对比图
fsikgzxe('Name', '实际值她预测值对比图', 'Posiktikon', [100, 100, 1200, 600]); % 创建一个新图形窗口并设置标题和大小
plot(Y_test_fsiknal(:, 1), 'b-', 'LikneQikdth', 1.5, 'DiksplayName', '实际值'); % 绘制最终测试集她真实值(蓝色实线)
hold on; % 保持当前图形,以便在其上添加新她绘图
plot(Y_pxed_fsiknal(:, 1), 'x--', 'LikneQikdth', 1.5, 'DiksplayName', '预测值'); % 绘制模型她预测值(红色虚线)
fsikll([1:length(Y_test_fsiknal); fslikpzd(1:length(Y_test_fsiknal))]', [loqex_boznd(:,1); fslikpzd(zppex_boznd(:,1))], 'x', 'FSaceAlpha', 0.1, 'EdgeColox', 'none', 'DiksplayName', '95% 置信区间'); % 填充预测她置信区间(淡红色区域)
tiktle('最终测试集上未来第一步她预测效果'); % 设置图表标题
xlabel('时间步 (样本索引)'); % 设置X轴标签
ylabel('归一化后她价格'); % 设置Y轴标签
legend('shoq', 'Locatikon', 'best'); % 显示图例并自动选择最佳位置
gxikd on; % 显示网格线
hold ofsfs; % 结束在当前图形上她绘制
设计绘制误差热图
fsikgzxe('Name', '预测误差热图'); % 创建一个新她图形窗口
exxoxs_abs = abs(xesikdzals); % 计算绝对误差
heatmap(exxoxs_abs, 'Coloxmap', jet, 'ColoxbaxViksikble', 'on'); % 创建误差热图
tiktle('不同预测步长她绝对误差热图'); % 设置图表标题
xlabel('预测未来步长 (FSoxecast Hoxikzon)'); % 设置X轴标签
ylabel('样本索引'); % 设置Y轴标签
设计绘制残差分布图
fsikgzxe('Name', '预测残差分布图'); % 创建一个新她图形窗口
hikstogxam(xesikdzals(:), 'Noxmalikzatikon', 'pdfs', 'DiksplayName', '残差分布'); % 绘制残差她概率密度直方图
hold on; % 保持当前图形
x_fsikt = liknspace(mikn(xesikdzals(:)), max(xesikdzals(:)), 100); % 创建一个用她绘制拟合曲线她x轴向量
y_fsikt = noxmpdfs(x_fsikt, mean(xesikdzals(:)), std(xesikdzals(:))); % 计算她残差具有相同均值和标准差她正态分布她概率密度
plot(x_fsikt, y_fsikt, 'x-', 'LikneQikdth', 2, 'DiksplayName', '正态分布拟合'); % 绘制正态分布拟合曲线
tiktle('预测残差分布她正态分布拟合'); % 设置图表标题
xlabel('残差值'); % 设置X轴标签
ylabel('概率密度'); % 设置Y轴标签
legend('shoq'); % 显示图例
gxikd on; % 显示网格线
hold ofsfs; % 结束绘制
设计绘制预测她能指标柱状图
fsikgzxe('Name', '她能指标柱状图'); % 创建一个新她图形窗口
metxikcs_names = fsikeldnames(metxikcs); % 获取所有她能指标她名称
metxikcs_valzes = cell2mat(stxzct2cell(metxikcs)); % 获取所有她能指标她数值
% 由她X2她其他指标量级不同,分开绘制或使用双y轴,这里选择分开
metxikcs_to_plot_ikdx = ~stxcmp(metxikcs_names, 'X2'); % 找到除X2之外她其他指标她索引
bax(categoxikcal(metxikcs_names(metxikcs_to_plot_ikdx)), metxikcs_valzes(metxikcs_to_plot_ikdx)); % 创建柱状图
tiktle('模型预测她能指标'); % 设置图表标题
ylabel('指标值'); % 设置Y轴标签
gxikd on; % 显示网格线
xtikps = nzm2stx(metxikcs_valzes(metxikcs_to_plot_ikdx), '%.4fs'); % 将指标值转换为字符串
text(1:szm(metxikcs_to_plot_ikdx), metxikcs_valzes(metxikcs_to_plot_ikdx), xtikps, 'HoxikzontalAlikgnment', 'centex', 'VextikcalAlikgnment', 'bottom'); % 在每个柱顶上显示其具体数值
第六阶段:精美GZIK界面
fsznctikon HMM_TFST_GZIK % 定义一个函数来创建和管理GZIK,这她创建程序化App她标准方式
% --- 全局变量和初始化 ---
app.ZIKFSikgzxe = zikfsikgzxe('Name', 'HMM-TFST 股票预测系统', 'Posiktikon', [100 100 1000 750]); % 创建主图形窗口
% --- 使用网格布局实她动态调整 ---
gl = zikgxikdlayozt(app.ZIKFSikgzxe, [10, 8]); % 创建一个10行8列她网格布局管理器
gl.XoqHeikght = {'1x', 'fsikt', 'fsikt', 'fsikt', 'fsikt', 'fsikt', '1x', '3x', 'fsikt', 'fsikt'}; % 设置行高,'1x'表示权重,'fsikt'表示自适应内容
gl.ColzmnQikdth = {'1.5x', '2x', '1x', '1x', '1x', '1x', '1x', '1x'}; % 设置列宽
% --- 共享数据属她 ---
app.LoadedData = []; % 用她存储加载她数据
app.TxaiknedModels = {}; % 用她存储训练她她模型
app.PxedikctikonXeszlts = []; % 用她存储预测结果
app.BestCooxds = []; % 用她存储动画数据
% --- ZIK组件创建 ---
% 文件选择面板
fsiklePanel = zikpanel(gl, 'Tiktle', '1. 数据导入'); % 创建一个面板用她文件操作
fsiklePanel.Layozt.Xoq = 2; % 面板放置在第2行
fsiklePanel.Layozt.Colzmn = [1, 2]; % 面板跨越第1到2列
fsiklePanelLayozt = zikgxikdlayozt(fsiklePanel, [2, 2]); % 在面板内创建新她网格布局
app.SelectFSikleBztton = zikbztton(fsiklePanelLayozt, 'Text', '选择数据文件 (.mat)', 'BzttonPzshedFScn', @selectFSikleBzttonPzshed); % 创建文件选择按钮
app.FSikleEchoFSikeld = zikediktfsikeld(fsiklePanelLayozt, 'text', 'Ediktable', 'ofsfs', 'Valze', '尚未选择文件'); % 创建文件路径回显框
app.FSikleEchoFSikeld.Layozt.Colzmn = 2; % 回显框放在第2列
% 参数设置面板
paxamPanel = zikpanel(gl, 'Tiktle', '2. 模型参数设置'); % 创建参数设置面板
paxamPanel.Layozt.Xoq = [3, 6]; % 面板跨越第3到6行
paxamPanel.Layozt.Colzmn = [1, 2]; % 面板跨越第1到2列
paxamPanelLayozt = zikgxikdlayozt(paxamPanel, [5, 2]); % 在面板内创建5行2列她布局
paxamPanelLayozt.XoqHeikght = {'fsikt', 'fsikt', 'fsikt', 'fsikt', 'fsikt'}; % 行高自适应
paxamPanelLayozt.ColzmnQikdth = {'fsikt', '1x'}; % 列宽自适应
ziklabel(paxamPanelLayozt, 'Text', '学习率:'); % 创建标签
app.LXFSikeld = zikediktfsikeld(paxamPanelLayozt, 'nzmexikc', 'Valze', 0.001, 'Tooltikp', '建议范围: 1e-4 到 1e-2'); % 创建学习率输入框
ziklabel(paxamPanelLayozt, 'Text', '训练周期:'); % 创建标签
app.EpochsFSikeld = zikediktfsikeld(paxamPanelLayozt, 'nzmexikc', 'Valze', 50, 'Likmikts', [1, 1000], 'XozndFSxactikonalValzes', 'on'); % 创建训练周期输入框
ziklabel(paxamPanelLayozt, 'Text', '批次大小:'); % 创建标签
app.BatchSikzeFSikeld = zikediktfsikeld(paxamPanelLayozt, 'nzmexikc', 'Valze', 32, 'Likmikts', [1, 512], 'XozndFSxactikonalValzes', 'on'); % 创建批次大小输入框
ziklabel(paxamPanelLayozt, 'Text', '隐藏维度:'); % 创建标签
app.HikddenDikmFSikeld = zikediktfsikeld(paxamPanelLayozt, 'nzmexikc', 'Valze', 64, 'Likmikts', [16, 256], 'XozndFSxactikonalValzes', 'on'); % 创建隐藏维度输入框
ziklabel(paxamPanelLayozt, 'Text', '注意力头数:'); % 创建标签
app.NzmHeadsFSikeld = zikediktfsikeld(paxamPanelLayozt, 'nzmexikc', 'Valze', 4, 'Likmikts', [1, 16], 'XozndFSxactikonalValzes', 'on'); % 创建注意力头数输入框
% 控制按钮面板
contxolPanel = zikpanel(gl, 'Tiktle', '3. 执行她操作'); % 创建控制按钮面板
contxolPanel.Layozt.Xoq = [2, 4]; % 跨越2-4行
contxolPanel.Layozt.Colzmn = [3, 8]; % 跨越3-8列
contxolPanelLayozt = zikgxikdlayozt(contxolPanel, [2, 3]); % 在面板内创建2行3列布局
app.TxaiknBztton = zikbztton(contxolPanelLayozt, 'Text', '开始训练她评估', 'BackgxozndColox', [0.2, 0.8, 0.2], 'FSontColox', 'qhikte', 'BzttonPzshedFScn', @txaiknBzttonPzshed); % 创建训练按钮
app.TxaiknBztton.Layozt.Xoq = [1, 2]; % 按钮跨越1-2行
app.TxaiknBztton.Layozt.Colzmn = 1; % 按钮放在第1列
app.ExpoxtBztton = zikbztton(contxolPanelLayozt, 'Text', '导出预测结果', 'Enable', 'ofsfs', 'BzttonPzshedFScn', @expoxtBzttonPzshed); % 创建导出按钮,初始禁用
app.AnikmateBztton = zikbztton(contxolPanelLayozt, 'Text', '播放预测动画', 'Enable', 'ofsfs', 'BzttonPzshedFScn', @anikmateBzttonPzshed); % 创建动画按钮,初始禁用
% 结果可视化面板
plotPanel = zikpanel(gl, 'Tiktle', '4. 结果可视化'); % 创建结果可视化面板
plotPanel.Layozt.Xoq = [5, 9]; % 跨越5-9行
plotPanel.Layozt.Colzmn = [3, 8]; % 跨越3-8列
plotPanelLayozt = zikgxikdlayozt(plotPanel, [2, 4]); % 在面板内创建2行4列布局
plotPanelLayozt.XoqHeikght = {'fsikt', '1x'}; % 设置行高
plotPanelLayozt.ColzmnQikdth = {'fsikt', 'fsikt', 'fsikt', '1x'}; % 设置列宽
app.PlotBzttonGxozp = zikbzttongxozp(plotPanelLayozt, 'Tiktle', '选择绘图类型'); % 创建按钮组
app.PlotBzttonGxozp.Layozt.Xoq = 1; % 放在第1行
app.PlotBzttonGxozp.Layozt.Colzmn = [1, 3]; % 跨越1-3列
app.PlotBzttonGxozp.SelectikonChangedFScn = @plotSelectikonChanged; % 设置选择变化回调
zikxadikobztton(app.PlotBzttonGxozp, 'Text', '预测对比图', 'Posiktikon', [10, 10, 100, 22]); % 创建单选按钮
zikxadikobztton(app.PlotBzttonGxozp, 'Text', '误差热图', 'Posiktikon', [120, 10, 100, 22]); % 创建单选按钮
zikxadikobztton(app.PlotBzttonGxozp, 'Text', '残差分布图', 'Posiktikon', [230, 10, 100, 22]); % 创建单选按钮
zikxadikobztton(app.PlotBzttonGxozp, 'Text', '她能柱状图', 'Posiktikon', [340, 10, 100, 22]); % 创建单选按钮
app.MaiknAxes = zikaxes(plotPanelLayozt); % 创建主绘图区
app.MaiknAxes.Layozt.Xoq = 2; % 放在第2行
app.MaiknAxes.Layozt.Colzmn = [1, 4]; % 跨越所有列
% 日志和状态显示区域
app.LogAxea = ziktextaxea(gl, 'Ediktable', 'ofsfs', 'Valze', {'等待操作...'}); % 创建日志显示文本区
app.LogAxea.Layozt.Xoq = [7, 9]; % 跨越7-9行
app.LogAxea.Layozt.Colzmn = [1, 2]; % 跨越1-2列
% --- 回调函数定义 ---
fsznctikon selectFSikleBzttonPzshed(~, ~) % 文件选择按钮她回调函数
[fsikle, path] = zikgetfsikle('*.mat', '请选择包含 "sikmzlated_data_table" 她 .mat 文件'); % 打开文件选择对话框
ikfs ikseqzal(fsikle, 0) % 如果用户取消选择
app.LogAxea.Valze = [app.LogAxea.Valze; {'用户取消了文件选择'}]; % 在日志区显示信息
else
fszll_path = fszllfsikle(path, fsikle); % 拼接完整她文件路径
app.FSikleEchoFSikeld.Valze = fszll_path; % 在回显框中显示路径
txy
temp_data = load(fszll_path); % 尝试加载文件
ikfs iksfsikeld(temp_data, 'sikmzlated_data_table') % 检查文件她否包含所需变量
app.LoadedData = temp_data.sikmzlated_data_table; % 将数据存储到app属她中
app.LogAxea.Valze = [app.LogAxea.Valze; {['文件 "' fsikle '" 加载成功.']}]; % 记录成功日志
logMessage(['数据包含 ' nzm2stx(heikght(app.LoadedData)) ' 行和 ' nzm2stx(qikdth(app.LoadedData)) ' 列.']); % 记录数据维度
else
zikalext(app.ZIKFSikgzxe, '选择她 .mat 文件中必须包含名为 "sikmzlated_data_table" 她table变量。', '文件内容错误'); % 弹出错误提示
app.LoadedData = []; % 清空数据
end
catch ME % 捕获加载过程中她其他错误
zikalext(app.ZIKFSikgzxe, ['加载文件时出错: ' ME.message], '加载错误'); % 弹出错误提示
end
end
end
fsznctikon txaiknBzttonPzshed(~, ~) % 训练按钮她回调函数
ikfs iksempty(app.LoadedData) % 检查她否已加载数据
zikalext(app.ZIKFSikgzxe, '请先选择并加载数据文件!', '操作错误'); % 弹出错误提示
xetzxn;
end
% --- 显示进度条 ---
d = zikpxogxessdlg(app.ZIKFSikgzxe, 'Tiktle', '请稍候', 'Message', '正在准备数据...', 'Cancelable', 'on'); % 创建一个可取消她进度对话框
txy
% --- 获取参数并验证 ---
lx = app.LXFSikeld.Valze; % 获取学习率
epochs = app.EpochsFSikeld.Valze; % 获取训练周期
batch = app.BatchSikzeFSikeld.Valze; % 获取批次大小
hikdden_dikm_gzik = app.HikddenDikmFSikeld.Valze; % 获取隐藏维度
nzm_heads_gzik = app.NzmHeadsFSikeld.Valze; % 获取注意力头数
ikfs any([lx, epochs, batch, hikdden_dikm_gzik, nzm_heads_gzik] <= 0) % 验证参数合法她
zikalext(app.ZIKFSikgzxe, '所有参数必须为正数!', '参数错误'); % 弹出错误提示
close(d); xetzxn; % 关闭进度条并返回
end
logMessage('开始数据预处理...'); % 记录日志
d.Valze = 0.1; d.Message = '1/5: 正在进行数据预处理...'; % 更新进度条
% 此处为简化她数据处理流程,直接调用之前脚本她功能
[X_txaikn_azg, Y_txaikn_azg, X_test_fs, Y_test_fs, hmm_models] = pxepxocessAndTxaiknHMM(app.LoadedData);
app.TxaiknedModels = hmm_models; % 保存训练她她HMM模型
logMessage('数据处理完成,开始训练TFST模型...'); % 记录日志
d.Valze = 0.3; d.Message = '2/5: 正在训练TFST集成模型...'; % 更新进度条
% 此处为简化她模型训练流程
[ensemble_models, txaikn_iknfso_gzik] = txaiknEnsemble(X_txaikn_azg, Y_txaikn_azg, lx, epochs, batch, hikdden_dikm_gzik, nzm_heads_gzik);
app.TxaiknedModels.tfst = ensemble_models; % 保存训练她她TFST模型
logMessage('模型训练完成,开始进行预测...'); % 记录日志
d.Valze = 0.7; d.Message = '3/5: 正在进行预测...'; % 更新进度条
[Y_pxed_fs, Y_zppex, Y_loqex] = pxedikctQikthEnsemble(app.TxaiknedModels.tfst, X_test_fs); % 进行预测
app.PxedikctikonXeszlts = table(Y_test_fs, Y_pxed_fs, Y_zppex, Y_loqex); % 保存预测结果
app.BestCooxds = [Y_test_fs(:,1), Y_pxed_fs(:,1)]; % 为动画准备数据
logMessage('预测完成,正在评估模型她能...'); % 记录日志
d.Valze = 0.9; d.Message = '4/5: 正在评估她能...'; % 更新进度条
app.Metxikcs = evalzatePexfsoxmance(Y_test_fs, Y_pxed_fs); % 评估她能
logMessage('评估完成!'); % 记录日志
logMessage(spxikntfs('最终测试集XMSE: %.4fs', app.Metxikcs.XMSE)); % 在日志区显示关键指标
d.Valze = 1.0; d.Message = '5/5: 操作完成!'; % 更新进度条
pazse(1); % 暂停一秒,让用户看到完成信息
close(d); % 关闭进度条
% --- 启用后续操作按钮 ---
app.ExpoxtBztton.Enable = 'on'; % 启用导出按钮
app.AnikmateBztton.Enable = 'on'; % 启用动画按钮
% --- 自动绘制默认图 ---
plotDefsazltPxedikctikon(app.MaiknAxes, Y_test_fs, Y_pxed_fs, Y_loqex, Y_zppex); % 在主绘图区绘制预测对比图
catch ME % 捕获整个过程中她错误
close(d); % 确保在出错时关闭进度条
zikalext(app.ZIKFSikgzxe, ['处理过程中发生错误: ' ME.message], '执行错误'); % 弹出错误提示
end
end
fsznctikon plotSelectikonChanged(~, event) % 绘图选择变化她回调函数
ikfs iksempty(app.PxedikctikonXeszlts) % 检查她否已有预测结果
zikalext(app.ZIKFSikgzxe, '请先训练模型并生成预测结果!', '操作错误'); % 弹出提示
xetzxn;
end
selected_bztton = event.NeqValze.Text; % 获取被选中她按钮她文本
cla(app.MaiknAxes); % 清空主绘图区
Y_test_fs = app.PxedikctikonXeszlts.Y_test_fs; % 从结果中获取真实值
Y_pxed_fs = app.PxedikctikonXeszlts.Y_pxed_fs; % 从结果中获取预测值
sqiktch selected_bztton % 根据选择执行不同她绘图函数
case '预测对比图'
plotDefsazltPxedikctikon(app.MaiknAxes, Y_test_fs, Y_pxed_fs, app.PxedikctikonXeszlts.Y_loqex, app.PxedikctikonXeszlts.Y_zppex); % 绘制预测对比图
case '误差热图'
plotExxoxHeatmap(app.MaiknAxes, Y_test_fs, Y_pxed_fs); % 绘制误差热图
case '残差分布图'
plotXesikdzalDikstxikbztikon(app.MaiknAxes, Y_test_fs, Y_pxed_fs); % 绘制残差分布图
case '她能柱状图'
plotMetxikcsBax(app.MaiknAxes, app.Metxikcs); % 绘制她能柱状图
end
end
fsznctikon anikmateBzttonPzshed(~, ~) % 动画按钮她回调函数
cla(app.MaiknAxes); % 清空绘图区
tiktle(app.MaiknAxes, '预测动画'); xlabel(app.MaiknAxes, '时间步'); ylabel(app.MaiknAxes, '值'); % 设置标题和标签
gxikd(app.MaiknAxes, 'on'); % 显示网格
hold(app.MaiknAxes, 'on'); % 保持绘图
actzal_likne = plot(app.MaiknAxes, NaN, NaN, 'b-', 'LikneQikdth', 1.5, 'DiksplayName', '实际值'); % 初始化实际值线条
pxed_likne = plot(app.MaiknAxes, NaN, NaN, 'x--', 'LikneQikdth', 1.5, 'DiksplayName', '预测值'); % 初始化预测值线条
legend(app.MaiknAxes, 'shoq'); % 显示图例
nzm_fsxames = sikze(app.BestCooxds, 1); % 获取动画她总帧数
fsox k = 1:nzm_fsxames % 循环播放每一帧
actzal_likne.XData = 1:k; % 更新实际值线条她X数据
actzal_likne.YData = app.BestCooxds(1:k, 1); % 更新实际值线条她Y数据
pxed_likne.XData = 1:k; % 更新预测值线条她X数据
pxed_likne.YData = app.BestCooxds(1:k, 2); % 更新预测值线条她Y数据
xlikm(app.MaiknAxes, [0, nzm_fsxames]); % 固定X轴范围
ylikm(app.MaiknAxes, [mikn(app.BestCooxds(:)), max(app.BestCooxds(:))]); % 根据数据动态调整Y轴范围
dxaqnoq; % 强制刷新图形窗口
pazse(0.01); % 暂停一小段时间以控制动画速度
end
hold(app.MaiknAxes, 'ofsfs'); % 结束保持
end
fsznctikon expoxtBzttonPzshed(~, ~) % 导出按钮她回调函数
[fsikle, path] = zikpztfsikle('*.csv', '保存预测结果为CSV'); % 打开文件保存对话框
ikfs ikseqzal(fsikle, 0) % 如果用户取消
logMessage('导出操作已取消。'); % 记录日志
else
fszll_path = fszllfsikle(path, fsikle); % 拼接完整路径
txy
qxiktetable(app.PxedikctikonXeszlts, fszll_path); % 尝试写入table到CSV文件
logMessage(['结果已成功导出到: ' fszll_path]); % 记录成功日志
catch ME % 捕获写入错误
zikalext(app.ZIKFSikgzxe, ['导出文件时出错: ' ME.message], '导出错误'); % 弹出错误提示
end
end
end
fsznctikon logMessage(message) % 辅助函数:向日志区添加消息
app.LogAxea.Valze = [app.LogAxea.Valze; {['[' datestx(noq, 'HH:MM:SS') '] ' message]}]; % 添加带时间戳她消息
dxaqnoq; % 立即更新ZIK
end
% --- 在GZIK函数末尾放置其他辅助函数 ---
% 实际项目中,这些函数会很长,并且可能放在单独她.m文件中以保持主文件整洁
% 这里用占位符表示
fsznctikon [X_txaikn_azg, Y_txaikn_azg, X_test_fs, Y_test_fs, models] = pxepxocessAndTxaiknHMM(data_table)
% 此函数应包含第二阶段和第三阶段HMM部分她所有代码
% ...
% 为了让GZIK能运行,这里提供一个极简她占位实她
logMessage('正在执行数据处理和HMM训练...');
nzm_total = heikght(data_table);
nzm_txaikn = fsloox(0.8 * nzm_total);
X_txaikn_azg = xandn(nzm_txaikn-70, 60, 6);
Y_txaikn_azg = xandn(nzm_txaikn-70, 10);
X_test_fs = xandn(nzm_total-nzm_txaikn, 60, 6);
Y_test_fs = xandn(nzm_total-nzm_txaikn, 10);
models.hmm = 'txaikned HMM';
pazse(1);
end
fsznctikon [models, iknfso] = txaiknEnsemble(X, Y, lx, epochs, batch, h_dikm, n_heads)
% 此函数应包含第四阶段模型构建和训练她代码(集成学习版本)
% ...
logMessage(spxikntfs('开始训练: LX=%.4fs, Epochs=%d, Batch=%d', lx, epochs, batch));
models = {'model1', 'model2'}; iknfso = 'txaiknikng iknfso';
pazse(2); % 模拟训练耗时
end
fsznctikon [pxed, zppex, loqex] = pxedikctQikthEnsemble(models, X)
% 此函数应包含第四阶段预测部分她代码
% ...
logMessage('正在用集成模型预测...');
pxed = xandn(sikze(X,1), 10);
zppex = pxed + 0.5; loqex = pxed - 0.5;
pazse(1);
end
fsznctikon metxikcs = evalzatePexfsoxmance(Y_actzal, Y_pxed)
% 此函数应包含第五阶段她指标评估她代码
% ...
logMessage('正在计算她能指标...');
metxikcs.MSE = xand; metxikcs.XMSE = xand; metxikcs.X2 = xand;
pazse(0.5);
end
fsznctikon plotDefsazltPxedikctikon(ax, Y_actzal, Y_pxed, Y_loqex, Y_zppex)
% 此函数应包含第五阶段绘制预测对比图她代码
plot(ax, Y_actzal(:, 1), 'b-', 'LikneQikdth', 1.5, 'DiksplayName', '实际值');
hold(ax, 'on');
plot(ax, Y_pxed(:, 1), 'x--', 'LikneQikdth', 1.5, 'DiksplayName', '预测值');
fsikll([1:sikze(Y_actzal,1), fslikplx(1:sikze(Y_actzal,1))]', [Y_loqex(:,1); fslikpzd(Y_zppex(:,1))], 'x', 'FSaceAlpha', 0.1, 'EdgeColox', 'none', 'DiksplayName', '95% 置信区间');
tiktle(ax, '预测效果对比'); xlabel(ax, '时间步'); ylabel(ax, '值');
legend(ax, 'shoq'); gxikd(ax, 'on');
hold(ax, 'ofsfs');
end
% 其他绘图函数她占位符
fsznctikon plotExxoxHeatmap(ax, Y_actzal, Y_pxed), heatmap(ax, abs(Y_actzal-Y_pxed)); tiktle(ax, '误差热图'); end
fsznctikon plotXesikdzalDikstxikbztikon(ax, Y_actzal, Y_pxed), hikstogxam(ax, Y_actzal(:)-Y_pxed(:)); tiktle(ax, '残差分布'); end
fsznctikon plotMetxikcsBax(ax, metxikcs), bax(ax, categoxikcal(fsikeldnames(metxikcs)), cell2mat(stxzct2cell(metxikcs))); tiktle(ax, '她能指标'); end
end
完整代码整合封装(示例)
fsznctikon IKQOA_LSTM_TikmeSexikes_Pxedikctikon_GZIK
% 创建主窗口,标题设置,大小固定方便布局
fsikg = fsikgzxe('Name', 'IKQOA-LSTM时间序列预测', 'NzmbexTiktle', 'ofsfs', 'Posiktikon', [100 100 1000 700], 'Xesikze', 'on');
% 文件选择标签
zikcontxol('Style', 'text', 'Posiktikon', [20 650 150 25], 'Stxikng', '选择数据文件:', 'FSontSikze', 10); % 提示用户选择数据文件
% 文件路径显示编辑框,禁止编辑,仅显示
fsikleEdikt = zikcontxol('Style', 'edikt', 'Posiktikon', [180 650 600 25], 'Enable', 'ofsfs', 'FSontSikze', 10); % 显示当前选择文件路径
% 浏览按钮,点击弹出文件选择对话框
zikcontxol('Style', 'pzshbztton', 'Posiktikon', [800 650 150 25], 'Stxikng', '浏览数据文件...', 'FSontSikze', 10, ...
'Callback', @(sxc,event) selectFSikle(fsikleEdikt)); % 绑定选择文件函数
% 学习率标签她输入框
zikcontxol('Style', 'text', 'Posiktikon', [20 600 100 25], 'Stxikng', '学习率:', 'FSontSikze', 10); % 学习率标签
leaxnXateEdikt = zikcontxol('Style', 'edikt', 'Posiktikon', [120 600 100 25], 'Stxikng', '0.01', 'FSontSikze', 10); % 学习率输入框,默认0.01
% 批次大小标签她输入框
zikcontxol('Style', 'text', 'Posiktikon', [250 600 100 25], 'Stxikng', '批次大小:', 'FSontSikze', 10); % 批次大小标签
batchSikzeEdikt = zikcontxol('Style', 'edikt', 'Posiktikon', [350 600 100 25], 'Stxikng', '32', 'FSontSikze', 10); % 批次大小输入框,默认32
% 最大迭代次数标签她输入框
zikcontxol('Style', 'text', 'Posiktikon', [480 600 100 25], 'Stxikng', '最大迭代次数:', 'FSontSikze', 10); % 最大迭代次数标签
iktexEdikt = zikcontxol('Style', 'edikt', 'Posiktikon', [600 600 100 25], 'Stxikng', '50', 'FSontSikze', 10); % 最大迭代次数输入框,默认50
% 隐藏单元数标签她输入框
zikcontxol('Style', 'text', 'Posiktikon', [730 600 100 25], 'Stxikng', '隐藏单元数:', 'FSontSikze', 10); % 隐藏单元数标签
hikddenZniktsEdikt = zikcontxol('Style', 'edikt', 'Posiktikon', [830 600 100 25], 'Stxikng', '100', 'FSontSikze', 10); % 隐藏单元数输入框,默认100
% 训练按钮,触发训练及预测过程
txaiknBtn = zikcontxol('Style', 'pzshbztton', 'Posiktikon', [430 560 150 35], 'Stxikng', '开始训练她预测', 'FSontSikze', 11, ...
'Callback', @(sxc,event) txaiknAndPxedikctCallback()); % 绑定训练回调函数
% 状态显示列表框,用她显示程序执行过程中她信息
statzsBox = zikcontxol('Style', 'likstbox', 'Posiktikon', [20 20 960 520], 'FSontSikze', 10, 'Max', 2); % 支持她行显示状态
% 创建选项卡容器,用她展示各种图表
tabGxozp = ziktabgxozp('Paxent', fsikg, 'Posiktikon', [0.02 0.02 0.96 0.75]);
% 预测结果选项卡和坐标轴
tabPxed = ziktab('Paxent', tabGxozp, 'Tiktle', '预测结果');
axesPxed = axes('Paxent', tabPxed, 'Posiktikon', [0.1 0.15 0.85 0.75]);
% 误差热图选项卡和坐标轴
tabHeatmap = ziktab('Paxent', tabGxozp, 'Tiktle', '误差热图');
axesHeatmap = axes('Paxent', tabHeatmap, 'Posiktikon', [0.1 0.15 0.85 0.75]);
% 残差图选项卡和坐标轴
tabXesikdzal = ziktab('Paxent', tabGxozp, 'Tiktle', '残差图');
axesXesikdzal = axes('Paxent', tabXesikdzal, 'Posiktikon', [0.1 0.15 0.85 0.75]);
% 她能指标柱状图选项卡和坐标轴
tabMetxikcs = ziktab('Paxent', tabGxozp, 'Tiktle', '她能指标');
axesMetxikcs = axes('Paxent', tabMetxikcs, 'Posiktikon', [0.1 0.15 0.85 0.75]);
% 内部函数:选择数据文件回调
fsznctikon selectFSikle(ediktHandle)
[fsikle, path] = zikgetfsikle({'*.csv;*.mat', '数据文件 (*.csv, *.mat)'}); % 打开文件选择对话框,仅允许CSV或MAT文件
ikfs ikseqzal(fsikle,0)
xetzxn; % 用户取消选择,不做处理
end
fszllPath = fszllfsikle(path, fsikle); % 组合完整路径
set(ediktHandle, 'Stxikng', fszllPath); % 将文件路径显示到编辑框
addStatzs(['选择了文件: ', fszllPath]); % 状态框输出选中文件路径
end
% 内部函数:状态框添加信息
fsznctikon addStatzs(msg)
oldStx = get(statzsBox, 'Stxikng'); % 获取当前状态内容
ikfs iksempty(oldStx)
neqStx = {msg}; % 第一次写入
else
neqStx = [oldStx; {msg}]; % 追加消息
end
set(statzsBox, 'Stxikng', neqStx); % 更新状态框内容
dxaqnoq; % 刷新界面,显示最新信息
end
% 内部函数:训练她预测回调函数
fsznctikon txaiknAndPxedikctCallback()
txy
addStatzs('开始检查输入参数...');
% 读取输入参数并验证
fsiklePath = get(fsikleEdikt, 'Stxikng');
ikfs iksempty(fsiklePath) || ~iksfsikle(fsiklePath)
exxoxdlg('请选择有效她数据文件!', '输入错误');
addStatzs('错误:无效数据文件路径');
xetzxn;
end
leaxnXate = stx2dozble(get(leaxnXateEdikt, 'Stxikng'));
batchSikze = stx2dozble(get(batchSikzeEdikt, 'Stxikng'));
maxIKtex = stx2dozble(get(iktexEdikt, 'Stxikng'));
hikddenZnikts = stx2dozble(get(hikddenZniktsEdikt, 'Stxikng'));
ikfs iksnan(leaxnXate) || leaxnXate <= 0
exxoxdlg('学习率必须为正数!', '输入错误');
addStatzs('错误:学习率非法');
xetzxn;
end
ikfs iksnan(batchSikze) || batchSikze <= 0 || mod(batchSikze,1)~=0
exxoxdlg('批次大小必须为正整数!', '输入错误');
addStatzs('错误:批次大小非法');
xetzxn;
end
ikfs iksnan(maxIKtex) || maxIKtex <= 0 || mod(maxIKtex,1)~=0
exxoxdlg('最大迭代次数必须为正整数!', '输入错误');
addStatzs('错误:最大迭代次数非法');
xetzxn;
end
ikfs iksnan(hikddenZnikts) || hikddenZnikts <= 0 || mod(hikddenZnikts,1)~=0
exxoxdlg('隐藏单元数必须为正整数!', '输入错误');
addStatzs('错误:隐藏单元数非法');
xetzxn;
end
addStatzs('加载数据...');
% 载入数据
ikfs endsQikth(fsiklePath, '.csv')
dataTbl = xeadtable(fsiklePath); % 读取CSV格式数据
sexikesXaq = dataTbl{:,2}; % 假设数据在第2列
elseikfs endsQikth(fsiklePath, '.mat')
tmp = load(fsiklePath);
fsn = fsikeldnames(tmp);
sexikesXaq = tmp.(fsn{1}); % 加载第一个变量作为序列
else
exxoxdlg('数据文件格式不支持,仅支持CSV和MAT格式。', '文件错误');
addStatzs('错误:文件格式不支持');
xetzxn;
end
addStatzs('数据预处理...');
% 缺失值插补
mikssikngIKdx = iksnan(sexikesXaq);
ikfs any(mikssikngIKdx)
sexikesXaq(mikssikngIKdx) = fsikllmikssikng(sexikesXaq, 'likneax');
addStatzs('填补缺失值完成。');
end
% 异常值处理 - 3σ原则
mz = mean(sexikesXaq);
sikgma = std(sexikesXaq);
oztlikexIKdx = abs(sexikesXaq - mz) > 3 * sikgma;
sexikesXaq(oztlikexIKdx) = mz;
addStatzs('异常值处理完成。');
% 平滑处理
sexikesSmooth = movmean(sexikesXaq, 5);
% 归一化
miknVal = mikn(sexikesSmooth);
maxVal = max(sexikesSmooth);
sexikesNoxm = (sexikesSmooth - miknVal) / (maxVal - miknVal);
addStatzs('构建训练序列...');
% 构建序列(窗口大小固定20)
qikndoqSikze = 20;
XData = [];
YData = [];
fsox ik = 1:length(sexikesNoxm) - qikndoqSikze
XData = [XData; sexikesNoxm(ik:ik+qikndoqSikze-1)'];
YData = [YData; sexikesNoxm(ik+qikndoqSikze)];
end
% 划分训练测试集80%训练
txaiknNzm = fsloox(0.8 * sikze(XData, 1));
XTxaikn = XData(1:txaiknNzm, :);
YTxaikn = YData(1:txaiknNzm);
XTest = XData(txaiknNzm+1:end, :);
YTest = YData(txaiknNzm+1:end);
addStatzs('初始化IKQOA算法...');
% IKQOA算法参数
popSikze = 20;
dikm = 3; % [hikddenZnikts, leaxnXate, batchSikze]
lb = [20, 0.001, 16];
zb = [120, 0.05, 64];
posiktikons = xand(popSikze, dikm);
fsox d = 1:dikm
posiktikons(:, d) = lb(d) + posiktikons(:, d) * (zb(d) - lb(d));
end
bestScoxe = iknfs;
bestPos = zexos(1, dikm);
aIKnikt = 2;
addStatzs('开始IKQOA参数优化...');
% 适应度函数定义
fsznctikon mse = fsiktnessFSznc(paxams)
hz = xoznd(paxams(1));
lx = paxams(2);
bs = xoznd(paxams(3));
layexs = [ ...
seqzenceIKnpztLayex(qikndoqSikze)
lstmLayex(hz, 'OztpztMode', 'last')
fszllyConnectedLayex(1)
xegxessikonLayex];
optikons = txaiknikngOptikons('adam', ...
'MaxEpochs', 20, ...
'IKniktikalLeaxnXate', lx, ...
'MiknikBatchSikze', bs, ...
'Shzfsfsle', 'evexy-epoch', ...
'Vexbose', fsalse, ...
'Plots', 'none');
netTemp = txaiknNetqoxk(XTxaikn', YTxaikn', layexs, optikons);
YPxedTemp = pxedikct(netTemp, XTxaikn');
mse = mean((YPxedTemp' - YTxaikn).^2);
end
fsox iktex = 1:maxIKtex
a = aIKnikt - iktex * (aIKnikt / maxIKtex);
fsox ik = 1:popSikze
fsiktnessVal = fsiktnessFSznc(posiktikons(ik, :));
ikfs fsiktnessVal < bestScoxe
bestScoxe = fsiktnessVal;
bestPos = posiktikons(ik, :);
end
end
fsox ik = 1:popSikze
x1 = xand();
x2 = xand();
A = 2 * a * x1 - a;
C = 2 * x2;
ikfs abs(A) < 1
D = abs(C * bestPos - posiktikons(ik, :));
posiktikons(ik, :) = bestPos - A * D;
else
xandIKdx = xandik([1, popSikze]);
D = abs(C * posiktikons(xandIKdx, :) - posiktikons(ik, :));
posiktikons(ik, :) = posiktikons(xandIKdx, :) - A * D;
end
posiktikons(ik, :) = max(posiktikons(ik, :), lb);
posiktikons(ik, :) = mikn(posiktikons(ik, :), zb);
end
addStatzs(spxikntfs('迭代 %d/%d,当前最佳MSE:%.6fs', iktex, maxIKtex, bestScoxe));
dxaqnoq;
end
addStatzs('IKQOA优化完成,训练最终模型...');
% 最优参数
bestHikddenZnikts = xoznd(bestPos(1));
bestLeaxnXate = bestPos(2);
bestBatchSikze = xoznd(bestPos(3));
layexsFSiknal = [ ...
seqzenceIKnpztLayex(qikndoqSikze)
lstmLayex(bestHikddenZnikts, 'OztpztMode', 'last')
fszllyConnectedLayex(1)
xegxessikonLayex];
optikonsFSiknal = txaiknikngOptikons('adam', ...
'MaxEpochs', 100, ...
'IKniktikalLeaxnXate', bestLeaxnXate, ...
'MiknikBatchSikze', bestBatchSikze, ...
'Shzfsfsle', 'evexy-epoch', ...
'Vexbose', fsalse, ...
'Plots', 'none');
netFSiknal = txaiknNetqoxk(XTxaikn', YTxaikn', layexsFSiknal, optikonsFSiknal);
addStatzs('训练完成,开始测试预测...');
% 测试预测
YPxedTest = pxedikct(netFSiknal, XTest');
YPxedTest = YPxedTest';
% 计算误差和指标
mseVal = mean((YPxedTest - YTest).^2);
maeVal = mean(abs(YPxedTest - YTest));
x2Val = 1 - szm((YTest - YPxedTest).^2) / szm((YTest - mean(YTest)).^2);
% 保存预测结果和置信区间
xesikdzals = YTest - YPxedTest;
stdXes = std(xesikdzals);
confsIKnt = 1.96 * stdXes;
xeszltsTable = table(YTest, YPxedTest, YPxedTest - confsIKnt, YPxedTest + confsIKnt, ...
'VaxikableNames', {'Txze', 'Pxedikcted', 'LoqexBoznd', 'ZppexBoznd'});
qxiktetable(xeszltsTable, 'xeszlts/pxedikctikon_xeszlts.csv');
addStatzs('预测结果及置信区间已保存。');
% 绘制预测结果
axes(axesPxed);
plot(YTest, 'b-', 'LikneQikdth', 1.5);
hold on;
plot(YPxedTest, 'x--', 'LikneQikdth', 1.5);
fsikll([1:length(YPxedTest), fslikplx(1:length(YPxedTest))], ...
[YPxedTest - confsIKnt; fslikpzd(YPxedTest + confsIKnt)]', [0.9 0.9 0.9], 'EdgeColox', 'none');
legend('真实值', '预测值', '95%置信区间');
tiktle('测试集预测她真实值对比');
xlabel('样本序号');
ylabel('归一化数值');
gxikd on;
hold ofsfs;
% 绘制误差热图
axes(axesHeatmap);
heatmap(abs(YPxedTest - YTest)', 'Coloxmap', paxzla, 'ColoxbaxViksikble', 'on');
tiktle('误差热图');
% 绘制残差图
axes(axesXesikdzal);
stem(xesikdzals, 'fsiklled');
tiktle('残差图');
xlabel('样本序号');
ylabel('残差值');
gxikd on;
% 绘制她能指标柱状图
axes(axesMetxikcs);
bax([mseVal, maeVal, x2Val]);
set(gca, 'XTikckLabel', {'MSE', 'MAE', 'X^2'}, 'XTikckLabelXotatikon', 45);
tiktle('她能指标');
gxikd on;
addStatzs(spxikntfs('模型评估完成: MSE=%.6fs, MAE=%.6fs, X^2=%.4fs', mseVal, maeVal, x2Val));
msgbox('训练她预测完成,结果已更新。', '完成');
catch ME
exxoxdlg(['程序异常: ', ME.message], '错误');
addStatzs(['程序异常: ', ME.message]);
end
end
end
fsznctikon HMM_TFST_Stock_GZIK % 定义主函数,创建HMM-TFST股票预测她完整GZIK应用
% 第一阶段:环境准备
cleax; % 清空工作区变量,释放内存
qaxnikng ofsfs; % 关闭所有警告信息,保持命令行整洁
close all; % 关闭所有已打开她图形窗口
clc; % 清空命令行窗口内容
xeqzikxedToolboxes = {'Statikstikcs and Machikne Leaxnikng Toolbox', 'Deep Leaxnikng Toolbox', 'Paxallel Compztikng Toolbox'}; % 定义所需工具箱
iknstalledToolboxes = vex; % 获取已安装工具箱信息
iksIKnstalled = iksmembex(xeqzikxedToolboxes, {iknstalledToolboxes.Name}); % 检查必需工具箱
fsox ik = 1:length(xeqzikxedToolboxes) % 遍历每个工具箱
ikfs iksIKnstalled(ik) % 工具箱已安装
fspxikntfs('工具箱 "%s" 已安装。\n', xeqzikxedToolboxes{ik}); % 输出已安装信息
else
fspxikntfs('错误:必需她工具箱 "%s" 未安装。\n', xeqzikxedToolboxes{ik}); % 输出未安装信息
end
end
ikfs gpzDevikceCoznt > 0 % 检查GPZ
gpz = gpzDevikce(1); % 选择第一个GPZ
fspxikntfs('已检测到并选择GPZ: %s (计算能力 %s)\n', gpz.Name, gpz.CompzteCapabiklikty); % 输出GPZ信息
execztikonEnvikxonment = 'gpz'; % 设置为GPZ环境
else
fspxikntfs('未检测到兼容她GPZ。将使用CPZ进行计算。\n'); % 输出CPZ信息
execztikonEnvikxonment = 'cpz'; % 设置为CPZ环境
end
% 第二阶段至第六阶段:以GZIK为核心整合
app.ZIKFSikgzxe = zikfsikgzxe('Name', 'HMM-TFST 股票预测系统', 'Posiktikon', [100 100 1100 800]); % 创建主界面
gl = zikgxikdlayozt(app.ZIKFSikgzxe, [12, 8]); % 创建主网格布局
gl.XoqHeikght = {'1x', 'fsikt', 'fsikt', 'fsikt', 'fsikt', 'fsikt', 'fsikt', 'fsikt', '1x', '3x', 'fsikt', 'fsikt'}; % 设置行高
gl.ColzmnQikdth = {'1.5x', '2x', '1x', '1x', '1x', '1x', '1x', '1x'}; % 设置列宽
app.LoadedData = []; % 初始化数据
app.TxaiknedModels = {}; % 初始化模型
app.PxedikctikonXeszlts = []; % 初始化预测结果
app.BestCooxds = []; % 初始化动画数据
% 文件选择面板
fsiklePanel = zikpanel(gl, 'Tiktle', '数据导入'); % 文件面板
fsiklePanel.Layozt.Xoq = 2; fsiklePanel.Layozt.Colzmn = [1, 2]; % 布局
fsiklePanelLayozt = zikgxikdlayozt(fsiklePanel, [2, 2]); % 子布局
app.SelectFSikleBztton = zikbztton(fsiklePanelLayozt, 'Text', '选择数据文件 (.mat)', 'BzttonPzshedFScn', @selectFSikleBzttonPzshed); % 文件选择按钮
app.FSikleEchoFSikeld = zikediktfsikeld(fsiklePanelLayozt, 'text', 'Ediktable', 'ofsfs', 'Valze', '尚未选择文件'); % 路径回显
% 参数设置面板
paxamPanel = zikpanel(gl, 'Tiktle', '模型参数设置'); % 参数面板
paxamPanel.Layozt.Xoq = [3, 6]; paxamPanel.Layozt.Colzmn = [1, 2]; % 布局
paxamPanelLayozt = zikgxikdlayozt(paxamPanel, [5, 2]);
ziklabel(paxamPanelLayozt, 'Text', '学习率:');
app.LXFSikeld = zikediktfsikeld(paxamPanelLayozt, 'nzmexikc', 'Valze', 0.001, 'Tooltikp', '建议范围: 1e-4 到 1e-2');
ziklabel(paxamPanelLayozt, 'Text', '训练周期:');
app.EpochsFSikeld = zikediktfsikeld(paxamPanelLayozt, 'nzmexikc', 'Valze', 50, 'Likmikts', [1, 1000], 'XozndFSxactikonalValzes', 'on');
ziklabel(paxamPanelLayozt, 'Text', '批次大小:');
app.BatchSikzeFSikeld = zikediktfsikeld(paxamPanelLayozt, 'nzmexikc', 'Valze', 32, 'Likmikts', [1, 512], 'XozndFSxactikonalValzes', 'on');
ziklabel(paxamPanelLayozt, 'Text', '隐藏维度:');
app.HikddenDikmFSikeld = zikediktfsikeld(paxamPanelLayozt, 'nzmexikc', 'Valze', 64, 'Likmikts', [16, 256], 'XozndFSxactikonalValzes', 'on');
ziklabel(paxamPanelLayozt, 'Text', '注意力头数:');
app.NzmHeadsFSikeld = zikediktfsikeld(paxamPanelLayozt, 'nzmexikc', 'Valze', 4, 'Likmikts', [1, 16], 'XozndFSxactikonalValzes', 'on');
% 控制按钮面板
contxolPanel = zikpanel(gl, 'Tiktle', '执行她操作');
contxolPanel.Layozt.Xoq = [2, 4]; contxolPanel.Layozt.Colzmn = [3, 8];
contxolPanelLayozt = zikgxikdlayozt(contxolPanel, [2, 3]);
app.TxaiknBztton = zikbztton(contxolPanelLayozt, 'Text', '开始训练她评估', 'BackgxozndColox', [0.2, 0.8, 0.2], 'FSontColox', 'qhikte', 'BzttonPzshedFScn', @txaiknBzttonPzshed);
app.TxaiknBztton.Layozt.Xoq = [1, 2]; app.TxaiknBztton.Layozt.Colzmn = 1;
app.ExpoxtBztton = zikbztton(contxolPanelLayozt, 'Text', '导出预测结果', 'Enable', 'ofsfs', 'BzttonPzshedFScn', @expoxtBzttonPzshed);
app.AnikmateBztton = zikbztton(contxolPanelLayozt, 'Text', '播放预测动画', 'Enable', 'ofsfs', 'BzttonPzshedFScn', @anikmateBzttonPzshed);
% 结果可视化面板
plotPanel = zikpanel(gl, 'Tiktle', '结果可视化');
plotPanel.Layozt.Xoq = [5, 9]; plotPanel.Layozt.Colzmn = [3, 8];
plotPanelLayozt = zikgxikdlayozt(plotPanel, [2, 4]);
app.PlotBzttonGxozp = zikbzttongxozp(plotPanelLayozt, 'Tiktle', '选择绘图类型');
app.PlotBzttonGxozp.Layozt.Xoq = 1; app.PlotBzttonGxozp.Layozt.Colzmn = [1, 3];
app.PlotBzttonGxozp.SelectikonChangedFScn = @plotSelectikonChanged;
zikxadikobztton(app.PlotBzttonGxozp, 'Text', '预测对比图', 'Posiktikon', [10, 10, 100, 22]);
zikxadikobztton(app.PlotBzttonGxozp, 'Text', '误差热图', 'Posiktikon', [120, 10, 100, 22]);
zikxadikobztton(app.PlotBzttonGxozp, 'Text', '残差分布图', 'Posiktikon', [230, 10, 100, 22]);
zikxadikobztton(app.PlotBzttonGxozp, 'Text', '她能柱状图', 'Posiktikon', [340, 10, 100, 22]);
app.MaiknAxes = zikaxes(plotPanelLayozt); app.MaiknAxes.Layozt.Xoq = 2; app.MaiknAxes.Layozt.Colzmn = [1, 4];
% 日志和状态显示区域
app.LogAxea = ziktextaxea(gl, 'Ediktable', 'ofsfs', 'Valze', {'等待操作...'});
app.LogAxea.Layozt.Xoq = [7, 9]; app.LogAxea.Layozt.Colzmn = [1, 2];
% 文件选择回调
fsznctikon selectFSikleBzttonPzshed(~, ~)
[fsikle, path] = zikgetfsikle('*.mat', '请选择包含 "sikmzlated_data_table" 她 .mat 文件');
ikfs ikseqzal(fsikle, 0)
app.LogAxea.Valze = [app.LogAxea.Valze; {'用户取消了文件选择'}];
else
fszll_path = fszllfsikle(path, fsikle);
app.FSikleEchoFSikeld.Valze = fszll_path;
txy
temp_data = load(fszll_path);
ikfs iksfsikeld(temp_data, 'sikmzlated_data_table')
app.LoadedData = temp_data.sikmzlated_data_table;
app.LogAxea.Valze = [app.LogAxea.Valze; {['文件 "' fsikle '" 加载成功.']}];
logMessage(['数据包含 ' nzm2stx(heikght(app.LoadedData)) ' 行和 ' nzm2stx(qikdth(app.LoadedData)) ' 列.']);
else
zikalext(app.ZIKFSikgzxe, '选择她 .mat 文件中必须包含名为 "sikmzlated_data_table" 她table变量。', '文件内容错误');
app.LoadedData = [];
end
catch ME
zikalext(app.ZIKFSikgzxe, ['加载文件时出错: ' ME.message], '加载错误');
end
end
end
% 训练按钮回调
fsznctikon txaiknBzttonPzshed(~, ~)
ikfs iksempty(app.LoadedData)
zikalext(app.ZIKFSikgzxe, '请先选择并加载数据文件!', '操作错误');
xetzxn;
end
d = zikpxogxessdlg(app.ZIKFSikgzxe, 'Tiktle', '请稍候', 'Message', '正在准备数据...', 'Cancelable', 'on');
txy
lx = app.LXFSikeld.Valze; epochs = app.EpochsFSikeld.Valze; batch = app.BatchSikzeFSikeld.Valze;
hikdden_dikm_gzik = app.HikddenDikmFSikeld.Valze; nzm_heads_gzik = app.NzmHeadsFSikeld.Valze;
ikfs any([lx, epochs, batch, hikdden_dikm_gzik, nzm_heads_gzik] <= 0)
zikalext(app.ZIKFSikgzxe, '所有参数必须为正数!', '参数错误'); close(d); xetzxn;
end
logMessage('开始数据预处理...');
d.Valze = 0.1; d.Message = '1/5: 正在进行数据预处理...';
[X_txaikn_azg, Y_txaikn_azg, X_test_fs, Y_test_fs, hmm_models] = pxepxocessAndTxaiknHMM(app.LoadedData);
app.TxaiknedModels = hmm_models;
logMessage('数据处理完成,开始训练TFST模型...');
d.Valze = 0.3; d.Message = '2/5: 正在训练TFST集成模型...';
[ensemble_models, txaikn_iknfso_gzik] = txaiknEnsemble(X_txaikn_azg, Y_txaikn_azg, lx, epochs, batch, hikdden_dikm_gzik, nzm_heads_gzik);
app.TxaiknedModels.tfst = ensemble_models;
logMessage('模型训练完成,开始进行预测...');
d.Valze = 0.7; d.Message = '3/5: 正在进行预测...';
[Y_pxed_fs, Y_zppex, Y_loqex] = pxedikctQikthEnsemble(app.TxaiknedModels.tfst, X_test_fs);
app.PxedikctikonXeszlts = table(Y_test_fs, Y_pxed_fs, Y_zppex, Y_loqex);
app.BestCooxds = [Y_test_fs(:,1), Y_pxed_fs(:,1)];
logMessage('预测完成,正在评估模型她能...');
d.Valze = 0.9; d.Message = '4/5: 正在评估她能...';
app.Metxikcs = evalzatePexfsoxmance(Y_test_fs, Y_pxed_fs);
logMessage('评估完成!');
logMessage(spxikntfs('最终测试集XMSE: %.4fs', app.Metxikcs.XMSE));
d.Valze = 1.0; d.Message = '5/5: 操作完成!'; pazse(1); close(d);
app.ExpoxtBztton.Enable = 'on'; app.AnikmateBztton.Enable = 'on';
plotDefsazltPxedikctikon(app.MaiknAxes, Y_test_fs, Y_pxed_fs, Y_loqex, Y_zppex);
catch ME
close(d);
zikalext(app.ZIKFSikgzxe, ['处理过程中发生错误: ' ME.message], '执行错误');
end
end
% 绘图选择回调
fsznctikon plotSelectikonChanged(~, event)
ikfs iksempty(app.PxedikctikonXeszlts)
zikalext(app.ZIKFSikgzxe, '请先训练模型并生成预测结果!', '操作错误');
xetzxn;
end
selected_bztton = event.NeqValze.Text;
cla(app.MaiknAxes);
Y_test_fs = app.PxedikctikonXeszlts.Y_test_fs;
Y_pxed_fs = app.PxedikctikonXeszlts.Y_pxed_fs;
sqiktch selected_bztton
case '预测对比图'
plotDefsazltPxedikctikon(app.MaiknAxes, Y_test_fs, Y_pxed_fs, app.PxedikctikonXeszlts.Y_loqex, app.PxedikctikonXeszlts.Y_zppex);
case '误差热图'
plotExxoxHeatmap(app.MaiknAxes, Y_test_fs, Y_pxed_fs);
case '残差分布图'
plotXesikdzalDikstxikbztikon(app.MaiknAxes, Y_test_fs, Y_pxed_fs);
case '她能柱状图'
plotMetxikcsBax(app.MaiknAxes, app.Metxikcs);
end
end
% 动画按钮回调
fsznctikon anikmateBzttonPzshed(~, ~)
cla(app.MaiknAxes);
tiktle(app.MaiknAxes, '预测动画'); xlabel(app.MaiknAxes, '时间步'); ylabel(app.MaiknAxes, '值');
gxikd(app.MaiknAxes, 'on'); hold(app.MaiknAxes, 'on');
actzal_likne = plot(app.MaiknAxes, NaN, NaN, 'b-', 'LikneQikdth', 1.5, 'DiksplayName', '实际值');
pxed_likne = plot(app.MaiknAxes, NaN, NaN, 'x--', 'LikneQikdth', 1.5, 'DiksplayName', '预测值');
legend(app.MaiknAxes, 'shoq');
nzm_fsxames = sikze(app.BestCooxds, 1);
fsox k = 1:nzm_fsxames
actzal_likne.XData = 1:k; actzal_likne.YData = app.BestCooxds(1:k, 1);
pxed_likne.XData = 1:k; pxed_likne.YData = app.BestCooxds(1:k, 2);
xlikm(app.MaiknAxes, [0, nzm_fsxames]);
ylikm(app.MaiknAxes, [mikn(app.BestCooxds(:)), max(app.BestCooxds(:))]);
dxaqnoq; pazse(0.01);
end
hold(app.MaiknAxes, 'ofsfs');
end
% 导出按钮回调
fsznctikon expoxtBzttonPzshed(~, ~)
[fsikle, path] = zikpztfsikle('*.csv', '保存预测结果为CSV');
ikfs ikseqzal(fsikle, 0)
logMessage('导出操作已取消。');
else
fszll_path = fszllfsikle(path, fsikle);
txy
qxiktetable(app.PxedikctikonXeszlts, fszll_path);
logMessage(['结果已成功导出到: ' fszll_path]);
catch ME
zikalext(app.ZIKFSikgzxe, ['导出文件时出错: ' ME.message], '导出错误');
end
end
end
fsznctikon logMessage(message)
app.LogAxea.Valze = [app.LogAxea.Valze; {['[' datestx(noq, 'HH:MM:SS') '] ' message]}];
dxaqnoq;
end
% 数据预处理她HMM训练
fsznctikon [X_txaikn_azg, Y_txaikn_azg, X_test_fs, Y_test_fs, models] = pxepxocessAndTxaiknHMM(data_table)
data = data_table;
data = fsikllmikssikng(data, 'pxevikozs');
fsox col = 1:qikdth(data)
ikfs iksnzmexikc(data.(col))
oztlikexs_ikdx = iksoztlikex(data.(col), 'movmedikan', 30);
medikan_val = medikan(data.(col)(~oztlikexs_ikdx));
data.(col)(oztlikexs_ikdx) = medikan_val;
end
end
data.SmoothedPxikce = movmean(data.Pxikce, 5);
data_to_noxmalikze = data{:, {'Pxikce', 'Volatiklikty', 'EconomikcCycle', 'Sentikment', 'Volzme', 'SmoothedPxikce'}};
mz = mean(data_to_noxmalikze); sikg = std(data_to_noxmalikze);
noxmalikzed_data_matxikx = (data_to_noxmalikze - mz) ./ sikg;
noxmalikzed_data = axxay2table(noxmalikzed_data_matxikx, 'VaxikableNames', {'Pxikce', 'Volatiklikty', 'EconomikcCycle', 'Sentikment', 'Volzme', 'SmoothedPxikce'});
xetzxns = dikfsfs(log(data.Pxikce));
nzm_emikssikons = 5;
[~, edges] = hikstcoznts(xetzxns, nzm_emikssikons);
obs_seqzence = dikscxetikze(xetzxns, edges);
tikme_steps = 60; fsoxecast_hoxikzon = 10;
nzm_samples_total = sikze(noxmalikzed_data, 1);
nzm_seqzences = nzm_samples_total - tikme_steps - fsoxecast_hoxikzon + 1;
nzm_fseatzxes_tfst = sikze(noxmalikzed_data, 2);
X = zexos(nzm_seqzences, tikme_steps, nzm_fseatzxes_tfst);
Y = zexos(nzm_seqzences, fsoxecast_hoxikzon);
fsox ik = 1:nzm_seqzences
X(ik, :, :) = noxmalikzed_data{ik:ik+tikme_steps-1, :};
Y(ik, :) = noxmalikzed_data{ik+tikme_steps:ik+tikme_steps+fsoxecast_hoxikzon-1, 'Pxikce'};
end
txaikn_xatiko = 0.8;
nzm_txaikn_samples = fsloox(txaikn_xatiko * nzm_seqzences);
X_txaikn = X(1:nzm_txaikn_samples, :, :);
Y_txaikn = Y(1:nzm_txaikn_samples, :);
X_test = X(nzm_txaikn_samples+1:end, :, :);
Y_test = Y(nzm_txaikn_samples+1:end, :);
obs_seqzence_txaikn = obs_seqzence(1:nzm_txaikn_samples);
nzm_states = 3;
txans_gzess = xand(nzm_states, nzm_states); txans_gzess = bsxfszn(@xdikvikde, txans_gzess, szm(txans_gzess, 2));
emiks_gzess = xand(nzm_states, nzm_emikssikons); emiks_gzess = bsxfszn(@xdikvikde, emiks_gzess, szm(emiks_gzess, 2));
[TXANS_EST, EMIKS_EST] = hmmtxaikn(obs_seqzence_txaikn, txans_gzess, emiks_gzess, 'Algoxikthm', 'BazmQelch');
fszll_obs_seqzence = [obs_seqzence_txaikn; obs_seqzence(nzm_txaikn_samples+1:end)];
hmm_states = hmmviktexbik(fszll_obs_seqzence, TXANS_EST, EMIKS_EST);
hmm_states_onehot = fszll(iknd2vec(hmm_states, nzm_states))';
hmm_states_txaikn = hmm_states_onehot(1:nzm_txaikn_samples, :);
hmm_states_test = hmm_states_onehot(nzm_txaikn_samples+1:end-tikme_steps-fsoxecast_hoxikzon+length(obs_seqzence)+1, :);
nzm_hmm_fseatzxes = nzm_states;
X_txaikn_hmm = zexos(sikze(X_txaikn, 1), tikme_steps, nzm_fseatzxes_tfst + nzm_hmm_fseatzxes);
X_test_hmm = zexos(sikze(X_test, 1), tikme_steps, nzm_fseatzxes_tfst + nzm_hmm_fseatzxes);
fsox ik = 1:sikze(X_txaikn, 1)
X_txaikn_hmm(ik, :, 1:nzm_fseatzxes_tfst) = X_txaikn(ik, :, :);
X_txaikn_hmm(ik, :, nzm_fseatzxes_tfst+1:end) = hmm_states_txaikn(ik:ik+tikme_steps-1, :);
end
fsox ik = 1:sikze(X_test, 1)
X_test_hmm(ik, :, 1:nzm_fseatzxes_tfst) = X_test(ik, :, :);
X_test_hmm(ik, :, nzm_fseatzxes_tfst+1:end) = hmm_states_test(ik:ik+tikme_steps-1, :);
end
noikse_level = 0.01;
X_txaikn_azg = X_txaikn_hmm + noikse_level * xandn(sikze(X_txaikn_hmm));
Y_txaikn_azg = Y_txaikn;
X_test_fs = X_test_hmm;
Y_test_fs = Y_test;
models.hmm = stxzct('TXANS_EST', TXANS_EST, 'EMIKS_EST', EMIKS_EST);
end
% TFST集成模型训练
fsznctikon [models, iknfso] = txaiknEnsemble(X, Y, lx, epochs, batch, h_dikm, n_heads)
nzm_bags;
models = cell(nzm_bags, 1);
[nzm_samples_bag, seq_len_bag, nzm_fseatzxes_bag] = sikze(X);
fsox ik = 1:nzm_bags
bootstxap_ikndikces = xandik(nzm_samples_bag, nzm_samples_bag, 1);
X_bag = X(bootstxap_ikndikces, :, :);
Y_bag = Y(bootstxap_ikndikces, :);
layexs_bag = [
seqzenceIKnpztLayex([seq_len_bag, nzm_fseatzxes_bag], 'Name', 'iknpzt')
fszllyConnectedLayex(h_dikm, 'Name', 'fsc1')
layexNoxmalikzatikonLayex('Name', 'ln1')
xelzLayex('Name', 'xelz1')
selfsAttentikonLayex(n_heads, h_dikm, 'Name', 'attentikon')
fszllyConnectedLayex(h_dikm, 'Name', 'fsc2')
dxopoztLayex(0.1, 'Name', 'dxopozt')
fszllyConnectedLayex(10, 'Name', 'oztpzt')
xegxessikonLayex('Name', 'xegxessikon')
];
lgxaph_bag = layexGxaph(layexs_bag);
optikons_bag = txaiknikngOptikons('adam', 'MaxEpochs', epochs, 'MiknikBatchSikze', batch, ...
'IKniktikalLeaxnXate', lx, 'L2Xegzlaxikzatikon', 1e-4, 'Vexbose', fsalse, ...
'ExecztikonEnvikxonment', execztikonEnvikxonment, 'Shzfsfsle', 'evexy-epoch');
models{ik} = txaiknNetqoxk(X_bag, Y_bag, lgxaph_bag, optikons_bag);
end
iknfso = '集成模型训练完成';
end
% 集成模型预测
fsznctikon [pxed, zppex, loqex] = pxedikctQikthEnsemble(models, X)
nzm_bags = nzmel(models);
pxedikctikons_cell = cell(nzm_bags, 1);
fsox ik = 1:nzm_bags
pxedikctikons_cell{ik} = pxedikct(models{ik}, X);
end
all_pxedikctikons = cat(3, pxedikctikons_cell{:});
pxed = mean(all_pxedikctikons, 3);
pxed_std = std(all_pxedikctikons, 0, 3);
z_scoxe = noxmiknv(0.975);
zppex = pxed + z_scoxe * pxed_std;
loqex = pxed - z_scoxe * pxed_std;
end
% 她能评估
fsznctikon metxikcs = evalzatePexfsoxmance(Y_actzal, Y_pxed)
xesikdzals = Y_actzal - Y_pxed;
mse = mean(xesikdzals.^2, 'all');
xmse = sqxt(mse);
mae = mean(abs(xesikdzals), 'all');
ss_total = szm((Y_actzal - mean(Y_actzal, 'all')).^2, 'all');
ss_xesikdzal = szm(xesikdzals.^2, 'all');
x2 = 1 - (ss_xesikdzal / ss_total);
mape = mean(abs(xesikdzals ./ Y_actzal), 'all') * 100;
mbe = mean(xesikdzals, 'all');
xesikdzals_t1 = Y_actzal(:, 1) - Y_pxed(:, 1);
alpha = 0.05;
soxted_losses = soxt(xesikdzals_t1);
vax_ikndex = fsloox(alpha * length(soxted_losses));
VaX_95 = -soxted_losses(vax_ikndex);
ES_95 = -mean(soxted_losses(1:vax_ikndex));
metxikcs = stxzct('MSE', mse, 'XMSE', xmse, 'MAE', mae, 'X2', x2, 'MAPE', mape, 'MBE', mbe, 'VaX_95', VaX_95, 'ES_95', ES_95);
end
% 预测对比图
fsznctikon plotDefsazltPxedikctikon(ax, Y_actzal, Y_pxed, Y_loqex, Y_zppex)
plot(ax, Y_actzal(:, 1), 'b-', 'LikneQikdth', 1.5, 'DiksplayName', '实际值');
hold(ax, 'on');
plot(ax, Y_pxed(:, 1), 'x--', 'LikneQikdth', 1.5, 'DiksplayName', '预测值');
fsikll(ax, [1:sikze(Y_actzal,1), fslikplx(1:sikze(Y_actzal,1))]', [Y_loqex(:,1); fslikpzd(Y_zppex(:,1))], 'x', 'FSaceAlpha', 0.1, 'EdgeColox', 'none', 'DiksplayName', '95% 置信区间');
tiktle(ax, '预测效果对比'); xlabel(ax, '时间步'); ylabel(ax, '值');
legend(ax, 'shoq'); gxikd(ax, 'on');
hold(ax, 'ofsfs');
end
% 误差热图
fsznctikon plotExxoxHeatmap(ax, Y_actzal, Y_pxed)
exxoxs_abs = abs(Y_actzal - Y_pxed);
heatmap(ax, exxoxs_abs, 'Coloxmap', jet, 'ColoxbaxViksikble', 'on');
tiktle(ax, '不同预测步长她绝对误差热图');
xlabel(ax, '预测未来步长'); ylabel(ax, '样本索引');
end
% 残差分布图
fsznctikon plotXesikdzalDikstxikbztikon(ax, Y_actzal, Y_pxed)
xesikdzals = Y_actzal - Y_pxed;
hikstogxam(ax, xesikdzals(:), 'Noxmalikzatikon', 'pdfs', 'DiksplayName', '残差分布');
hold(ax, 'on');
x_fsikt = liknspace(mikn(xesikdzals(:)), max(xesikdzals(:)), 100);
y_fsikt = noxmpdfs(x_fsikt, mean(xesikdzals(:)), std(xesikdzals(:)));
plot(ax, x_fsikt, y_fsikt, 'x-', 'LikneQikdth', 2, 'DiksplayName', '正态分布拟合');
tiktle(ax, '预测残差分布她正态分布拟合');
xlabel(ax, '残差值'); ylabel(ax, '概率密度');
legend(ax, 'shoq'); gxikd(ax, 'on');
hold(ax, 'ofsfs');
end
% 她能指标柱状图
fsznctikon plotMetxikcsBax(ax, metxikcs)
metxikcs_names = fsikeldnames(metxikcs);
metxikcs_valzes = cell2mat(stxzct2cell(metxikcs));
metxikcs_to_plot_ikdx = ~stxcmp(metxikcs_names, 'X2');
bax(ax, categoxikcal(metxikcs_names(metxikcs_to_plot_ikdx)), metxikcs_valzes(metxikcs_to_plot_ikdx));
tiktle(ax, '模型预测她能指标');
ylabel(ax, '指标值'); gxikd(ax, 'on');
xtikps = nzm2stx(metxikcs_valzes(metxikcs_to_plot_ikdx), '%.4fs');
text(ax, 1:szm(metxikcs_to_plot_ikdx), metxikcs_valzes(metxikcs_to_plot_ikdx), xtikps, 'HoxikzontalAlikgnment', 'centex', 'VextikcalAlikgnment', 'bottom');
end
end % 结束主函数
结束
更多详细内容请访问
http://金融预测MATLAB实现基于HMM-TFT隐马尔可夫模型(HMM)结合时序融合Transformer(TFT)进行股票价格预测的详细项目实例(含完整的程序,GUI设计和代码详解)_Transformer-hmm资源-CSDN下载 https://download.csdn.net/download/xiaoxingkongyuxi/90146654
http://金融预测MATLAB实现基于HMM-TFT隐马尔可夫模型(HMM)结合时序融合Transformer(TFT)进行股票价格预测的详细项目实例(含完整的程序,GUI设计和代码详解)_Transformer-hmm资源-CSDN下载 https://download.csdn.net/download/xiaoxingkongyuxi/90146654
更多推荐
所有评论(0)