【Python时序预测系列】建立LSTM与DT融合模型实现单变量时序预测(案例+源码)

这是我的第419篇原创文章。

一、引言

将LSTM与决策树结合形成“混合时间序列预测模型,可以更好地建模实际数据中的复杂性。

模型结构:

  • 第一阶段:使用LSTM模型对时间序列进行主预测;

  • 第二阶段:利用决策树回归器学习LSTM的残差(预测误差);

  • 组合预测:最终预测值 = LSTM预测 + 决策树预测残差。

数据流流程:

  1. 模拟生成时间序列(含多周期、季节性和噪声);

  2. 将序列切片为监督学习格式;

  3. 使用80%的前序数据训练模型(严格时间顺序,避免数据泄露);

  4. 剩余20%作为测试集;

  5. 可视化与分析模型效果。

二、实现过程

2.1 读取时间序列数据

核心代码:

data = pd.DataFrame(pd.read_csv('data.csv'))
print(data.head())
y = data['Passengers'].values

2.2 构造监督学习问题

核心代码:

def create_sequences(data, seq_length):
    X, y = [], []
    for i in range(len(data) - seq_length):
        X.append(data[i:i+seq_length])
        y.append(data[i+seq_length])
    return np.array(X), np.array(y)
seq_length = 7
X, y_target = create_sequences(y, seq_length)
# 分为训练集和测试集(避免未来信息泄露)
split_index = int(len(X) * 0.8)
X_train, y_train = X[:split_index], y_target[:split_index]
X_test, y_test = X[split_index:], y_target[split_index:]

2.3 构建LSTM模型

核心代码:

class LSTMRegressor(nn.Module):
    def __init__(self, input_size=1, hidden_size=50, num_layers=1):
        super(LSTMRegressor, self).__init__()
        self.hidden_size = hidden_size
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, 1)
    def forward(self, x):
        out, _ = self.lstm(x)
        out = self.fc(out[:, -1, :])
        return out

2.4 模型训练

核心代码:

num_epochs = 1000
loss_list = []
for epoch in range(num_epochs):
    model.train()
    total_loss = 0
    for seqs, targets in train_loader:
        optimizer.zero_grad()
        outputs = model(seqs)
        loss = criterion(outputs, targets)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    avg_loss = total_loss / len(train_loader)
    loss_list.append(avg_loss)
    if epoch % 10 == 0:
        print(f"Epoch [{epoch}/{num_epochs}], Loss: {avg_loss:.4f}")

训练损失下降曲线:

图片

可见损失逐步下降并趋于稳定,说明模型成功学习了时间序列结构,若呈震荡或上升趋势,需重新调整模型参数或学习率。

2.5 LSTM预测 + 决策树增强

核心代码:

model.eval()
X_test_tensor = torch.tensor(X_test, dtype=torch.float32).unsqueeze(-1)
lstm_preds = model(X_test_tensor).detach().numpy().flatten()
# 决策树基于LSTM残差预测
residuals = y_test - lstm_preds
# 特征扩展
X_tree_train = lstm_preds.reshape(-1, 1)
model_tree = DecisionTreeRegressor(max_depth=3)
model_tree.fit(X_tree_train, residuals)
residual_preds = model_tree.predict(X_tree_train)
final_preds = lstm_preds + residual_preds

2.6 可视化分析

图1:LSTM预测 vs 真实值。对比基本LSTM模型的预测能力与实际时间序列。

    核心代码:

    plt.figure(figsize=(10, 4))
    plt.plot(y_test, label="True", color='blue')
    plt.plot(lstm_preds, label="LSTM Prediction", color='orange')
    plt.title("LSTM vs True Value")
    plt.legend()
    plt.grid(True)
    plt.show()

    结果:

    图片

    蓝线表示真实测试数据;橙线表示LSTM模型的输出;曲线整体趋势相似,但在局部波动、高频变化点存在一定误差。可以看到,LSTM能捕捉主要趋势,但对复杂结构建模仍有欠缺。

    图2:混合模型预测 vs 真实值:展示LSTM+决策树混合模型的预测结果与真实值对比。

    核心代码:

    plt.figure(figsize=(10, 4))
    plt.plot(y_test, label="True", color='blue')
    plt.plot(final_preds, label="LSTM + Tree Hybrid", color='green')
    plt.title("Hybrid Model vs True Value")
    plt.legend()
    plt.grid(True)
    plt.show()

    结果:

    图片

    绿色曲线为混合模型预测,显著比单一LSTM更贴合真实值,尤其是在转折点、局部波动处。可以看到,混合模型能有效纠正LSTM预测误差,增强模型表达能力。

    图3:残差分布对比:对比LSTM与混合模型的预测残差分布,分析误差收敛情况。

    核心代码:

    plt.figure(figsize=(10, 4))
    sns.histplot(y_test - lstm_preds, color='red', label='LSTM Residuals', kde=True)
    sns.histplot(y_test - final_preds, color='green', label='Hybrid Residuals', kde=True)
    plt.title("Residual Distribution: LSTM vs Hybrid")
    plt.legend()
    plt.grid(True)
    plt.show()

    结果:

    图片

    红色直方图为LSTM残差,绿色直方图为混合模型残差;可以看到混合模型的残差更集中于0附近,分布更窄。可以看到,决策树成功捕捉了LSTM无法建模的残差模式。

    作者简介:

    读研期间发表6篇SCI数据挖掘相关论文,现在某研究院从事数据算法相关科研工作,结合自身科研实践经历不定期分享关于Python、机器学习、深度学习、人工智能系列基础知识与应用案例。致力于只做原创,以最简单的方式理解和学习,关注我一起交流成长。需要数据集和源码的小伙伴可以关注底部公众号添加作者微信。

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包

    打赏作者

    数据杂坛

    你的鼓励将是我创作的最大动力

    ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
    扫码支付:¥1
    获取中
    扫码支付

    您的余额不足,请更换扫码支付或充值

    打赏作者

    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值