You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TensorFlow v1中基于pandas DataFrame实现LSTM并解决相关报错

错误原因拆解

1. 初始维度报错根因

LSTM层的标准输入格式必须是**(样本数, 时间步长, 特征数)** 三维张量,你初始代码中DenseFeatures层输出的是二维张量(None, 2),其中None代表动态batch size,2是特征数量,缺少了时间步长维度,所以触发ndim不匹配的报错。
你之前加Reshape层报错是因为X_train.shape是(训练集总样本数, 特征数),你直接把整个训练集的样本总数当成了单样本的维度参数,单batch32个样本每个2特征总元素是32*2=64,你要reshape到包含总样本数的维度当然元素数不够,所以报64和8000不匹配。

2. 改用TimeseriesGenerator后的KeyError原因

你同时传了batch_input_shape和input_shape两个参数导致冲突,而且stateful模式的batch_input_shape参数顺序是**(batch_size, timesteps, features)**,你写反了时间步和batch的位置;其次TimeseriesGenerator输出的数据是numpy数组格式,没有DenseFeatures需要的字典键,你去掉了DenseFeatures层但没有调整数据输入逻辑,才会触发找不到键的报错。

3. 时间戳相关问题

不需要把时间戳单独设为一列,你用TimeseriesGenerator是按数据的顺序生成时间窗口,只要拆分数据集的时候没有打乱顺序(你代码里已经设了shuffle=False是对的),时序的先后关系已经保留了。有状态LSTM只要求你按时序顺序喂数据,且前后batch的样本是连续的时序片段即可。


适配TF1.15的可运行修复代码

使用TimeseriesGenerator后不需要DenseFeatures和字典格式的数据集,直接喂数组即可,调整后的代码:

import random
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
from tensorflow.keras.preprocessing.sequence import TimeseriesGenerator
from sklearn.model_selection import train_test_split

# 全局参数设置
time_steps = 10 # 可根据你需要的历史窗口大小调整,这里代表用10个时间步的历史数据预测下一个值
batch_size = 32
np.random.seed(0)
tf.random.set_random_seed(0)
random.seed(0)

# 假设frame为你的原始数据框
X = frame[['optimal_long_log_return', 'optimal_short_log_return']][:-1].values # 转numpy数组
Y = frame['equilibrium_log_return'].shift(-1)[:-1].values
# 时序拆分不能打乱顺序
X_train, _X, y_train, _y = train_test_split(X, Y, test_size=0.5, shuffle=False, random_state=1)
X_validation, X_test, y_validation, y_test = train_test_split(_X, _y, test_size=0.5, shuffle=False, random_state=1)

# 生成时序窗口数据
train = TimeseriesGenerator(X_train, y_train, length=time_steps, batch_size=batch_size)
validation = TimeseriesGenerator(X_validation, y_validation, length=time_steps, batch_size=batch_size)
test = TimeseriesGenerator(X_test, y_test, length=time_steps, batch_size=batch_size)

# 模型构建,stateful模式注意参数
model = Sequential(name='Expected Equilibrium Log Return')
# stateful模式的batch_input_shape顺序是(batch_size, timesteps, features)
# 注意要保证每个batch的样本数固定,最后不足一个batch的数据会被自动丢弃
model.add(LSTM(256, name='LSTM', stateful=True, batch_input_shape=(batch_size, time_steps, X_train.shape[1])))
model.add(Dense(1, name='Output'))
model.compile(loss='logcosh', metrics=['mean_absolute_percentage_error'], optimizer='Adam')
print(model.summary())

# 训练有状态LSTM需要每个epoch后手动重置状态
for epoch in range(10):
    model.fit_generator(train, epochs=1, validation_data=validation, verbose=1, shuffle=False)
    model.reset_states()

loss, accuracy = model.evaluate_generator(test, verbose=0)
print(f'Model Error: {accuracy}%')

关键调整说明

  • 输入特征提前转成numpy数组,不需要用DenseFeatures和字典数据集,避免KeyError
  • 显式指定时间步长参数time_steps,控制LSTM每次输入用多少个历史时刻的特征
  • 修正stateful模式下的batch_input_shape参数顺序,删除冲突的input_shape参数
  • 有状态LSTM训练时每个epoch结束后手动调用reset_states()清理隐藏层状态,避免前后epoch的状态混淆
  • 移除不必要的sample_weight_mode='temporal'参数,单输出预测不需要时序加权

内容的提问来源于stack exchange,提问作者SnakeWasTheNameTheyGaveMe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 19:39:05