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

如何基于多输入LSTM模型实现股票价格多日预测?

多变量LSTM股票多日预测修改方案

问题背景

我基于多变量时间序列实现了输入维度为(50,5)的LSTM股票预测模型,但目前只能输出单日单列的预测结果,想要实现30天的多日预测。尝试循环预测时,发现模型要求输入是50×5的维度,没法把单日1×1的预测结果补充到输入里,求修改指导。

现有代码与输出情况

训练数据维度

(480, 50, 5)  # x_train:480个样本,每个样本50时间步×5特征
(480,)        # y_train:每个样本对应1个单日收盘价标签
(132, 50, 5)  # x_test
(132,)        # y_test

现有模型与单日预测代码

model = Sequential()
n_neurons = x_train.shape[1] * x_train.shape[2]
print(n_neurons, x_train.shape[1], x_train.shape[2])
model.add(LSTM(n_neurons, return_sequences=True, input_shape=(x_train.shape[1], x_train.shape[2])))
model.add(LSTM(n_neurons, return_sequences=False))
model.add(Dense(5))
model.add(Dense(1))

model.compile(optimizer='adam', loss='mse')
epochs = 100
batch_size = 16
early_stop = EarlyStopping(monitor='loss', patience=5, verbose=1)
history = model.fit(x_train, y_train, 
                    batch_size=batch_size, 
                    epochs=epochs,
                    validation_data=(x_test, y_test)
                   )
# 单日预测逻辑
pred_price_scaled = model.predict(np.array(to_predict_scaled))
pred_price_unscaled = scaler.inverse_transform(pred_price_scaled.reshape(-1, 1))

price_today = np.round(data.loc[data.index[-1], "Close Price"])
predicted_price = np.round(pred_price_unscaled.ravel()[0], 2)
change_percent = np.round(100 - (price_today * 100)/predicted_price, 2)

print(f'The predicted close price is {predicted_price} ({"+" if change_percent > 0 else "-"}{change_percent}%)  today={price_today}')

输出:The predicted close price is 1322.5 (-0.72%) today=1332.0

尝试的多日预测代码(存在问题)

while(i<30):
    yhat = model.predict(np.array(X_test_new))
    X_test_new.extend(yhat[0].tolist())
    lst_output.extend(yhat.tolist())
    i=i+1

核心问题分析

模型输入要求是50时间步×5特征,但每次预测仅输出1个收盘价(1×1),无法直接补全5个特征的输入维度。要实现多日预测,必须解决两个核心问题:

  1. 每次预测后维持输入序列的50时间步长度
  2. 补全预测日除收盘价外的其他4个特征值

具体修改方案

方案:保留5特征的滚动预测(推荐)

假设你的5个特征是[Open, High, Low, Close, Volume]这类常规股票特征,以下是可直接运行的修改代码:

# 初始化预测结果列表
lst_output = []
# 复制初始输入(确保是形状为(1,50,5)的归一化数据)
current_input = to_predict_scaled.copy()

for _ in range(30):
    # 预测单日归一化后的收盘价
    yhat_scaled = model.predict(current_input, verbose=0)
    lst_output.append(yhat_scaled[0][0])
    
    # --- 构建新的输入序列 ---
    # 取输入序列最后1天的前4个特征(Open/High/Low/Volume)作为新一天的对应特征
    last_day_features = current_input[0, -1, :4]
    # 拼接成新的1天数据:[Open, High, Low, 预测Close, Volume]
    new_day = np.concatenate([last_day_features, yhat_scaled[0]])
    # 调整形状为(1,1,5),匹配输入维度要求
    new_day = new_day.reshape(1,1,5)
    # 更新输入:去掉最旧的1天,加入新生成的1天,保持50时间步长度
    current_input = np.concatenate([current_input[:, 1:, :], new_day], axis=1)

# --- 反归一化处理 ---
# 构造包含5列的数组(适配原始归一化器),仅Close列是预测值
pred_scaled_array = np.array(lst_output).reshape(-1,1)
full_pred_scaled = np.hstack([np.zeros((30,4)), pred_scaled_array])
# 反归一化后提取Close列的预测结果
pred_unscaled = scaler.inverse_transform(full_pred_scaled)[:,4]

# 输出30天预测结果
print("30天预测收盘价:", pred_unscaled.round(2))

关键说明

  1. 特征补全逻辑:代码中用前一日的Open/High/Low/Volume作为新一天的对应特征,是最简单的实现方式。如果追求更高精度,可以为每个特征单独训练预测模型,或用移动平均、插值等方法生成其他特征的预测值。
  2. 输入维度维持:每次预测后通过"丢弃最旧时间步+新增预测时间步"的方式,始终保持输入序列为50时间步长度。
  3. 反归一化适配:原始归一化器是针对5个特征训练的,因此需要构造包含5列的数组完成反归一化,最后提取Close列的结果即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:55:15