前言
前面寫了一個RNN對股票走勢的預測,可以看到回圈神經網路在時序問題上面的表現還是非常不錯的,本次就用RNN的改進版本LSTM(長短時記憶神經網路)再做一個時間序列問題,看看LSTM的效果怎么樣,
資料集可視化
本次資料集采用statsmodels庫中的二訊訓碳資料集,資料集可以通過匯入statsmodels庫直接獲取,首先匯入本次任務可能用到的庫:
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
import numpy as np
import itertools
from tensorflow import keras
from tensorflow.keras import layers
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
from sklearn.preprocessing import MinMaxScaler
import statsmodels.api as sm
import matplotlib.dates as dates
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import math
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, LSTM
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from keras import optimizers
import time
讀入資料,并對資料集進行可視化:
#資料讀入可視化
data=sm.datasets.co2.load()
index = pd.date_range(start=data.data['date'][0].decode('utf-8'),periods=len(data.data),freq='W-SAT')
data=pd.DataFrame(data.data['co2'], index=index, columns=['co2'])
data = data['co2'].resample('MS').mean()
data = data.fillna(data.bfill())
plt.figure(figsize=(20, 10))
plt.plot(data,color='r')
plt.ylabel('co2')
plt.xlabel('date')
plt.show()
整體資料呈下圖趨勢:

資料預處理
資料預處理方面主要進行歸一化處理,其他操作也可以自己進行嘗試,資料歸一化后就進行訓練集和測驗集的劃分,直接選取train_test_split函式進行劃分,訓練集占全部資料集的70%,測驗集占全部資料集的30%,代碼如下:
#資料預處理和訓練集,測驗集構建
data = data.values
scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(data.reshape(-1, 1))
x=[]
y=[]
time_back=1
for i in range(len(data)-time_back-1):
x.append(data[i:i+time_back])
y.append(data[i+time_back])
x=np.array(x)
y=np.array(y)
from sklearn.model_selection import train_test_split
trainX, testX, trainY, testY = train_test_split(x, y, test_size=0.3)
LSTM模型構建及訓練
模型構建方面還是采取簡單構建,中間層數都可以自行添加或者刪減,激活函式全部都是采用sigmoid函式,因為資料集比較簡單且量小,所以模型差異不會太大,
#LSTM模型構建以及訓練
model=tf.keras.models.Sequential([
tf.keras.layers.LSTM(input_dim=1, units=50, return_sequences=True),
tf.keras.layers.LSTM(input_dim=50, units=100, return_sequences=True),
tf.keras.layers.LSTM(input_dim=100, units=200, return_sequences=True),
tf.keras.layers.LSTM(300, return_sequences=False),
tf.keras.layers.Dense(units=100),
tf.keras.layers.Dense(units=1)
])
model.add(Activation('sigmoid')) #激活函式可以自選
start = time.time()
model.summary()
model.compile(optimizer=keras.optimizers.Adam(0.01),loss=keras.losses.mean_squared_error)
model_information=model.fit(trainX,trainY,epochs=100,verbose=1) #模型訓練
列印模型結構看看:

可以看到模型簡單,一共也不到一百萬引數,訓練非常快,
模型訓練中損失可視化:
#模型損失可視化
information_loss=model_information.history['loss'] #模型訓練損失
def loss(information_loss):
plt.figure(figsize=(12, 8))
plt.plot(information_loss)
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.show()
loss(information_loss)
模型損失如下圖:

可以看到損失函式收斂,最終也是趨于平穩,穩定在0.001左右,
測驗集預測
最后用訓練好的模型對測驗集進行預測,然后對比預測結果和真實值的對比,
#對測驗集進行預測
testPredict = model.predict(testX)#這里預測出的結果也是在0-1之間的,這次就沒做反歸一化了,做不做效果都一樣
#測驗集進行可視化
plt.figure(figsize=(15, 5))
plt.plot(range(len(testPredict)), testPredict, label='prediction', lineWidth=1)
plt.plot(range(len(testY)), testY, label='true', lineWidth=1)
plt.ylabel('co2')
plt.xlabel('date')
plt.legend()
plt.title("prediction and true")
plt.show()
預測結果和真實值的可視化對比,可以看到效果還是非常好的,趨勢和范圍基本一致,大家也可以自己嘗試一下,

原始碼也可以通過以下地址獲取:https://github.com/CquptDJ/CquptDJ/tree/main
寫在最后
上次RNN遇到了一個預測結果滯后問題,這次其實開始也是這樣,后來找了一下問題,發現問題出在測驗集劃分上,上次是直接按時間順序劃分測驗集,前面80%是訓練集,后面20%作為測驗集,這樣劃分就出現了一個滯后問題(可以看前面那篇RNN文章),但是這次我采用train_test_split函式進行隨機劃分后就沒有出現這種問題了,我也有點懵逼,暫時還沒想通是怎么回事,如果有大佬知道歡迎評論!本人才疏學淺,如果有錯誤或者理解不到位的地方請指正!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/289435.html
標籤:AI
