logo

LSTM 时间序列预测

王哲峰 / 2022-09-17


目录

目标

Python 依赖

import numpy as np
import pandas as pd
from matplotlib.pyplot as plt

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import GridSearchCV

数据

df = pd.read_csv("train.csv", parse_dates = ["Date"], index_col = [0])
df.head()
df.tail()
df.shape

训练数据分割

test_split = round(len(df) * 0.2)

df_train = df[:-test_split]
df_test = df[-test_split:]

print(df_train)
print(df_test)

数据规范化

scaler = MinMaxScaler(feature_range = (0, 1))

df_train_scaled = scaler.fit_transform(df_train)
df_test_scaled = scaler.transform(df_test)

print(df_train_scaled)

数据处理

def create_x_y(data, n_past):
    data_x = []
    data_y = []
    for i in range(n_past, len(data)):  # range(30, 4162), range(30, 1041)
        data_x.append(data[(i - n_past):i, 0:data.shape[1]])
        data_y.append(data[i, 0])

    return np.array(data_x), np.array(data_y)

train_x, train_y = create_x_y(df_train_scaled, 30)
test_x, test_y = create_x_y(df_test_scaled, 30)
print(f"train_x shape: {train_x.shape}")
print(f"train_y shape: {train_y.shape}")

print(f"test_x shape: {test_x.shape}")
print(f"test_y shape: {test_y.shape}")

print(f"train_x[0]: {train_x[0]}")
print(f"train_y[0]: {train_y[0]}")
(4132, 30, 5)
(4132,)

(1011, 30, 5)
(1011,)

超参数调优

def build_model(optimizer):
    grid_model = Sequential()
    grid_model.add(LSTM(50), return_sequences = True, input_shape = (30, 5))
    grid_model.add(LSTM(50))
    grid_model.add(Dropout(0.2))
    grid_model.add(Dense(1))

    grid_model.compile(loss = "mse", optimizer = optimizer)
    
    return grid_model
grid_model = KerasRegressor(
    build_fn = build_model, 
    verbose = 1,
    validation_data = (tset_x, test_y)
)

parameters = {
    "batch_size": [16, 20],
    "epochs": [8, 10],
    "optimizer": ["adam", "Adadelta"],
}

grid_search = GridSearchCV(
    estimator = grid_model,
    param_grid = parameters,
    cv = 2,
)

grid_search = grid_search.fit(train_x, train_y)

# 最优参数
grid_search.best_params_

模型预测

# 训练好的模型
my_model = grid_search.best_estimator_.model

# 模型预测
prediction = my_model.predict(test_x)
print(f"prediction:\n {prediction}")
print(f"\nPrediction shape: {prediction.shape}")
prediction_copy_array = np.repeat(prediction, 5, axis = -1)
pred = scaler.inver_transform(prediction_copy_array)

参考