如何将Pandas DataFrame传入Keras SimpleRNN层实现目标预测?
解决方法
1. 明确RNN输入的核心要求
RNN层要求输入是**[batch_size, timesteps, features]**的3D张量:
- batch_size:每次训练的样本数
- timesteps:每个序列包含的时间步数量(比如用前2周的数据预测第3周目标,timesteps=2)
- features:每个时间步对应的特征数量(你的数据里是5个Feature)
你的当前数据是2D的[样本数, 特征数],缺少时间步维度,同时模型的input_shape设置与实际特征数不匹配,这是报错的根本原因。
2. 将2D数据转换为3D序列
编写工具函数生成符合要求的序列数据,以“用前N周数据预测当前周Target”为例:
import numpy as np def create_sequences(feature_df, target_series, timesteps): X, y = [], [] # 遍历生成序列:从第0个样本到 len(data)-timesteps 个样本 for i in range(len(feature_df) - timesteps): # 取连续timesteps个时间步的特征 X.append(feature_df.iloc[i:i+timesteps].values) # 取对应下一个时间步的Target值 y.append(target_series.iloc[i+timesteps]) return np.array(X), np.array(y) # 选择时间步长度,比如用前1周数据预测当前周(可根据需求调整为2、3等) timesteps = 1 # 转换各数据集 train_X, train_y = create_sequences(train_df, train_ans, timesteps) val_X, val_y = create_sequences(val_df, val_ans, timesteps) test_X, test_y = create_sequences(test_df, test_ans, timesteps)
转换后的数据形状示例(timesteps=1时):
train_X.shape→(34, 1, 5)train_y.shape→(34,)
3. 修正模型的输入形状
模型的input_shape需要匹配每个序列的[timesteps, features],调整后的模型代码:
model = keras.models.Sequential([ # input_shape设置为[timesteps, 5],对应每个序列的时间步和特征数 keras.layers.SimpleRNN(5, return_sequences=True, input_shape=[timesteps, 5]), keras.layers.SimpleRNN(5, return_sequences=True), keras.layers.SimpleRNN(1) ]) model.compile(loss="mse", optimizer="adam") history = model.fit(train_X, train_y, epochs=20, validation_data=(val_X, val_y))
如果希望模型支持可变长度的时间步,可以把input_shape改为[None, 5],其中None表示时间步数量不固定。
4. 关键优化建议
- 数据归一化:RNN对数据尺度敏感,建议用
StandardScaler对特征列做归一化处理,避免不同特征的数值差异过大影响模型收敛 - 调整时间步:尝试不同的timesteps值(如2、3),看哪种序列长度的预测效果更好
- 防止过拟合:由于你的数据集规模很小,可以考虑添加
Dropout层,或者减少RNN单元数量、训练轮数(epochs)
内容的提问来源于stack exchange,提问作者Jonas Palačionis
相关产品推荐
相关产品推荐

