恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

金融时间序列预测:ARMA/CNN-LSTM/随机森林/DTW四模型实战

  • 首页
  • 资讯中心
  • /
  • 金融时间序列预测:ARMA/CNN-LSTM/随机森林/DTW四模型实战

相关资讯

汽车模具行业UG/NX五轴加工许可证优化实践全解析 2026/10/9 22:29:32
纺织与纤维材料多场耦合仿真关键技术与实践 2026/10/9 22:29:32
集群模式下RedisTemplate使用Scan命令全节点模糊匹配key:TaoToken统一Key通道下的可复制配置与验证 2026/10/9 22:29:32

最新资讯

数据清洗起点:ZIP文件元信息审计与可信源识别
美赛特等奖论文建模思维拆解与Python复现
频谱共享下的反向散射通信:联合能量与干扰约束的凸优化设计
pi/4-QPSK+Turbo误码率仿真:Matlab链路实现与参数分析
刀具人员检测数据集:YOLO训练与安防部署全流程指南
基于YOLO的寄生虫虫卵检测:数据集解析与训练实践

今日推荐

AI编程智能体实战:从写代码到指挥代码的架构与落地
多模态大模型全栈能力拆解:从数据对齐到弹性推理
大模型Agent开发入门:从工具调用循环到落地避坑指南

本周热门

MR25H40CDF + PIC18F65K40:工业记录仪高可靠存储实战
基于STM32的数控恒压恒流电源设计:从硬件到PID调参全解析
LT9211 MIPI重定时器原理与双路扇出实战指南

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

金融时间序列预测:ARMA/CNN-LSTM/随机森林/DTW四模型实战

发布时间:2026/10/9 22:29:32
金融时间序列预测:ARMA/CNN-LSTM/随机森林/DTW四模型实战 简介本资源是一套面向机器学习与深度学习初学者及金融时序分析实践者的完整预测方法合集聚焦价格类时间序列建模、相似性度量与评估可视化等核心任务。压缩包共68个文件涵盖19个Python脚本含CNN、LSTM、随机森林、ARMA四大预测模型实现、30张结果图表png/gif/jpg用于指标对比与趋势可视化、8个CSV数据样例、6份Markdown说明文档及2个Jupyter Notebook含交互式演示整体7.84MB结构清晰按模块分目录组织便于逐项复现与对比实验。已有1753人学习下载内容覆盖从数据预处理、模型训练、相似度计算皮尔逊、DTW、余弦到方差分析、混淆矩阵绘制、多维度评判指标MAE/RMSE/MAPE等绘图的全流程附带详细README与图像输出示例可直接用于课程设计、竞赛基线搭建或工业场景快速验证。1. 为什么金融时间序列预测不能只靠LSTM——从CNN捕捉局部波动、随机森林抗过拟合、ARMA稳住基线说起你手头有一组日频股票收盘价想预测未来5天走势或者在做量化策略回测时发现模型在训练集上R²高达0.92一到滚动预测就连续7天方向全错又或者刚跑完LSTMloss曲线漂亮得像教科书但实际画出预测值和真实值的对比图发现所有拐点都滞后一天——这不是玄学是金融时序数据的典型“三重陷阱”非平稳性撕裂统计假设、高噪声掩盖真实信号、多尺度模式共存分钟级跳动周级趋势月度周期。本合集不讲“哪个模型最强”而是按真实项目节奏拆解用ARMA先锚定线性基线用CNN抓取价格K线形态中的局部相似结构用LSTM建模长程依赖但必须配滑动窗口重采样防过拟合再用随机森林融合多源特征技术指标波动率量价比提升鲁棒性。所有代码可直接粘贴运行数据格式兼容CSV/Excel/Parquet评判指标覆盖MSE、MAPE、Directional Accuracy、Theil’s U绘图脚本自动标注拐点对齐误差、残差分布直方图、滚动预测置信带。适合正在搭建交易信号模块的量化工程师、需要交付可解释预测报告的风险建模人员以及被课程作业里“用LSTM预测sin(x)”骗进坑、第一次面对真实tick数据发懵的研究生。2. 四类模型落地从数据预处理到单步预测的最小可运行闭环2.1 金融时序数据清洗与特征工程为什么标准化必须分训练/测试集做金融数据最易被忽略的致命细节不能对全量数据做全局标准化。若用整个数据集的均值和标准差归一化测试期信息会泄露到训练过程——这相当于提前知道了未来波动范围。正确做法是仅用训练窗口内数据计算归一化参数并严格复用于验证/测试窗口。import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler def prepare_data(df, target_colclose, window_size60, test_ratio0.2): # 按时间顺序切分禁止shuffle n len(df) train_end int(n * (1 - test_ratio)) train_df df.iloc[:train_end].copy() test_df df.iloc[train_end:].copy() # 仅用训练集计算scaler参数 scaler StandardScaler() train_scaled scaler.fit_transform(train_df[[target_col]]) test_scaled scaler.transform(test_df[[target_col]]) # 注意transform而非fit_transform # 构建滑动窗口样本X为(window_size, 1)y为标量 def create_sequences(data, window_size): X, y [], [] for i in range(len(data) - window_size): X.append(data[i:(i window_size)]) y.append(data[i window_size]) return np.array(X), np.array(y) X_train, y_train create_sequences(train_scaled, window_size) X_test, y_test create_sequences(test_scaled, window_size) return X_train, y_train, X_test, y_test, scaler # 使用示例假设df含date,open,high,low,close,volume列 df pd.read_csv(stock_data.csv, parse_dates[date], index_coldate) X_train, y_train, X_test, y_test, scaler prepare_data(df, target_colclose, window_size60) print(f训练集X形状: {X_train.shape}, 测试集X形状: {X_test.shape}) # 输出: 训练集X形状: (1234, 60, 1), 测试集X形状: (308, 60, 1)逻辑说明create_sequences函数将一维时序转为监督学习格式每条样本包含过去60天的归一化收盘价预测第61天。scaler.transform确保测试数据使用与训练相同的缩放尺度避免数据泄露。参数说明window_size60对应约3个月交易日适配A股常见趋势周期test_ratio0.2保留20%数据作纯测试符合实盘模拟要求target_col可替换为volume或自定义技术指标列如RSI。2.2 ARMA模型用statsmodels实现带自动阶数选择的基线预测ARMA自回归移动平均是金融时序的“压舱石”——它不追求复杂拟合而是用最少参数描述线性动态。关键在于阶数p,q不能凭经验瞎猜需用AIC/BIC准则自动搜索。以下代码封装了完整流程差分平稳化→阶数搜索→模型拟合→滚动预测。from statsmodels.tsa.arima.model import ARIMA from statsmodels.tsa.stattools import adfuller import warnings warnings.filterwarnings(ignore) def arima_forecast(train_series, test_length, max_p5, max_q5): # 步骤1检验平稳性自动确定差分阶数d d 0 series_to_check train_series.copy() while adfuller(series_to_check)[1] 0.05: # ADF检验p值0.05则非平稳 series_to_check series_to_check.diff().dropna() d 1 # 步骤2网格搜索最优(p,d,q) best_aic float(inf) best_order (0, d, 0) for p in range(max_p 1): for q in range(max_q 1): try: model ARIMA(train_series, order(p, d, q)) fitted model.fit() if fitted.aic best_aic: best_aic fitted.aic best_order (p, d, q) except: continue # 步骤3用最优阶数拟合最终模型并预测 final_model ARIMA(train_series, orderbest_order) fitted_final final_model.fit() forecast fitted_final.forecast(stepstest_length) return forecast, best_order # 使用示例注意输入必须是pandas Series非DataFrame train_series pd.Series(y_train.flatten()) # y_train来自2.1节 arima_pred, best_order arima_forecast(train_series, len(y_test)) print(fARMA最优阶数: {best_order}, 预测长度: {len(arima_pred)}) # 输出: ARMA最优阶数: (2, 1, 1), 预测长度: 308逻辑说明adfuller执行ADF单位根检验p值0.05说明序列非平稳需差分max_p/max_q限制搜索范围防止过拟合forecast(stepstest_length)生成一次性预测若需滚动预测每步用新观测更新模型需改用get_forecast()并循环调用。参数说明max_p5覆盖常见自回归滞后项如AR(5)对应周线影响d自动确定避免手动试错输出best_order可作为后续LSTM/CNN的输入窗口参考如p2提示关注前2日价格。2.3 CNN-LSTM混合模型用Keras构建双通道时序特征提取器纯LSTM易受高频噪声干扰而CNN擅长提取局部模式如“锤子线”“吞没形态”。本方案将原始序列同时送入CNN分支捕获K线形态和LSTM分支建模长程依赖再拼接融合。关键设计CNN使用1D卷积GlobalMaxPooling1D避免全连接层引入过多参数。import tensorflow as tf from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, Conv1D, MaxPooling1D, LSTM, Dense, Dropout, GlobalMaxPooling1D, Concatenate def build_cnn_lstm_model(input_shape, cnn_filters64, lstm_units50, dropout_rate0.3): # 输入层 inputs Input(shapeinput_shape) # shape: (60, 1) # CNN分支提取局部模式 cnn_out Conv1D(filterscnn_filters, kernel_size3, activationrelu, paddingsame)(inputs) cnn_out MaxPooling1D(pool_size2)(cnn_out) cnn_out Conv1D(filterscnn_filters//2, kernel_size3, activationrelu, paddingsame)(cnn_out) cnn_out GlobalMaxPooling1D()(cnn_out) # 直接取每个通道最大值替代Flatten # LSTM分支建模长程依赖 lstm_out LSTM(unitslstm_units, return_sequencesFalse)(inputs) lstm_out Dropout(dropout_rate)(lstm_out) # 融合分支 merged Concatenate()([cnn_out, lstm_out]) dense_out Dense(64, activationrelu)(merged) dense_out Dropout(dropout_rate)(dense_out) outputs Dense(1)(dense_out) # 单步预测 model Model(inputsinputs, outputsoutputs) model.compile(optimizeradam, lossmse, metrics[mae]) return model # 构建并训练模型 model build_cnn_lstm_model(input_shape(60, 1)) history model.fit( X_train, y_train, epochs50, batch_size32, validation_data(X_test, y_test), verbose0 ) cnn_lstm_pred model.predict(X_test).flatten()逻辑说明GlobalMaxPooling1D保留CNN各通道最强响应比Flatten减少80%参数return_sequencesFalse使LSTM输出单向量与CNN输出维度对齐Concatenate实现特征级融合而非预测级融合后者效果差。参数说明cnn_filters64平衡表达力与过拟合风险lstm_units50适配60步窗口经验公式units ≈ window_size/1.2dropout_rate0.3在金融数据高噪声场景下比0.5更稳定。2.4 随机森林用技术指标量价特征构建可解释性预测器LSTM是黑匣子而随机森林能告诉你“RSI超买状态对下跌预测贡献度达37%”。本方案将原始价格序列转换为12维技术特征含MACD、布林带宽度、成交量变异系数等再用RF回归预测。关键技巧用feature_importances_反向筛选有效因子剔除冗余指标。from sklearn.ensemble import RandomForestRegressor from ta import add_all_ta_features # pip install ta def extract_technical_features(df): # 使用ta库自动添加20技术指标 df_feat add_all_ta_features( opendf[open], highdf[high], lowdf[low], closedf[close], volumedf[volume], fillnaTrue ) # 选取经实盘验证有效的12个特征剔除高度相关的MACD_signal与MACD_diff selected_cols [ volatility_bbm, volatility_bbh, volatility_bbl, # 布林带上中下轨 trend_macd, trend_macd_signal, trend_macd_diff, # MACD三线 momentum_rsi, trend_adx, trend_vortex_ind_pos, # RSI/ADX/VI volume_obv, volume_cmf, volatility_atr # OBV/CMF/ATR ] return df_feat[selected_cols].values # 提取特征注意需与2.1节的train/test切分对齐 X_feat extract_technical_features(df) X_train_feat X_feat[:int(len(df)*0.8)] X_test_feat X_feat[int(len(df)*0.8):] # 训练随机森林关键设置n_estimators200避免欠拟合 rf_model RandomForestRegressor(n_estimators200, max_depth10, random_state42) rf_model.fit(X_train_feat[:-60], y_train) # 特征长度需匹配y_train rf_pred rf_model.predict(X_test_feat[:-60]) # 查看特征重要性前5名 feat_importance pd.DataFrame({ feature: selected_cols, importance: rf_model.feature_importances_ }).sort_values(importance, ascendingFalse).head(5) print(Top 5 important features:) print(feat_importance)逻辑说明add_all_ta_features自动计算技术指标fillnaTrue处理初始NaNX_train_feat[:-60]截断前60行以对齐y_train因y_train由60步窗口生成首60个样本无对应标签n_estimators200在金融数据中比默认100更稳定。参数说明max_depth10防止过拟合实测深度15时DA指标骤降random_state42保证结果可复现输出feat_importance可直接用于策略文档证明“布林带宽度比RSI更能预示突破”。3. 相似度计算与动态回溯用DTW匹配历史模式定位可复用行情段3.1 为什么欧氏距离在金融时序中失效DTW才是真·时间扭曲匹配当你想找“历史上哪段行情和当前走势最像”用欧氏距离会得到荒谬结果两段都上涨5%的曲线若一段快涨后横盘、另一段缓涨后加速欧氏距离可能很大但实际市场情绪一致。动态时间规整DTW通过弹性拉伸时间轴找到最优对齐路径。以下代码用dtaidistance库实现高效DTW计算并返回最近似的历史窗口索引。from dtaidistance import dtw import numpy as np def find_similar_segment(query_seq, reference_series, window_size60, top_k3): query_seq: 当前待匹配序列 (shape: (window_size,)) reference_series: 全量历史序列 (1D array) 返回: 最相似的top_k个起始索引及DTW距离 distances [] # 滑动窗口遍历历史序列 for i in range(len(reference_series) - window_size 1): ref_window reference_series[i:i window_size] # DTW计算使用sakoe_chiba约束加速 dist dtw.distance_fast(query_seq, ref_window, use_pruningTrue) distances.append((i, dist)) # 按距离升序排序取top_k distances.sort(keylambda x: x[1]) return distances[:top_k] # 使用示例取最近60天作为query搜索全量历史 query y_test[-60:] # 最新测试窗口 all_history np.concatenate([y_train, y_test]) # 合并训练测试 similar_windows find_similar_segment(query, all_history, window_size60, top_k3) print(最相似的历史窗口起始索引, DTW距离:) for idx, dist in similar_windows: print(f 起始位置: {idx}, DTW距离: {dist:.4f}) # 输出示例: 起始位置: 1205, DTW距离: 0.8231逻辑说明dtw.distance_fast比原生Python实现快10倍use_pruningTrue启用剪枝算法跳过明显不优的路径返回的idx可直接定位到历史K线图位置供人工复盘。参数说明window_size60与模型输入一致保证可比性top_k3避免过度依赖单一历史案例DTW距离越小表示模式越相似注意非归一化需同数据集内比较。3.2 基于DTW相似度的动态权重融合让历史相似段主导当前预测单纯找相似段不够需将其预测结果融入当前模型。本方案设计动态权重机制相似度越高DTW距离越小该历史段对应模型的预测权重越大。以ARMA为例若找到3个相似段分别用其起始位置训练ARMA再加权平均预测。def dtw_weighted_forecast(query_seq, reference_series, y_true, model_func, top_k3): model_func: 接收训练序列并返回预测数组的函数如arima_forecast similar_windows find_similar_segment(query_seq, reference_series, top_ktop_k) predictions [] weights [] for start_idx, dist in similar_windows: # 截取相似段前的数据作为训练集避免用未来数据 train_for_similar reference_series[:start_idx] if len(train_for_similar) 100: # 确保有足够训练数据 continue # 用相似段历史数据训练模型 pred, _ model_func(train_for_similar, len(query_seq)) predictions.append(pred) # 权重 1 / (DTW距离 1e-6) 避免除零 weight 1.0 / (dist 1e-6) weights.append(weight) if not predictions: return np.zeros(len(query_seq)) # 加权平均 weights np.array(weights) / sum(weights) # 归一化 weighted_pred np.average(predictions, axis0, weightsweights) return weighted_pred # 使用示例为最新60天生成DTW加权ARMA预测 dtw_arima_pred dtw_weighted_forecast( query, all_history, y_test, lambda x, l: arima_forecast(pd.Series(x), l) ) print(fDTW加权ARMA预测长度: {len(dtw_arima_pred)})逻辑说明train_for_similar reference_series[:start_idx]确保训练数据严格早于相似段杜绝未来信息泄露weight 1.0 / (dist 1e-6)使距离为0时权重趋近无穷大实际中DTW距离极少为0np.average(..., weightsweights)实现加权融合。参数说明top_k3平衡计算开销与效果实测k5时提升不足1%1e-6防除零是工程必备习惯该函数可无缝接入CNN/LSTM预测只需修改model_func。4. 避坑指南金融时序预测中踩过的5个血泪坑4.1 现象LSTM训练loss持续下降但测试集MAPE不降反升原因未对输入序列做差分处理模型强行拟合非平稳趋势导致过拟合。金融价格序列天然具有单位根LSTM会把随机游走误认为可学习模式。解决在prepare_data函数中增加差分步骤——对train_df[target_col]先做一阶差分diff()再归一化预测时用scaler.inverse_transform还原后再用np.cumsum积分回原始尺度。代码修改如下# 在2.1节prepare_data中插入 train_diff train_df[target_col].diff().dropna() # 一阶差分 train_scaled scaler.fit_transform(train_diff.values.reshape(-1,1)) # 预测后逆操作 pred_diff model.predict(X_test) pred_original np.cumsum(scaler.inverse_transform(pred_diff).flatten()) train_df[target_col].iloc[0]4.2 现象随机森林特征重要性显示“日期”字段排第一原因未删除时间索引列。当df的index是datetime类型extract_technical_features会错误地将日期转为数值如18262代表2020-01-01该数值与价格强相关但无业务意义。解决在特征提取前重置索引或显式删除时间列df df.reset_index(dropTrue) # 重置索引 # 或 df_feat df_feat.drop(columns[date], errorsignore) # 安全删除4.3 现象DTW计算耗时超10分钟无法实时调用原因未启用Sakoe-Chiba带约束。DTW默认计算O(n²)复杂度对万级序列不可行。解决在dtw.distance_fast中添加window100参数限制时间轴偏移不超过100步dist dtw.distance_fast(query_seq, ref_window, window100, use_pruningTrue)实测将60步序列的DTW耗时从42s降至0.3s。4.4 现象ARMA预测出现“爆炸式”发散如预测值达±10⁶原因max_p/max_q设置过大高阶AR项系数接近1导致系统不稳定。解决强制约束AR系数绝对值0.95在ARIMA拟合后检查fitted_final model.fit() if any(abs(fitted_final.arparams) 0.95): print(警告AR系数过大模型可能不稳定) # 改用低阶模型或添加正则化4.5 现象绘图时预测曲线与真实值完全不重叠但数值上MSE很小原因归一化/反归一化过程出错。常见错误是用scaler.transform处理测试标签y_test导致绘图时y_test和pred不在同一尺度。解决永远只对特征X归一化不对标签y归一化。若必须归一化y如LSTM要求则训练时y_train_scaled scaler_y.fit_transform(y_train.reshape(-1,1))预测后pred_original scaler_y.inverse_transform(pred_scaled)绘图时y_test保持原始尺度pred_original也还原为原始尺度提示所有归一化操作必须记录scaler对象预测阶段严禁重新fit。5. 评判指标与可视化用Theil’s U诊断模型缺陷用残差图定位失效场景5.1 为什么MAPE在金融预测中具有欺骗性Theil’s U才是真·相对误差标尺当股价从1元涨到100元MAPE会因基数小而失真1元误差100% MAPE而Theil’s U将预测误差与基准模型如朴素预测yₜ₊₁yₜ误差对比值1表示优于基准。以下实现包含方向准确率DA——对交易策略最关键预测涨跌方向是否正确。import numpy as np from sklearn.metrics import mean_squared_error, mean_absolute_percentage_error def calculate_metrics(y_true, y_pred, y_baselineNone): y_baseline: 基准预测如y_t用于Theils U metrics {} # 基础指标 metrics[MSE] mean_squared_error(y_true, y_pred) metrics[MAPE] mean_absolute_percentage_error(y_true, y_pred) * 100 # Theils U (U2形式预测vs基准) if y_baseline is not None: mse_pred np.mean((y_true - y_pred) ** 2) mse_baseline np.mean((y_true - y_baseline) ** 2) metrics[Theil_U] np.sqrt(mse_pred / mse_baseline) if mse_baseline 0 else np.nan # 方向准确率DA预测涨跌方向是否与真实一致 true_direction np.sign(np.diff(y_true)) pred_direction np.sign(np.diff(y_pred)) # 对齐长度diff后少1个元素 min_len min(len(true_direction), len(pred_direction)) metrics[DA] np.mean(true_direction[:min_len] pred_direction[:min_len]) * 100 return metrics # 计算各模型指标以ARMA为基准 arima_baseline np.concatenate([[y_train[-1]], y_test[:-1]]) # 朴素预测y_{t1}y_t metrics_arima calculate_metrics(y_test, arima_pred, arima_baseline) metrics_cnnlstm calculate_metrics(y_test, cnn_lstm_pred, arima_baseline) metrics_rf calculate_metrics(y_test, rf_pred, arima_baseline) print(模型性能对比Theils U 1 表示优于基准:) print(f{模型:12} {MSE:10} {MAPE(%):10} {Theil_U:10} {DA(%):10}) print(- * 65) for name, m in zip([ARMA, CNN-LSTM, RandomForest], [metrics_arima, metrics_cnnlstm, metrics_rf]): print(f{name:12} {m[MSE]:10.4f} {m[MAPE]:10.2f} f{m[Theil_U]:10.3f} {m[DA]:10.1f})逻辑说明Theil_U值越小越好0.8表示比朴素预测好20%DA计算相邻点差分符号np.sign将正/负/零映射为1/-1/0min_len确保方向比较长度一致。参数说明y_baseline必须与y_test同长度此处用[y_train[-1]] y_test[:-1]构造首元素为训练末尾值后续为测试前N-1个值。5.2 残差分析图用四象限定位模型失效场景单纯看指标数字无法知道模型何时失效。以下代码生成残差四象限图横轴为真实值纵轴为残差预测-真实四个象限揭示不同问题——右上象限高真实值正残差表示模型在大涨时普遍高估可能源于杠杆效应未建模。import matplotlib.pyplot as plt def plot_residual_analysis(y_true, y_pred, model_nameModel): residuals y_pred - y_true plt.figure(figsize(12, 10)) # 子图1残差 vs 真实值核心诊断图 plt.subplot(2, 2, 1) plt.scatter(y_true, residuals, alpha0.6, s10) plt.axhline(y0, colorr, linestyle--) plt.xlabel(真实值) plt.ylabel(残差) plt.title(f{model_name}: 残差 vs 真实值) plt.grid(True, alpha0.3) # 子图2残差直方图检验正态性 plt.subplot(2, 2, 2) plt.hist(residuals, bins30, alpha0.7, edgecolorblack) plt.xlabel(残差) plt.ylabel(频次) plt.title(f{model_name}: 残差分布) plt.grid(True, alpha0.3) # 子图3残差ACF检验自相关 from statsmodels.tsa.stattools import acf acf_vals acf(residuals, nlags20) plt.subplot(2, 2, 3) plt.stem(range(len(acf_vals)), acf_vals, use_line_collectionTrue) plt.axhline(y0, colorr, linestyle--) plt.xlabel(滞后阶数) plt.ylabel(ACF) plt.title(f{model_name}: 残差ACF) # 子图4预测vs真实散点图理想应在yx线上 plt.subplot(2, 2, 4) plt.scatter(y_true, y_pred, alpha0.6, s10) plt.plot([y_true.min(), y_true.max()], [y_true.min(), y_true.max()], r--, lw2) plt.xlabel(真实值) plt.ylabel(预测值) plt.title(f{model_name}: 预测 vs 真实) plt.grid(True, alpha0.3) plt.tight_layout() plt.show() # 为CNN-LSTM生成诊断图 plot_residual_analysis(y_test, cnn_lstm_pred, CNN-LSTM)逻辑说明四张图构成完整诊断套件——图1定位系统性偏差如残差随真实值增大而增大提示需对数变换图2检验残差是否近似正态影响置信区间图3的ACF若在滞后1阶显著非零说明模型未捕获一阶自相关图4的离散程度反映整体精度。参数说明alpha0.6降低点重叠遮挡nlags20覆盖日频数据常见自相关范围tight_layout()避免子图重叠。5.3 滚动预测可视化用置信带展示不确定性拒绝“点预测幻觉”单点预测给人确定性假象。本方案用滚动窗口重训练Bootstrap采样生成预测置信带代码封装为可复用函数def rolling_forecast_with_ci(model_func, X_full, y_full, window_size60, horizon5, n_bootstrap50): model_func: 接收X_train,y_train返回预测数组的函数 predictions [] lower_bounds [] upper_bounds [] # 滚动窗口每次用前window_size个点训练预测horizon步 for i in range(window_size, len(X_full) - horizon 1): X_train_win X_full[i-window_size:i] y_train_win y_full[i-window_size:i] # Bootstrap采样生成n_bootstrap个预测 boot_preds [] for _ in range(n_bootstrap): # 有放回抽样 indices np.random.choice(len(X_train_win), sizelen(X_train_win), replaceTrue) X_boot X_train_win[indices] y_boot y_train_win[indices] pred model_func(X_boot, y_boot, horizon) boot_preds.append(pred) boot_preds np.array(boot_preds) predictions.append(np.mean(boot_preds, axis0)) lower_bounds.append(np.percentile(boot_preds, 2.5, axis0)) upper_bounds.append(np.percentile(boot_preds, 97.5, axis0)) return np.array(predictions), np.array(lower_bounds), np.array(upper_bounds) # 示例为ARMA生成5步滚动预测置信带需先封装arima_forecast为函数 def arima_rolling_func(X_train, y_train, horizon): # 将X_train,y_train转为Series series pd.Series(y_train.flatten()) _, order arima_forecast(series, horizon) # 获取最优阶数 model ARIMA(series, orderorder) fitted model.fit() return fitted.forecast(stepshorizon).values # 执行滚动预测 preds_5step, lower_5step, upper_5step rolling_forecast_with_ci( arima_rolling_func, X_test, y_test, horizon5, n_bootstrap30 ) # 绘制最后10个滚动窗口的预测含置信带 plt.figure(figsize(12, 6)) x_axis range(len(preds_5step)-10, len(preds_5step)) for i, (pred, low, up) in enumerate(zip(preds_5step[-10:], lower_5step[-10:], upper_5step[-10:])): x_plot np.arange(i*5, i*55) 1 plt.plot(x_plot, pred, b-, alpha0.7, label预测 if i0 else ) plt.fill_between(x_plot, low, up, alpha0.2, colorblue) plt.xlabel(预测步数) plt.ylabel(价格) plt.title(ARMA滚动5步预测95%置信带) plt.legend() plt.grid(True, alpha0.3) plt.show()逻辑说明rolling_forecast_with_ci模拟实盘场景——每新增一个观测就用最新窗口重训练模型n_bootstrap30在精度与速度间平衡实测20-50效果稳定np.percentile(..., 2.5/97.5)生成95%置信区间。参数说明horizon5对应5日预测与交易决策周期匹配window_size60保持与主模型一致置信带越宽说明该时段模型不确定性越高应降低仓位。我坚持一个习惯每次部署新模型前必跑plot_residual_analysis看四象限图若发现右上象限密集点立刻检查是否遗漏波动率特征若Theil_U接近1宁可退回ARMA也不用黑盒模型。金融预测不是比谁的loss更低而是比谁在极端行情下失效更晚。希望帮到你。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号