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

基于LSTM的NDVI时间序列预测:如何实现超测试集未来值预测?

LSTM时间序列未来值预测解决方案(NDVI数据集)

问题背景

基于LSTM搭建的NDVI时间序列模型,在历史数据的训练、验证和测试环节表现正常,但无法实现测试集之外的多步未来值预测。

核心思路

未来预测的关键是滚动迭代:用模型预测出的下一个值,补充到输入序列中,再用新序列预测下一个时间步,循环往复得到多步结果。另外必须补充数据归一化步骤,避免数值分布偏差导致预测失真。

代码优化与预测实现

第一步:补充数据归一化

原代码未做归一化,这会导致未来预测时数值分布偏离训练数据,先修改数据预处理部分:

import tensorflow as tf
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt

df = pd.read_csv(r'NDVI.csv')
df.index = pd.to_datetime(df['Date time'], format='%m/%d/%Y')
NDVI = df['NDVI']

# 数据归一化(必须用训练数据拟合scaler)
scaler = MinMaxScaler(feature_range=(0,1))
NDVI_scaled = scaler.fit_transform(NDVI.values.reshape(-1,1)).flatten()

def df_to_X_y(df, window_size=3):
    df_as_np = df
    X = []
    y = []
    for i in range(len(df_as_np)-window_size):
        row = [[a] for a in df_as_np[i:i+window_size]]
        X.append(row)
        label = df_as_np[i+window_size]
        y.append(label)
    return np.array(X), np.array(y)

WINDOW_SIZE=3
X,y= df_to_X_y(NDVI_scaled, WINDOW_SIZE)

# 划分数据集
X_train, y_train = X[:410], y[:410]
X_val, y_val= X[410:456], y[410:456]
X_test, y_test = X[456:], y[456:]

第二步:训练模型(保留原模型结构,复用即可)

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import *
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.losses import MeanSquaredError
from tensorflow.keras.metrics import RootMeanSquaredError
from tensorflow.keras.optimizers import Adam

model1 = Sequential()
model1.add(InputLayer((WINDOW_SIZE, 1)))
model1.add(LSTM(64))
model1.add(Dense(8, 'relu'))
model1.add(Dense(1, 'linear'))

cp = ModelCheckpoint('NDVImodel/', save_best_only=True)
model1.compile(loss=MeanSquaredError(), optimizer=Adam(learning_rate=0.01), metrics=[RootMeanSquaredError()])
model1.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=20, callbacks=[cp])

第三步:实现未来滚动预测

def predict_future(model, last_sequence, steps, window_size):
    predictions = []
    current_sequence = last_sequence.copy()
    for _ in range(steps):
        # 预测单步值
        next_val = model.predict(current_sequence.reshape(1, window_size, 1), verbose=0)[0][0]
        predictions.append(next_val)
        # 更新序列:丢弃最旧值,加入新预测值
        current_sequence = np.roll(current_sequence, -1)
        current_sequence[-1] = next_val
    # 反归一化还原真实NDVI值
    return scaler.inverse_transform(np.array(predictions).reshape(-1,1)).flatten()

# 获取历史数据最后一个窗口的序列(作为预测起点)
last_history_sequence = NDVI_scaled[-WINDOW_SIZE:]
# 设定要预测的未来步数
future_steps = 10
# 执行预测
future_predictions = predict_future(model1, last_history_sequence, future_steps, WINDOW_SIZE)

# 可视化结果
plt.figure(figsize=(12,6))
# 绘制历史NDVI数据
plt.plot(df.index, NDVI, label='历史NDVI')
# 生成未来日期序列(假设原数据是日频,可根据实际调整freq参数)
future_dates = pd.date_range(start=df.index[-1], periods=future_steps+1, freq='D')[1:]
# 绘制未来预测值
plt.plot(future_dates, future_predictions, label='未来预测', linestyle='--', color='#ff4444')
plt.legend()
plt.title('NDVI历史数据与未来预测')
plt.show()

关键注意事项

  • 归一化必须用训练数据拟合的scaler,不能对测试集或未来数据重新拟合,否则会引入数据泄露
  • 多步预测的误差会随步数增加累积,建议控制预测步数(比如10-30步),或改用Seq2Seq结构的LSTM模型优化长序列预测
  • 可尝试调整窗口大小(比如增大到7、14),让模型捕获更长时间的时序规律,提升预测稳定性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:18:09