LMST模型敏感性-初学者反运气

问题描述 投票:0回答:1

我一直在试验艾伯塔省电力市场的一些非常基本的数据,并尝试使用时间序列数据的 LMST 模型来尝试预测价格。我确实从我的模型中得到了“可能”的结果,而且它似乎确实出现了一些我们可以预期的波动性(仅根据我自己的市场经验)。

但是,我正在寻求更好地理解我遇到的一些陷阱。

from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dropout
from keras.layers import Dense
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error,mean_squared_error
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import joblib

# Load the data
# Load the data

# Load the data
csv_file_path = 'Frankenstein.csv'  # Update with your actual file path
df = pd.read_csv(csv_file_path)

# Convert 'Date/Time' to datetime and extract components if present in your dataset
if 'Date/Time' in df.columns:
    df['Date'] = pd.to_datetime(df['Date/Time'])
    df['Year'] = df['Date'].dt.year
    df['Month'] = df['Date'].dt.month
    df['Day'] = df['Date'].dt.day
    df['Hour'] = df['Date'].dt.hour
    df.drop(['Date/Time', 'Date'], axis=1, inplace=True)

# Assuming 'Price' is the target variable
features = df.drop(['Price'], axis=1)
target = df['Price']

# Normalize features and target
scaler_features = MinMaxScaler()
features_scaled = scaler_features.fit_transform(features)
scaler_target = MinMaxScaler()
target_scaled = scaler_target.fit_transform(target.values.reshape(-1, 1))

# Create sequences function
def create_sequences(features, target, time_steps=100):
    X, y = [], []
    for i in range(len(features) - time_steps):
        X.append(features[i:(i + time_steps)])
        y.append(target[i + time_steps])
    return np.array(X), np.array(y)

# Create sequences using the entire dataset
X, y = create_sequences(features_scaled, target_scaled.flatten())

# Model configuration
input_shape = (X.shape[1], X.shape[2])  # (time_steps, num_features)

# Define the LSTM model
model = Sequential([
    LSTM(units=100, return_sequences=True, input_shape=input_shape),
    Dropout(0.1),
    LSTM(units=100),
    Dropout(0.1),
    Dense(units=100, activation='elu'),
    Dense(1)  # Predicting a single value
])

# Compile the model
model.compile(optimizer='adam', loss='mean_squared_error')

# Train the model on the entire dataset
history = model.fit(X, y, epochs=150, batch_size=20, validation_split=0.1)

# Plot training & validation loss values
plt.figure(figsize=(10, 6))
plt.plot(history.history['loss'], label='Train')
plt.plot(history.history['val_loss'], label='Validation')
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(loc='upper right')
plt.show()

# Save the LSTM model
model_save_path = 'trained_lstm_model.h5'
model.save(model_save_path)
print(f"Model saved to {model_save_path}")
joblib.dump(scaler_features, 'scaler_features.pkl')
joblib.dump(scaler_target, 'scaler_target.pkl')

有人可以给绝对的初学者一些建议吗?主要是为了更好地理解我应该如何设置它。我有一个每小时的数据集,是过去三年的历史生成和交换。我正在寻找方法让我的模型对供应与价格的变化更具反应性。

python-3.x machine-learning keras neural-network
1个回答
0
投票

您可以尝试训练模型来预测更长的时间范围,例如接下来的 12 小时,而不仅仅是下一小时。这为模型在学习过程中提供了更多背景信息。这类似于将模型更改为多任务或多预测安排,而不是让它仅从下一小时的预测中学习。它也可能对短期趋势产生平均或稳定作用,尽管我认为值得尝试。

模型的新输出形状将为

(batch size, forecast_length)
。推断时,即使模型将输出未来 12 小时的预测,您也只能读取第一个值。对代码的更改将包括以下内容:

 ...
 #for each input sequence, the target is a "forecast_length" vector
 forecast_length = 14
 y.append(target[i + time_steps:i + timesteps + forecast_length])

目前,模型正在摄取一个序列,并且仅在逐步执行所有 100 帧(序列到向量架构)后才渲染其预测。更改为序列到序列架构通常可以得到改进,在该架构中,您可以对输入序列中的每个步骤进行目标预测,而不仅仅是整个序列的单个目标。这可以稳定并加速训练,因为有更多的误差梯度,并且它们不必在时间上流动那么多。输入形状保持不变

(batch_size, sequence_length, input_size)
,但目标形状更改为
(batch_size, sequence_length, forecast_length)
- 序列中的每个点都有一个目标。

对于当前 100 帧的序列大小,听起来模型在学习预测时会考虑大约 4 天的上下文。使用更宽的窗口可能会有所改进。然而,您不是简单地增加序列长度(LSTM 可能会遇到困难),而是可以预先添加一个卷积阶段,该阶段学习将宽感受野压缩为较短的序列,为后续的 LSTM 阶段做好准备。

您也可以完全放弃 LSTM,而采用全卷积方法,类似于 WaveNet。

我认为很难提前判断什么最适合数据,因为它需要实验和调整。

© www.soinside.com 2019 - 2024. All rights reserved.