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

如何使用LSTM模型基于多特征输入实现单输出时序预测?

多变量LSTM单目标预测实现方案

你需要实现的是*多输入单输出(MISO)*时序预测任务:用全量股票技术特征、多标的行情数据的时序信息,拟合指定单一目标(如标普500收盘价)的走势。
多变量时序预测数据结构示意图

现有代码存在两处核心偏差:

  • 标签拆分逻辑硬编码取数据集最后一列,未手动指定目标列位置
  • 输入形状重构时将时间步长设为1,未构造时序滑动窗口样本,LSTM无法学习长短期时序依赖

以下是标准化实现流程:

1. 明确目标列,正确拆分特征与标签

不要用[:, -1]的默认方式取标签,先在数据集中定位你要预测的目标列,建议对特征和目标值分别做缩放,方便后续逆转换还原真实价格:

import numpy as np
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dropout, Dense

# 替换为你的目标列名,例如标普500收盘价列
TARGET_COL = "sp500_close"
# 数据集需提前按时间升序排列,禁止随机打乱
feature_data = feature_data.sort_values("trade_date").reset_index(drop=True)

# 拆分特征、目标列
X = feature_data.drop(columns=[TARGET_COL, "trade_date"]).values
y = feature_data[[TARGET_COL]].values

# 先切分数据集再做缩放,避免数据泄露
train_size = int(len(X) * 0.8)
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]

scaler_X = MinMaxScaler(feature_range=(0,1))
scaler_y = MinMaxScaler(feature_range=(0,1))
X_train_scaled = scaler_X.fit_transform(X_train)
X_test_scaled = scaler_X.transform(X_test)
y_train_scaled = scaler_y.fit_transform(y_train)
y_test_scaled = scaler_y.transform(y_test)

2. 构造时序滑动窗口样本

LSTM输入要求形状为(样本数, 时间步长, 特征数),需要用过去N个时间步的全量特征,预测当前/未来时间步的目标值。时间步长可根据预测周期调整,常用值为5、10、20、60(对应单周、双周、单月、单季度交易日):

def build_ts_dataset(X, y, time_steps=10):
    X_seq, y_seq = [], []
    for i in range(time_steps, len(X)):
        # 取过去time_steps步的所有特征
        X_seq.append(X[i-time_steps:i, :])
        # 取当前步的目标值
        y_seq.append(y[i, 0])
    return np.array(X_seq), np.array(y_seq)

# 设定时间步长
TIME_STEPS = 10
X_train_seq, y_train_seq = build_ts_dataset(X_train_scaled, y_train_scaled, TIME_STEPS)
X_test_seq, y_test_seq = build_ts_dataset(X_test_scaled, y_test_scaled, TIME_STEPS)

3. 模型训练与预测

你现有堆叠LSTM的结构可直接复用,仅需调整输入形状匹配、输出层激活函数适配回归任务即可:

model = Sequential()
model.add(LSTM(50, return_sequences=True, input_shape=(X_train_seq.shape[1], X_train_seq.shape[2])))
model.add(Dropout(0.2))
model.add(LSTM(units=50, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(units=50, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(units=50))
model.add(Dropout(0.2))
# 回归任务用linear激活,避免relu截断0值导致预测偏差
model.add(Dense(units=1, activation='linear'))

model.compile(optimizer='adam', loss='mse')
history = model.fit(
    X_train_seq, y_train_seq,
    batch_size=32,
    epochs=50,
    validation_data=(X_test_seq, y_test_seq),
    shuffle=False # 时序训练禁止打乱样本顺序
)

# 预测后用scaler_y还原真实价格尺度
y_pred_scaled = model.predict(X_test_seq)
y_pred = scaler_y.inverse_transform(y_pred_scaled)
y_true = scaler_y.inverse_transform(y_test_seq.reshape(-1,1))

注意事项

  • 所有缩放操作必须在训练/测试集拆分后完成,仅用训练集统计量拟合scaler,否则会造成数据泄露,验证结果虚高
  • 输入特征建议提前做共线性筛选,剔除和目标列相关性极低的噪声特征,避免干扰模型学习
  • 若要预测多步之后的价格,仅需调整build_ts_dataset函数中y的取值偏移量即可
  • 模型评估不要直接用缩放后的MSE,需还原到真实价格尺度后计算指标,结果才有实际参考意义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 21:03:19