当前位置:   article > 正文

第87步 时间序列建模实战:LSTM回归建模_lstm回归模型

lstm回归模型

基于WIN10的64位系统演示

一、写在前面

这一期,我们介绍大名鼎鼎的LSTM回归。

同样,这里使用这个数据:

《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Syndrome in Jiangsu Province, China》文章的公开数据做演示。数据为江苏省2004年1月至2012年12月肾综合症出血热月发病率。运用2004年1月至2011年12月的数据预测2012年12个月的发病率数据。

二、LSTM回归

(1)LSTM简介

LSTM (Long Short-Term Memory) 是一种特殊的RNN(递归神经网络)结构,由Hochreiter和Schmidhuber在1997年首次提出。LSTM 被设计出来是为了避免长序列在训练过程中的长期依赖问题,这是传统 RNNs 所普遍遇到问题。

(a)LSTM 的主要特点:

(a1)三个门结构:LSTM 包含三个门结构:输入门、遗忘门和输出门。这些门决定了信息如何进入、被存储或被遗忘,以及如何输出。

(a2)记忆细胞:LSTM的核心是称为记忆细胞的结构。它可以保留、修改或访问的内部状态。通过门结构,模型可以学会在记忆细胞中何时存储、忘记或检索信息。

(a3)长期依赖问题:LSTM特别擅长学习、存储和使用长期信息,从而避免了传统RNN在长序列上的梯度消失问题。

(b)为什么LSTM适合时间序列建模:

(b1)序列数据的特性:时间序列数据具有顺序性,先前的数据点可能会影响后面的数据点。LSTM设计之初就是为了处理带有时间间隔、延迟和长期依赖关系的序列数据。

(b2)长期依赖:在时间序列分析中,某个事件可能会受到很早之前事件的影响。传统的RNNs由于梯度消失的问题,很难捕捉这些长期依赖关系。但是,LSTM结构可以有效地处理这种依赖关系。

(b3)记忆细胞:对于时间序列预测,能够记住过去的信息是至关重要的。LSTM的记忆细胞可以为模型提供这种存储和检索长期信息的能力。

(b4)灵活性:LSTM模型可以与其他神经网络结构(如CNN)结合,用于更复杂的时间序列任务,例如多变量时间序列或序列生成。

综上所述,由于LSTM的设计和特性,它非常适合时间序列建模,尤其是当数据具有长期依赖关系时。

(2)单步滚动预测

  1. import pandas as pd
  2. import numpy as np
  3. from sklearn.metrics import mean_absolute_error, mean_squared_error
  4. from tensorflow.python.keras.models import Sequential
  5. from tensorflow.python.keras import layers, models, optimizers
  6. from tensorflow.python.keras.optimizers import adam_v2
  7. # 读取数据
  8. data = pd.read_csv('data.csv')
  9. # 将时间列转换为日期格式
  10. data['time'] = pd.to_datetime(data['time'], format='%b-%y')
  11. # 创建滞后期特征
  12. lag_period = 6
  13. for i in range(lag_period, 0, -1):
  14. data[f'lag_{i}'] = data['incidence'].shift(lag_period - i + 1)
  15. # 删除包含 NaN 的行
  16. data = data.dropna().reset_index(drop=True)
  17. # 划分训练集和验证集
  18. train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
  19. validation_data = data[(data['time'] >= '2012-01-01') & (data['time'] <= '2012-12-31')]
  20. # 定义特征和目标变量
  21. X_train = train_data[['lag_1', 'lag_2', 'lag_3', 'lag_4', 'lag_5', 'lag_6']].values
  22. y_train = train_data['incidence'].values
  23. X_validation = validation_data[['lag_1', 'lag_2', 'lag_3', 'lag_4', 'lag_5', 'lag_6']].values
  24. y_validation = validation_data['incidence'].values
  25. # 对于LSTM,我们需要将输入数据重塑为 [samples, timesteps, features]
  26. X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
  27. X_validation = X_validation.reshape(X_validation.shape[0], X_validation.shape[1], 1)
  28. # 构建LSTM回归模型
  29. input_layer = layers.Input(shape=(X_train.shape[1], 1))
  30. x = layers.LSTM(50, return_sequences=True)(input_layer)
  31. x = layers.LSTM(25, return_sequences=False)(x)
  32. x = layers.Dropout(0.1)(x)
  33. x = layers.Dense(25, activation='relu')(x)
  34. x = layers.Dropout(0.1)(x)
  35. output_layer = layers.Dense(1)(x)
  36. model = models.Model(inputs=input_layer, outputs=output_layer)
  37. model.compile(optimizer=adam_v2.Adam(learning_rate=0.001), loss='mse')
  38. # 训练模型
  39. history = model.fit(X_train, y_train, epochs=200, batch_size=32, validation_data=(X_validation, y_validation), verbose=0)
  40. # 单步滚动预测函数
  41. def rolling_forecast(model, initial_features, n_forecasts):
  42. forecasts = []
  43. current_features = initial_features.copy()
  44. for i in range(n_forecasts):
  45. # 使用当前的特征进行预测
  46. forecast = model.predict(current_features.reshape(1, len(current_features), 1)).flatten()[0]
  47. forecasts.append(forecast)
  48. # 更新特征,用新的预测值替换最旧的特征
  49. current_features = np.roll(current_features, shift=-1)
  50. current_features[-1] = forecast
  51. return np.array(forecasts)
  52. # 使用训练集的最后6个数据点作为初始特征
  53. initial_features = X_train[-1].flatten()
  54. # 使用单步滚动预测方法预测验证集
  55. y_validation_pred = rolling_forecast(model, initial_features, len(X_validation))
  56. # 计算训练集上的MAE, MAPE, MSE 和 RMSE
  57. mae_train = mean_absolute_error(y_train, model.predict(X_train).flatten())
  58. mape_train = np.mean(np.abs((y_train - model.predict(X_train).flatten()) / y_train))
  59. mse_train = mean_squared_error(y_train, model.predict(X_train).flatten())
  60. rmse_train = np.sqrt(mse_train)
  61. # 计算验证集上的MAE, MAPE, MSE 和 RMSE
  62. mae_validation = mean_absolute_error(y_validation, y_validation_pred)
  63. mape_validation = np.mean(np.abs((y_validation - y_validation_pred) / y_validation))
  64. mse_validation = mean_squared_error(y_validation, y_validation_pred)
  65. rmse_validation = np.sqrt(mse_validation)
  66. print("验证集:", mae_validation, mape_validation, mse_validation, rmse_validation)
  67. print("训练集:", mae_train, mape_train, mse_train, rmse_train)

看结果:

(3)多步滚动预测-vol. 1

  1. import pandas as pd
  2. import numpy as np
  3. from sklearn.metrics import mean_absolute_error, mean_squared_error
  4. import tensorflow as tf
  5. from tensorflow.python.keras.models import Model
  6. from tensorflow.python.keras.layers import Input, LSTM, Dense, Dropout, Flatten
  7. from tensorflow.python.keras.optimizers import adam_v2
  8. # 读取数据
  9. data = pd.read_csv('data.csv')
  10. data['time'] = pd.to_datetime(data['time'], format='%b-%y')
  11. n = 6
  12. m = 2
  13. # 创建滞后期特征
  14. for i in range(n, 0, -1):
  15. data[f'lag_{i}'] = data['incidence'].shift(n - i + 1)
  16. data = data.dropna().reset_index(drop=True)
  17. train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
  18. validation_data = data[(data['time'] >= '2012-01-01') & (data['time'] <= '2012-12-31')]
  19. # 准备训练数据
  20. X_train = []
  21. y_train = []
  22. for i in range(len(train_data) - n - m + 1):
  23. X_train.append(train_data.iloc[i+n-1][[f'lag_{j}' for j in range(1, n+1)]].values)
  24. y_train.append(train_data.iloc[i+n:i+n+m]['incidence'].values)
  25. X_train = np.array(X_train)
  26. y_train = np.array(y_train)
  27. X_train = X_train.astype(np.float32)
  28. y_train = y_train.astype(np.float32)
  29. # 构建LSTM模型
  30. inputs = Input(shape=(n, 1))
  31. x = LSTM(64, return_sequences=True)(inputs)
  32. x = LSTM(32)(x)
  33. x = Dense(50, activation='relu')(x)
  34. x = Dropout(0.1)(x)
  35. outputs = Dense(m)(x)
  36. model = Model(inputs=inputs, outputs=outputs)
  37. model.compile(optimizer=adam_v2.Adam(learning_rate=0.001), loss='mse')
  38. # 训练模型
  39. model.fit(X_train, y_train, epochs=200, batch_size=32, verbose=0)
  40. def lstm_rolling_forecast(data, model, n, m):
  41. y_pred = []
  42. for i in range(len(data) - n):
  43. input_data = data.iloc[i+n-1][[f'lag_{j}' for j in range(1, n+1)]].values.astype(np.float32).reshape(1, n, 1)
  44. pred = model.predict(input_data)
  45. y_pred.extend(pred[0])
  46. for i in range(1, m):
  47. for j in range(len(y_pred) - i):
  48. y_pred[j+i] = (y_pred[j+i] + y_pred[j]) / 2
  49. return np.array(y_pred)
  50. # Predict for train_data and validation_data
  51. y_train_pred_lstm = lstm_rolling_forecast(train_data, model, n, m)[:len(y_train)]
  52. y_validation_pred_lstm = lstm_rolling_forecast(validation_data, model, n, m)[:len(validation_data) - n]
  53. # Calculate performance metrics for train_data
  54. mae_train = mean_absolute_error(train_data['incidence'].values[n:len(y_train_pred_lstm)+n], y_train_pred_lstm)
  55. mape_train = np.mean(np.abs((train_data['incidence'].values[n:len(y_train_pred_lstm)+n] - y_train_pred_lstm) / train_data['incidence'].values[n:len(y_train_pred_lstm)+n]))
  56. mse_train = mean_squared_error(train_data['incidence'].values[n:len(y_train_pred_lstm)+n], y_train_pred_lstm)
  57. rmse_train = np.sqrt(mse_train)
  58. # Calculate performance metrics for validation_data
  59. mae_validation = mean_absolute_error(validation_data['incidence'].values[n:len(y_validation_pred_lstm)+n], y_validation_pred_lstm)
  60. mape_validation = np.mean(np.abs((validation_data['incidence'].values[n:len(y_validation_pred_lstm)+n] - y_validation_pred_lstm) / validation_data['incidence'].values[n:len(y_validation_pred_lstm)+n]))
  61. mse_validation = mean_squared_error(validation_data['incidence'].values[n:len(y_validation_pred_lstm)+n], y_validation_pred_lstm)
  62. rmse_validation = np.sqrt(mse_validation)
  63. print("训练集:", mae_train, mape_train, mse_train, rmse_train)
  64. print("验证集:", mae_validation, mape_validation, mse_validation, rmse_validation)

结果:

(4)多步滚动预测-vol. 2

  1. import pandas as pd
  2. import numpy as np
  3. from sklearn.model_selection import train_test_split
  4. from sklearn.metrics import mean_absolute_error, mean_squared_error
  5. from tensorflow.python.keras.models import Sequential, Model
  6. from tensorflow.python.keras.layers import Dense, LSTM, Input
  7. from tensorflow.python.keras.optimizers import adam_v2
  8. # Loading and preprocessing the data
  9. data = pd.read_csv('data.csv')
  10. data['time'] = pd.to_datetime(data['time'], format='%b-%y')
  11. n = 6
  12. m = 2
  13. # 创建滞后期特征
  14. for i in range(n, 0, -1):
  15. data[f'lag_{i}'] = data['incidence'].shift(n - i + 1)
  16. data = data.dropna().reset_index(drop=True)
  17. train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
  18. validation_data = data[(data['time'] >= '2012-01-01') & (data['time'] <= '2012-12-31')]
  19. # 只对X_train、y_train、X_validation取奇数行
  20. X_train = train_data[[f'lag_{i}' for i in range(1, n+1)]].iloc[::2].reset_index(drop=True).values
  21. X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
  22. y_train_list = [train_data['incidence'].shift(-i) for i in range(m)]
  23. y_train = pd.concat(y_train_list, axis=1)
  24. y_train.columns = [f'target_{i+1}' for i in range(m)]
  25. y_train = y_train.iloc[::2].reset_index(drop=True).dropna().values[:, 0]
  26. X_validation = validation_data[[f'lag_{i}' for i in range(1, n+1)]].iloc[::2].reset_index(drop=True).values
  27. X_validation = X_validation.reshape(X_validation.shape[0], X_validation.shape[1], 1)
  28. y_validation = validation_data['incidence'].values
  29. # Building the LSTM model
  30. inputs = Input(shape=(n, 1))
  31. x = LSTM(50, activation='relu')(inputs)
  32. x = Dense(50, activation='relu')(x)
  33. outputs = Dense(1)(x)
  34. model = Model(inputs=inputs, outputs=outputs)
  35. optimizer = adam_v2.Adam(learning_rate=0.001)
  36. model.compile(optimizer=optimizer, loss='mse')
  37. # Train the model
  38. model.fit(X_train, y_train, epochs=200, batch_size=32, verbose=0)
  39. # Predict on validation set
  40. y_validation_pred = model.predict(X_validation).flatten()
  41. # Compute metrics for validation set
  42. mae_validation = mean_absolute_error(y_validation[:len(y_validation_pred)], y_validation_pred)
  43. mape_validation = np.mean(np.abs((y_validation[:len(y_validation_pred)] - y_validation_pred) / y_validation[:len(y_validation_pred)]))
  44. mse_validation = mean_squared_error(y_validation[:len(y_validation_pred)], y_validation_pred)
  45. rmse_validation = np.sqrt(mse_validation)
  46. # Predict on training set
  47. y_train_pred = model.predict(X_train).flatten()
  48. # Compute metrics for training set
  49. mae_train = mean_absolute_error(y_train, y_train_pred)
  50. mape_train = np.mean(np.abs((y_train - y_train_pred) / y_train))
  51. mse_train = mean_squared_error(y_train, y_train_pred)
  52. rmse_train = np.sqrt(mse_train)
  53. print("验证集:", mae_validation, mape_validation, mse_validation, rmse_validation)
  54. print("训练集:", mae_train, mape_train, mse_train, rmse_train)

结果:

(5)多步滚动预测-vol. 3

  1. import pandas as pd
  2. import numpy as np
  3. from sklearn.metrics import mean_absolute_error, mean_squared_error
  4. from tensorflow.python.keras.models import Sequential, Model
  5. from tensorflow.python.keras.layers import Dense, LSTM, Input
  6. from tensorflow.python.keras.optimizers import adam_v2
  7. # 数据读取和预处理
  8. data = pd.read_csv('data.csv')
  9. data_y = pd.read_csv('data.csv')
  10. data['time'] = pd.to_datetime(data['time'], format='%b-%y')
  11. data_y['time'] = pd.to_datetime(data_y['time'], format='%b-%y')
  12. n = 6
  13. for i in range(n, 0, -1):
  14. data[f'lag_{i}'] = data['incidence'].shift(n - i + 1)
  15. data = data.dropna().reset_index(drop=True)
  16. train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
  17. X_train = train_data[[f'lag_{i}' for i in range(1, n+1)]]
  18. m = 3
  19. X_train_list = []
  20. y_train_list = []
  21. for i in range(m):
  22. X_temp = X_train
  23. y_temp = data_y['incidence'].iloc[n + i:len(data_y) - m + 1 + i]
  24. X_train_list.append(X_temp)
  25. y_train_list.append(y_temp)
  26. for i in range(m):
  27. X_train_list[i] = X_train_list[i].iloc[:-(m-1)].values
  28. X_train_list[i] = X_train_list[i].reshape(X_train_list[i].shape[0], X_train_list[i].shape[1], 1)
  29. y_train_list[i] = y_train_list[i].iloc[:len(X_train_list[i])].values
  30. # 模型训练
  31. models = []
  32. for i in range(m):
  33. # Building the LSTM model
  34. inputs = Input(shape=(n, 1))
  35. x = LSTM(50, activation='relu')(inputs)
  36. x = Dense(50, activation='relu')(x)
  37. outputs = Dense(1)(x)
  38. model = Model(inputs=inputs, outputs=outputs)
  39. optimizer = adam_v2.Adam(learning_rate=0.001)
  40. model.compile(optimizer=optimizer, loss='mse')
  41. model.fit(X_train_list[i], y_train_list[i], epochs=200, batch_size=32, verbose=0)
  42. models.append(model)
  43. validation_start_time = train_data['time'].iloc[-1] + pd.DateOffset(months=1)
  44. validation_data = data[data['time'] >= validation_start_time]
  45. X_validation = validation_data[[f'lag_{i}' for i in range(1, n+1)]].values
  46. X_validation = X_validation.reshape(X_validation.shape[0], X_validation.shape[1], 1)
  47. y_validation_pred_list = [model.predict(X_validation) for model in models]
  48. y_train_pred_list = [model.predict(X_train_list[i]) for i, model in enumerate(models)]
  49. def concatenate_predictions(pred_list):
  50. concatenated = []
  51. for j in range(len(pred_list[0])):
  52. for i in range(m):
  53. concatenated.append(pred_list[i][j])
  54. return concatenated
  55. y_validation_pred = np.array(concatenate_predictions(y_validation_pred_list))[:len(validation_data['incidence'])]
  56. y_train_pred = np.array(concatenate_predictions(y_train_pred_list))[:len(train_data['incidence']) - m + 1]
  57. y_validation_pred = y_validation_pred.flatten()
  58. y_train_pred = y_train_pred.flatten()
  59. mae_validation = mean_absolute_error(validation_data['incidence'], y_validation_pred)
  60. mape_validation = np.mean(np.abs((validation_data['incidence'] - y_validation_pred) / validation_data['incidence']))
  61. mse_validation = mean_squared_error(validation_data['incidence'], y_validation_pred)
  62. rmse_validation = np.sqrt(mse_validation)
  63. mae_train = mean_absolute_error(train_data['incidence'][:-(m-1)], y_train_pred)
  64. mape_train = np.mean(np.abs((train_data['incidence'][:-(m-1)] - y_train_pred) / train_data['incidence'][:-(m-1)]))
  65. mse_train = mean_squared_error(train_data['incidence'][:-(m-1)], y_train_pred)
  66. rmse_train = np.sqrt(mse_train)
  67. print("验证集:", mae_validation, mape_validation, mse_validation, rmse_validation)
  68. print("训练集:", mae_train, mape_train, mse_train, rmse_train)

结果:

三、数据

链接:https://pan.baidu.com/s/1EFaWfHoG14h15KCEhn1STg?pwd=q41n

提取码:q41n

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/335035
推荐阅读
相关标签
  

闽ICP备14008679号