四模型并行预测股价:LR、LSTM、ARIMA与KNN融合实践

发布时间:2026/10/9 12:07:49
四模型并行预测股价:LR、LSTM、ARIMA与KNN融合实践 简介本资源是一套面向本科生与初学者的股价预测综合实践项目涵盖线性回归LR、长短期记忆网络LSTM、自回归积分滑动平均ARIMA及K近邻KNN等多种主流机器学习方法专为毕业设计、期末大作业及课程设计打造。项目提供完整可运行代码、详细注释、可视化分析图表及配套文档支持端到端数据预处理、模型训练、回测评估与结果展示新手亦能快速上手并理解各模型原理与适用场景。压缩包共31个文件含5个核心Python脚本如forecast.py、backtest.py、models.py、2个CSV行情数据、2个HTML交互图表、17张模型效果对比图含LSTM、ARIMA、Prophet等拟合曲线与残差分析以及README.md、requirements.txt等工程化支撑文件整体仅1.45MB轻量易部署。目前已有117人学习下载项目经严格调试功能完备、界面直观、结构清晰附带个股持有分析、月度资金曲线与收益率可视化等实用模块具备扎实的教学示范性与实际复现价值。1. 股价预测不是玄学为什么用 LR、LSTM、ARIMA、KNN 四种方法并行建模反而比单模型更稳你手头有一组日频股票收盘价数据想跑个预测——结果发现用 LSTM 训出来曲线很“丝滑”但一到跳空缺口就崩ARIMA 在平稳段误差小可遇到财报季突变直接失灵KNN 看似鲁棒却对最近三天的量价组合过度敏感把噪声当信号LR 更惨连趋势方向都常判反。这不是你调参不行而是股价本身不具备单一统计假设的刚性结构它既含长期记忆适合 LSTM又带短期自相关ARIMA 擅长还存在局部相似模式KNN 可捕获同时线性成分不可忽略LR 提供基线锚点。本项目不追求“最优单模型”而是构建一个四路并行、结果可比、误差可归因的预测框架每个模型独立训练、统一评估、输出带置信区间的区间预测最终用简单加权融合降低方差。适合刚接触金融时序的新手建立完整 pipeline 意识也适合有经验者快速验证新特征或替换某一路模型。所有代码在本地 CPU 即可跑通无需 GPU数据预处理与模型封装已解耦你改一行就能切模型、换股票、调窗口。2. 数据准备与特征工程从原始 OHLCV 到模型可吞食的张量2.1 原始数据清洗处理缺失、停牌、复权与异常值股价数据最常踩的第一个坑是直接拿交易所原始 CSV 开干。真实场景中你需要先解决三类硬伤停牌日填充不能简单前向填充会伪造交易信号应标记为NaN并在后续滑动窗口中自动剔除复权处理必须使用后复权post-adjusted价格否则分红送股导致的价格断层会彻底污染 ARIMA 的平稳性检验异常值过滤单日涨跌幅 15%非ST/科创板或成交量突增 5 倍以上需用scipy.stats.zscore检出并设为NaN而非删除——因为 LSTM 需要时间连续性。import pandas as pd import numpy as np from scipy import stats def load_and_clean_stock_data(file_path: str) - pd.DataFrame: df pd.read_csv(file_path, parse_dates[date], index_coldate) # 1. 强制后复权若原始列含 close_adj 优先用否则用 close 复权因子列 price_col close_adj if close_adj in df.columns else close df[price] df[price_col].ffill() # 后复权价已处理断层仅需前向填充极少数缺失 # 2. 标记停牌成交量为 0 或 NaN 且价格未变视为停牌 df[is_suspended] (df[volume] 0) | (df[volume].isna()) df.loc[df[is_suspended], [price, volume]] np.nan # 3. 异常值检测Z-score 4 z_scores np.abs(stats.zscore(df[[price, volume]].dropna())) outliers (z_scores 4).any(axis1) outlier_idx df.dropna(subset[price, volume]).index[outliers] df.loc[outlier_idx, [price, volume]] np.nan return df[[price, volume]].sort_index() # 示例调用 raw_df load_and_clean_stock_data(stock_600519.csv) # 贵州茅台示例 print(f原始记录数: {len(raw_df)}, 清洗后有效记录: {raw_df[price].count()})提示raw_df[price].count()是关键指标——若清洗后有效数据 原始 85%说明该股票噪音过大建议换标的或检查数据源质量。不要强行补全。2.2 构造多尺度特征不只是 lag而是「滞后滚动比率」三维组合LR 和 KNN 对特征敏感度高LSTM 虽能自动学习但喂高质量特征仍显著提升收敛速度与泛化性。我们不堆砌上百个技术指标只保留可解释、易复现、有经济含义的 12 维特征特征名计算方式用途说明price_lag1shift(1)最基础的自回归信息price_rtnpct_change(1)日收益率消除量纲vol_ma5rolling(5).mean()5日均量衡量流动性热度vol_ratiovolume / vol_ma5当前量能相对强度突破信号前置指标high_low_ratiohigh / low需原始OHLC当日波动率代理反映多空博弈烈度price_ma20rolling(20).mean()月线支撑/压力位参考price_dist_ma20(price - price_ma20) / price_ma20价格偏离月线程度超买超卖指示rsi_14100 - 100/(1 avg_up/avg_down)经典RSI但用ta库精确实现见下文# 安装 ta 库pip install ta from ta.momentum import RSIIndicator from ta.volatility import BollingerBands def build_features(df: pd.DataFrame, window_size: int 60) - pd.DataFrame: feat df.copy() # 基础滞后与收益率 feat[price_lag1] feat[price].shift(1) feat[price_rtn] feat[price].pct_change(1) # 滚动统计避免未来信息泄露全部用 closedleft feat[vol_ma5] feat[volume].rolling(5, closedleft).mean() feat[vol_ratio] feat[volume] / feat[vol_ma5] feat[price_ma20] feat[price].rolling(20, closedleft).mean() feat[price_dist_ma20] (feat[price] - feat[price_ma20]) / feat[price_ma20] # 技术指标需确保 ta 库版本 0.10.2 rsi_ind RSIIndicator(closefeat[price], window14, fillnaFalse) feat[rsi_14] rsi_ind.rsi() bb_ind BollingerBands(closefeat[price], window20, window_dev2, fillnaFalse) feat[bb_high] bb_ind.bollinger_hband() feat[bb_low] bb_ind.bollinger_lband() feat[bb_width] (feat[bb_high] - feat[bb_low]) / feat[price_ma20] # 布林带宽度归一化 # 目标变量预测未来第 1 天收盘价回归任务或涨跌方向分类任务 feat[target_price] feat[price].shift(-1) # 预测明日收盘价 feat[target_class] (feat[target_price] feat[price]).astype(int) # 1涨0跌 return feat feat_df build_features(raw_df) print(特征维度:, feat_df.shape[1], | 示例特征:, list(feat_df.columns[-5:]))注意所有rolling必须显式指定closedleft否则 pandas 默认closedboth会引入未来信息即用当天数据计算包含当天的均值这是金融时序建模最隐蔽的翻车点。2.3 滑动窗口切片为 LSTM 准备 (samples, timesteps, features)为其他模型准备 (samples, features)LSTM 输入是三维张量而 LR/KNN/ARIMA 接收二维表格。我们用统一窗口逻辑生成两套数据LSTM 输入取过去timesteps60天的全部特征12维预测第 61 天的target_price传统模型输入将同一 60 天窗口的最后一天所有特征即timesteps1的切片作为样本目标仍是第 61 天价格。def create_sequences( data: pd.DataFrame, target_col: str target_price, timesteps: int 60, feature_cols: list None ) - tuple: if feature_cols is None: feature_cols [c for c in data.columns if c not in [target_price, target_class]] X_lstm, y_lstm [], [] X_trad, y_trad [], [] # 确保目标列存在且无 NaN valid_mask ~data[target_col].isna() data_valid data[valid_mask].copy() for i in range(timesteps, len(data_valid)): # LSTM取 [i-timesteps : i] 共 timesteps 行 seq_X data_valid.iloc[i-timesteps:i][feature_cols].values seq_y data_valid.iloc[i][target_col] X_lstm.append(seq_X) y_lstm.append(seq_y) # 传统模型只取窗口最后一行的特征即第 i-1 行因目标是第 i 行 X_trad.append(data_valid.iloc[i-1][feature_cols].values) y_trad.append(seq_y) return ( np.array(X_lstm), np.array(y_lstm), np.array(X_trad), np.array(y_trad) ) X_lstm, y_lstm, X_trad, y_trad create_sequences( feat_df, timesteps60, feature_cols[price_lag1, price_rtn, vol_ratio, price_dist_ma20, rsi_14, bb_width] ) print(fLSTM 输入形状: {X_lstm.shape} → {X_lstm.shape[0]} 个样本, 每个含 60 步×6 特征) print(f传统模型输入形状: {X_trad.shape} → {X_trad.shape[0]} 个样本, 每个含 6 特征)血泪经验X_trad的构造必须用i-1行特征预测i行目标而不是i行特征预测i行目标——后者是数据穿越data leakage模型会在训练集上表现完美实盘必崩。3. 四模型并行训练LR、KNN、ARIMA、LSTM 的最小可行实现3.1 线性回归LR用 sklearn 实现但必须做标准化与残差诊断LR 不是“玩具模型”。在股价预测中它提供可解释的基线若 LR 的 R² 0.05说明数据噪声主导所有复杂模型都难有收益。关键步骤特征必须标准化StandardScaler否则量纲差异如price_dist_ma20在 ±0.1rsi_14在 0~100会让系数失真训练后必须画残差图若残差随预测值增大而扩散heteroscedasticity说明需对目标变量做对数变换。from sklearn.linear_model import LinearRegression from sklearn.preprocessing import StandardScaler from sklearn.metrics import r2_score, mean_absolute_error import matplotlib.pyplot as plt # 划分训练/测试按时间顺序禁用 shuffle split_idx int(0.8 * len(X_trad)) X_train_lr, X_test_lr X_trad[:split_idx], X_trad[split_idx:] y_train_lr, y_test_lr y_trad[:split_idx], y_trad[split_idx:] # 标准化 scaler_lr StandardScaler() X_train_scaled scaler_lr.fit_transform(X_train_lr) X_test_scaled scaler_lr.transform(X_test_lr) # 训练 lr_model LinearRegression() lr_model.fit(X_train_scaled, y_train_lr) # 预测 y_pred_lr lr_model.predict(X_test_scaled) # 评估 r2 r2_score(y_test_lr, y_pred_lr) mae mean_absolute_error(y_test_lr, y_pred_lr) print(fLR 测试集 R²: {r2:.4f}, MAE: {mae:.4f}) # 残差诊断图 residuals y_test_lr - y_pred_lr plt.figure(figsize(10, 4)) plt.subplot(1, 2, 1) plt.scatter(y_pred_lr, residuals, alpha0.5) plt.axhline(y0, colorr, linestyle--) plt.xlabel(Predicted Price) plt.ylabel(Residual) plt.title(Residual vs Fitted) plt.subplot(1, 2, 2) plt.hist(residuals, bins30, alpha0.7) plt.xlabel(Residual) plt.ylabel(Frequency) plt.title(Residual Distribution) plt.tight_layout() plt.show()参数说明StandardScaler的fit_transform必须只在训练集上调用测试集用transform—— 这是防止信息泄露的铁律。若残差图显示明显漏斗形应在create_sequences中对target_price做np.log1p变换并在预测后np.expm1还原。3.2 KNN用距离加权 特征缩放避免“最近邻”变成“最近噪声”KNN 在股价中有效是因为市场存在局部相似性如同样在年报前3天、量比2、RSI30 的形态后续走势常趋同。但直接KNeighborsRegressor(n_neighbors5)会失败原因未缩放特征导致price_dist_ma20±0.1被rsi_140~100完全淹没固定n_neighbors5在不同市场阶段牛市/熊市鲁棒性差未加权导致离得远的邻居和近的邻居投票权重一样。from sklearn.neighbors import KNeighborsRegressor from sklearn.model_selection import TimeSeriesSplit, GridSearchCV # 时间序列交叉验证非随机打乱 tscv TimeSeriesSplit(n_splits3) # 网格搜索在训练集上找最优 k 和权重 param_grid { n_neighbors: [3, 5, 7, 10], weights: [uniform, distance], p: [1, 2] # 曼哈顿 or 欧氏距离 } knn_model KNeighborsRegressor() grid_search GridSearchCV( knn_model, param_grid, cvtscv, scoringneg_mean_absolute_error, n_jobs-1 ) grid_search.fit(X_train_scaled, y_train_lr) # 注意这里用 LR 的训练标签因目标一致 print(KNN 最优参数:, grid_search.best_params_) best_knn grid_search.best_estimator_ y_pred_knn best_knn.predict(X_test_scaled) mae_knn mean_absolute_error(y_test_lr, y_pred_knn) print(fKNN 测试集 MAE: {mae_knn:.4f} (vs LR: {mae:.4f}))关键点TimeSeriesSplit是唯一合规的 CV 方式——它保证每次验证集都在训练集之后模拟真实预测场景。若用KFold模型会看到“未来”数据MAE 虚高 30%。3.3 ARIMA用 pmdarima 自动选参但必须手动验证平稳性与残差白噪声ARIMA 不是黑箱。pmdarima.auto_arima能省力但若跳过三步检验模型就是空中楼阁ADF 检验确认一阶差分后序列平稳p-value 0.05ACF/PACF 图目视判断p,q初值Ljung-Box 检验拟合后残差必须是白噪声p-value 0.05。import pmdarima as pm from statsmodels.tsa.stattools import adfuller from statsmodels.stats.diagnostic import acorr_ljungbox # 1. ADF 检验用原始 price 序列 adf_result adfuller(raw_df[price].dropna()) print(fADF Statistic: {adf_result[0]:.4f}, p-value: {adf_result[1]:.4f}) # 若 p 0.05需差分d1 # 2. 自动拟合 ARIMA限定搜索范围防过拟合 arima_model pm.auto_arima( raw_df[price].dropna(), start_p1, max_p3, start_q1, max_q3, d1, # 强制一阶差分 seasonalFalse, stepwiseTrue, suppress_warningsTrue, error_actionignore, n_jobs-1 ) print(ARIMA 最优阶数:, arima_model.order) # 如 (2,1,1) # 3. 残差白噪声检验 residuals_arima arima_model.resid() lb_test acorr_ljungbox(residuals_arima, lags[10], return_dfTrue) print(Ljung-Box p-value:, lb_test[lb_pvalue].iloc[0]) # 4. 预测未来 1 步对应 test 长度 y_pred_arima arima_model.predict(n_periodslen(y_test_lr)) mae_arima mean_absolute_error(y_test_lr, y_pred_arima) print(fARIMA 测试集 MAE: {mae_arima:.4f})避坑提醒auto_arima默认m0非季节性但 A 股存在明显月度效应如每月初资金面宽松若你研究的是月频数据必须设seasonalTrue, m12并增加max_P,max_Q。3.4 LSTM用 Keras 构建双层堆叠但 dropout 位置与早停策略决定成败LSTM 易过拟合。我们的最小可靠结构输入层LSTM(50, return_sequencesTrue, dropout0.2, recurrent_dropout0.2)第二层LSTM(30, dropout0.2, recurrent_dropout0.2)输出层Dense(1)关键recurrent_dropout必须 0否则循环连接过拟合early_stopping监控验证集 losspatience10。import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout from tensorflow.keras.callbacks import EarlyStopping # 划分 LSTM 数据同样按时间顺序 split_idx_lstm int(0.8 * len(X_lstm)) X_train_lstm, X_test_lstm X_lstm[:split_idx_lstm], X_lstm[split_idx_lstm:] y_train_lstm, y_test_lstm y_lstm[:split_idx_lstm], y_lstm[split_idx_lstm:] # 构建模型 model_lstm Sequential([ LSTM(50, return_sequencesTrue, dropout0.2, recurrent_dropout0.2, input_shape(X_lstm.shape[1], X_lstm.shape[2])), LSTM(30, dropout0.2, recurrent_dropout0.2), Dense(1) ]) model_lstm.compile(optimizeradam, lossmse, metrics[mae]) early_stopping EarlyStopping( monitorval_loss, patience10, restore_best_weightsTrue ) history model_lstm.fit( X_train_lstm, y_train_lstm, batch_size32, epochs100, validation_split0.2, callbacks[early_stopping], verbose0 ) y_pred_lstm model_lstm.predict(X_test_lstm).flatten() mae_lstm mean_absolute_error(y_test_lstm, y_pred_lstm) print(fLSTM 测试集 MAE: {mae_lstm:.4f}) # 绘制训练曲线 plt.figure(figsize(8, 4)) plt.plot(history.history[loss], labelTrain Loss) plt.plot(history.history[val_loss], labelVal Loss) plt.legend() plt.title(LSTM Training Loss) plt.show()玄学参数batch_size32是经验值——太小收敛慢太大易震荡recurrent_dropout0.2比dropout0.5更有效因它专门正则化循环连接而非输入连接。4. 避坑指南四个模型在股价预测中必踩的 5 个真实坑4.1 现象LSTM 训练 loss 下降快但测试 MAE 比 LR 还高原因输入数据未归一化。LSTM 对输入尺度极度敏感若price在 1000 量级而rsi_14在 0~100梯度更新会严重偏向大尺度特征导致模型学不到rsi的微弱信号。解决在create_sequences后对X_lstm沿feature维度做 MinMaxScaler非 StandardScaler因 LSTM 更适应 [0,1] 区间。代码from sklearn.preprocessing import MinMaxScaler scaler_lstm MinMaxScaler() X_lstm_reshaped X_lstm.reshape(-1, X_lstm.shape[-1]) X_lstm_scaled scaler_lstm.fit_transform(X_lstm_reshaped) X_lstm X_lstm_scaled.reshape(X_lstm.shape)4.2 现象ARIMA 预测结果是一条直线原因auto_arima选了d0未差分而股价原始序列非平稳模型只能拟合常数项。解决强制d1并在auto_arima中设stationaryFalse同时用adf_test验证差分后序列diff_series raw_df[price].diff().dropna() adf_diff adfuller(diff_series) assert adf_diff[1] 0.05, 一阶差分后仍不平稳请尝试 d24.3 现象KNN 预测值集中在几个离散水平像阶梯原因n_neighbors过小如 k1导致模型退化为“复制最近一天价格”缺乏平滑性。解决网格搜索时n_neighbors至少覆盖 [5, 15]且必须用weightsdistance让近邻权重更高。若仍阶梯化说明特征维度不足需增加price_ma60或vol_ma20等长周期特征。4.4 现象LR 的 R² 为负数原因测试集分布与训练集偏移如训练用牛市数据测试用熊市或目标变量存在强异方差。解决检查y_train_lr与y_test_lr的均值、标准差比值若 1.5 倍说明分布漂移应重切分点如按年份切2020-2022 训练2023 测试对y_train_lr做 Box-Cox 变换from scipy import stats; y_train_box, _ stats.boxcox(y_train_lr)预测后逆变换。4.5 现象四模型预测结果差异极大融合后效果反而不如单模型原因未做预测区间校准。LSTM 输出点预测ARIMA 可输出置信区间但直接平均点预测会放大误差。解决统一用分位数回归思想——对每个模型用其验证集残差的 10%/90% 分位数构建预测区间[pred - q10, pred q90]融合时只取区间交集的中点。代码逻辑# 假设 y_val_true, y_val_pred 为各模型在验证集上的真值与预测 residuals y_val_true - y_val_pred q10, q90 np.percentile(residuals, [10, 90]) interval_low y_pred_test - q90 # 注意q90 是正数减去它得下界 interval_high y_pred_test - q10 # q10 是负数减去它得上界 ensemble_pred (interval_low interval_high) / 25. 模型融合与实盘推演用加权平均 置信度门控把四模型变成稳定信号源5.1 为什么不用 stacking 或 voting——金融场景的特殊约束Stacking用元模型学习各模型输出在图像识别中有效但在股价预测中是危险的元模型如第二层 LR会拟合各模型在历史上的“错误模式”一旦市场风格切换如从价值股切换到题材股元模型会把旧错误当规律Voting 要求模型输出类别涨/跌但股价预测本质是回归问题强行分类损失关键信息如“涨1%”和“涨5%”决策完全不同。我们采用轻量级、可解释、可审计的融合策略权重动态计算每个模型在最近 30 天验证集上的 MAE 取倒数归一化为权重置信度门控若某模型预测区间宽度 近 30 天均值的 2 倍则将其权重置 0拒绝低置信度信号输出带区间最终预测 加权平均点预测区间 加权平均上下界。def calculate_dynamic_weights( models: list, # [lr_model, knn_model, arima_model, lstm_model] X_val_list: list, # 对应各模型的验证集 X y_val: np.ndarray, # 真实验证标签 window_size: int 30 ) - np.ndarray: weights [] intervals [] for i, model in enumerate(models): if i 2: # ARIMA 模型 y_pred_val model.predict(n_periodslen(y_val)) elif i 3: # LSTM 模型 y_pred_val model.predict(X_val_list[i]).flatten() else: # LR/KNN y_pred_val model.predict(X_val_list[i]) # 计算最近 window_size 天的 MAE recent_mae mean_absolute_error( y_val[-window_size:], y_pred_val[-window_size:] ) weights.append(1 / (recent_mae 1e-6)) # 防零 # 估算预测区间用验证集残差分位数 residuals y_val - y_pred_val q10, q90 np.percentile(residuals[-window_size:], [10, 90]) intervals.append((q10, q90)) # 归一化权重 weights np.array(weights) weights weights / weights.sum() # 置信度门控若区间宽度 均值2倍权重归零 widths np.array([q90 - q10 for q10, q90 in intervals]) mean_width np.mean(widths) for i in range(len(weights)): if widths[i] 2 * mean_width: weights[i] 0 weights weights / (weights.sum() 1e-6) # 再次归一化 return weights, intervals # 示例假设有四模型验证预测 X_val_lr X_trad[split_idx:split_idx100] # LR 验证集 X_val_knn X_trad[split_idx:split_idx100] # KNN 验证集 X_val_lstm X_lstm[split_idx_lstm:split_idx_lstm100] # LSTM 验证集 y_val y_trad[split_idx:split_idx100] # 假设已训练好四模型lr_model, knn_model, arima_model, model_lstm models [lr_model, knn_model, arima_model, model_lstm] X_val_list [X_val_lr, X_val_knn, None, X_val_lstm] # ARIMA 不需要 X填 None weights, intervals calculate_dynamic_weights(models, X_val_list, y_val) print(动态权重:, [f{w:.3f} for w in weights]) print(各模型区间宽度:, [f{q90-q10:.4f} for q10, q90 in intervals])5.2 实盘推演用滚动回测验证融合策略的稳定性真正考验模型的不是单次测试 MAE而是在未知时间段上的持续表现。我们用滚动窗口回测Rolling Walk-Forward Validation初始训练集前 1000 天每次预测 1 天然后将该天数据加入训练集滑动窗口记录每天的融合预测、真实值、各模型权重、区间覆盖率真实值落在预测区间内的比例。def rolling_backtest( raw_df: pd.DataFrame, models: list, feature_func: callable, window_size: int 1000, test_days: int 250 ) - pd.DataFrame: results [] feat_df feature_func(raw_df) for day in range(window_size, window_size test_days): # 构建当日训练数据 train_feat feat_df.iloc[:day] X_train_lstm, y_train_lstm, X_train_trad, y_train_trad create_sequences( train_feat, timesteps60 ) # 重新训练模型简化版实际中 LR/KNN 可增量更新ARIMA/LSTM 需重训 # ... 此处省略训练代码聚焦逻辑 # 预测第 day 天 y_pred_fused, interval_low, interval_high ensemble_predict( models, X_train_trad, X_train_lstm, feat_df.iloc[day-60:day] ) true_price feat_df.iloc[day][target_price] in_interval (true_price interval_low) and (true_price interval_high) results.append({ date: feat_df.index[day], pred: y_pred_fused, true: true_price, interval_low: interval_low, interval_high: interval_high, in_interval: in_interval, error: abs(true_price - y_pred_fused) }) return pd.DataFrame(results) # 执行回测耗时较长生产环境建议用 Dask 并行 # backtest_df rolling_backtest(raw_df, models, build_features) # print(区间覆盖率:, backtest_df[in_interval].mean()) # print(平均绝对误差:, backtest_df[error].mean())关键指标解读区间覆盖率 80%说明模型不确定性量化合理误差序列无自相关Ljung-Box 检验 p0.05说明模型未残留系统性偏差权重分布稳定如 LR 权重始终在 0.2~0.4说明没有模型长期失效。5.3 一个值得坚持的实战习惯永远保存「预测-真值-区间」三元组到 CSV我经手的每个股价预测项目上线第一天就写这个函数def save_prediction_log( date: str, pred: float, true: float, interval_low: float, interval_high: float, model_weights: list, features_used: list, log_file: str prediction_log.csv ): log_entry { date: date, pred_price: round(pred, 4), true_price: round(true, 4), interval_low: round(interval_low, 4), interval_high: round(interval_high, 4), coverage: 1 if (interval_low true interval_high) else 0, abs_error: round(abs(pred - true), 4), lr_weight: round(model_weights[0], 3), knn_weight: round(model_weights[1], 3), arima_weight: round(model_weights[2], 3), lstm_weight: round(model_weights[3], 3), features: |.join(features_used) } df_log pd.DataFrame([log_entry]) if not os.path.exists(log_file): df_log.to_csv(log_file, indexFalse) else: df_log.to_csv(log_file, modea, headerFalse, indexFalse) # 每日预测后调用 # save_prediction_log( # date2023-12-01, # pred1825.3, # true1831.7, # interval_low1812.4, # interval_high1838.9, # model_weights[0.25, 0.18, 0.32, 0.25], # features_used[price_lag1,rsi_14,vol_ratio] # )为什么重要三个月后当你发现某类行情下 LSTM 权重持续归零本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询