LSTM股价预测中验证数据能否传入model.fit?数据集划分疑问
核心结论
- 你当前的用法会导致测试集数据泄露,得到的预测效果完全不具备泛化参考价值,不属于训练集上的传统过拟合,但属于验证流程的根本性错误。
- 必须将原始时序数据按时间顺序拆分为训练集、验证集、测试集三个独立部分,严格区分用途。
原因说明
validation_data传入的数据集虽然不会参与反向传播的权重更新,但训练过程中你会根据验证集的损失变化做大量决策:比如调整训练轮次、修改网络结构、调整优化器参数、触发早停等,这些决策本质上是在让模型间接适配验证集的数据分布。如果你把原本留作最终评估的测试集当验证集用,相当于模型在训练阶段就间接“接触”了测试集的信息,最后再在这份数据上跑predict得到的结果,会远高于模型在真实未知数据上的表现,没有实际参考意义。
三类数据集的正确使用边界
- 训练集:直接参与梯度下降更新模型权重,是模型拟合的核心数据
- 验证集:训练阶段传入
validation_data参数,仅用于监控收敛状态、调整超参数、触发早停,不直接更新权重 - 测试集:训练、调参全程完全隔离,等模型结构、超参数全部确定、训练完成后,仅调用一次
model.predict()评估效果,得到的结果才是模型真实泛化能力的无偏估计
针对股价预测场景的特殊注意点
时间序列拆分严禁随机打乱,必须严格按照时间先后顺序切分,避免未来数据泄露到历史数据集中,你代码中设置shuffle=False是正确的。常规切分比例参考:最早70%数据作为训练集,中间20%作为验证集,最晚10%作为测试集。
修正后的代码示例
# 按时间顺序拆分数据集,假设X、y已经按时间从早到晚排序 total_sample_count = X.shape[0] train_split_idx = int(total_sample_count * 0.7) val_split_idx = int(total_sample_count * 0.9) X_train, y_train = X[:train_split_idx], y[:train_split_idx] X_val, y_val = X[train_split_idx:val_split_idx], y[train_split_idx:val_split_idx] X_test, y_test = X[val_split_idx:], y[val_split_idx:] model_lstm = Sequential() model_lstm.add(LSTM(50, return_sequences = True, input_shape = (X_train.shape[1], X_train.shape[2]))) model_lstm.add(LSTM(units=50, return_sequences=True)) model_lstm.add(LSTM(units=50, return_sequences=True)) model_lstm.add(LSTM(units=50)) model_lstm.add(Dense(units=1, activation='relu')) model_lstm.compile(loss = 'mse', optimizer = 'adam') model_lstm.summary() # 训练阶段仅传入验证集,测试集全程不参与 history_lstm = model_lstm.fit( X_train, y_train, validation_data=(X_val, y_val), epochs = 10, batch_size=32, shuffle=False ) # 模型定版后才在测试集上做最终预测评估 y_test_pred = model_lstm.predict(X_test)
内容的提问来源于stack exchange,提问作者WILLIAM
相关产品推荐
相关产品推荐

