如何用Python基于LSTM模型预测新值并绘制预测曲线?
Hey there! Great job getting your LSTM model trained and plotting your test predictions. Let's fix that missing piece: predicting future values (like the next 4 days) and adding them to your matplotlib plot. Here's a step-by-step solution tailored to your code:
Step 1: Understand the Future Prediction Logic
Since LSTMs require a sequence of past data to make a prediction, we'll use an iterative approach:
- Start with the last sequence from your test data (this gives the model the most recent context)
- Predict the next value
- Update the input sequence by dropping the oldest value and adding the new prediction
- Repeat this for as many future steps as you need (4 days in your case)
Step 2: Add a Function to Generate Future Predictions
Add this helper function to your code. It handles the iterative prediction and inverse scaling:
def predict_future(model, last_sequence, n_future_steps, scaler): # Initialize list to store future predictions future_predictions = [] current_sequence = last_sequence.reshape(1, last_sequence.shape[0], last_sequence.shape[1]) for _ in range(n_future_steps): # Predict next value next_pred = model.predict(current_sequence, verbose=0) # Inverse scale the prediction to get back to original units next_pred_inv = scaler.inverse_transform(next_pred) # Store the prediction future_predictions.append(next_pred_inv[0][0]) # Update the sequence: remove the oldest time step, add the new prediction # Reshape prediction to match the sequence's feature dimension next_pred_scaled = next_pred.reshape(1, 1, current_sequence.shape[2]) current_sequence = np.concatenate([current_sequence[:, 1:, :], next_pred_scaled], axis=1) return np.array(future_predictions)
Step 3: Integrate Future Predictions into Your Existing Code
Update your code after generating test_predict to compute future values:
# Get the last sequence from your test data (starting point for future predictions) last_test_sequence = X_test[-1] # Predict next 4 days (adjust n_future_steps to your needs) n_future_days = 4 future_preds = predict_future(model, last_test_sequence, n_future_days, scaler)
Step 4: Extend Your Plot to Include Future Predictions
Modify your plotting code to add the future predictions. We'll extend the x-axis to cover the future time steps:
# Plot setup plt.figure(figsize=(8,4)) # Plot actual test data (first 200 points as before) aa = [x for x in range(200)] plt.plot(aa, Y_test[0][:200], marker='.', label="actual") # Plot test predictions (first 200 points) plt.plot(aa, test_predict[:,0][:200], 'r', label="prediction") # Plot future predictions: extend the x-axis beyond the first 200 steps future_aa = [200 + x for x in range(n_future_days)] plt.plot(future_aa, future_preds, 'g--', marker='o', label="future prediction") # Formatting (keep your existing formatting) plt.tight_layout() sns.despine(top=True) plt.subplots_adjust(left=0.07) plt.ylabel('Global_active_power', size=15) plt.xlabel('Time step', size=15) # Adjusted font size for consistency plt.legend(fontsize=15) plt.show()
Full Modified Code
Here's how all the pieces fit together with your original code:
import numpy as np import matplotlib.pyplot as plt import seaborn as sns from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dropout, Dense from tensorflow.keras.callbacks import EarlyStopping from sklearn.metrics import mean_absolute_error, mean_squared_error from sklearn.preprocessing import MinMaxScaler # Assuming you used MinMaxScaler # --- Your original model setup and training --- model = Sequential() model.add(LSTM(100, input_shape=(X_train.shape[1], X_train.shape[2]))) model.add(Dropout(0.2)) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') history = model.fit(X_train, Y_train, epochs=20, batch_size=70, validation_data=(X_test, Y_test), callbacks=[EarlyStopping(monitor='val_loss', patience=10)], verbose=1, shuffle=False) model.summary() train_predict = model.predict(X_train) test_predict = model.predict(X_test) # Invert predictions train_predict = scaler.inverse_transform(train_predict) Y_train = scaler.inverse_transform([Y_train]) test_predict = scaler.inverse_transform(test_predict) Y_test = scaler.inverse_transform([Y_test]) print('Train Mean Absolute Error:', mean_absolute_error(Y_train[0], train_predict[:,0])) print('Train Root Mean Squared Error:',np.sqrt(mean_squared_error(Y_train[0], train_predict[:,0]))) print('Test Mean Absolute Error:', mean_absolute_error(Y_test[0], test_predict[:,0])) print('Test Root Mean Squared Error:',np.sqrt(mean_squared_error(Y_test[0], test_predict[:,0]))) # --- Add future prediction function --- def predict_future(model, last_sequence, n_future_steps, scaler): future_predictions = [] current_sequence = last_sequence.reshape(1, last_sequence.shape[0], last_sequence.shape[1]) for _ in range(n_future_steps): next_pred = model.predict(current_sequence, verbose=0) next_pred_inv = scaler.inverse_transform(next_pred) future_predictions.append(next_pred_inv[0][0]) next_pred_scaled = next_pred.reshape(1, 1, current_sequence.shape[2]) current_sequence = np.concatenate([current_sequence[:, 1:, :], next_pred_scaled], axis=1) return np.array(future_predictions) # --- Generate future predictions --- last_test_sequence = X_test[-1] n_future_days = 4 future_preds = predict_future(model, last_test_sequence, n_future_days, scaler) # --- Plot everything --- plt.figure(figsize=(8,4)) aa = [x for x in range(200)] plt.plot(aa, Y_test[0][:200], marker='.', label="actual") plt.plot(aa, test_predict[:,0][:200], 'r', label="prediction") # Plot future predictions future_aa = [200 + x for x in range(n_future_days)] plt.plot(future_aa, future_preds, 'g--', marker='o', label="future prediction") plt.tight_layout() sns.despine(top=True) plt.subplots_adjust(left=0.07) plt.ylabel('Global_active_power', size=15) plt.xlabel('Time step', size=15) plt.legend(fontsize=15) plt.show();
Key Notes
- Make sure your
scaleris defined and fitted on your original data (I added a comment assuming you usedMinMaxScaler—adjust if you used a different scaler) - The
verbose=0inmodel.predict()keeps the output clean during future predictions - The dashed green line with circle markers makes future predictions easy to distinguish from actual/test data
内容的提问来源于stack exchange,提问作者Amr Mahmoud

