簡單粗暴LSTM
LSTM進行時間序列預測
示例數據下載
點擊此處
或者:百度雲鏈接:https://pan.baidu.com/s/1jIAVEVkcpD2o3pUOfstthQ
提取碼:1qn2
此數據是1949 到 1960 一共 12 年,每年 12 個月的航班乘客數據,一共 144 個數據,單位是 1000。我們使用它來進行LSTM時間序列預測的實驗。
數據如圖所示
第一列為時間 第二列為數據
編寫代碼
頭文件
import numpy import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM import pandas as pd import os from keras.models import Sequential, load_model
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
加載數據
在這里我們設置時序數據的前65%為訓練數據 后35%為測試數據
dataframe = pd.read_csv('./international-airline-passengers.csv', usecols=[1], engine='python', skipfooter=3) dataset = dataframe.values # 將整型變為float dataset = dataset.astype('float32') #歸一化 在下一步會講解 scaler = MinMaxScaler(feature_range=(0, 1)) dataset = scaler.fit_transform(dataset) train_size = int(len(dataset) * 0.65) trainlist = dataset[:train_size] testlist = dataset[train_size:]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
對數據進行處理
LSTM進行預測需要的是時序數據 根據前timestep步預測后面的數據
假定給一個數據集
{
A,B,C->D
B,C,D->E
C,D,E->F
D,E,F->G
E,F,G->H
}
這時timestep為3,即根據前三個的數據預測后一個數據的值
所以我們需要對數據進行轉化
舉一個簡單的情況 假設一個list為[1,2,3,4,5],timestep = 2
我們轉化之后要達到的效果是
train_X | train_Y |
---|---|
[1,2] | [3] |
[2,3] | [4] |
[3,4] | [5] |
即依據前兩個值預測下一個值
對數據進行歸一化
LSTM可以不進行歸一化的操作,但是這樣會讓訓練模型的loss下降很慢。本教程如果不進行歸一化,100次迭代后loss還是很高
#上面代碼的片段講解 scaler = MinMaxScaler(feature_range=(0, 1)) dataset = scaler.fit_transform(dataset)
- 1
- 2
- 3
對數據進行處理
def create_dataset(dataset, look_back): #這里的look_back與timestep相同 dataX, dataY = [], [] for i in range(len(dataset)-look_back-1): a = dataset[i:(i+look_back)] dataX.append(a) dataY.append(dataset[i + look_back]) return numpy.array(dataX),numpy.array(dataY) #訓練數據太少 look_back並不能過大 look_back = 1 trainX,trainY = create_dataset(trainlist,look_back) testX,testY = create_dataset(testlist,look_back)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
LSTM模型
LSTM的輸入為 [samples, timesteps, features]
這里的timesteps為步數,features為維度 這里我們的數據是1維的
trainX = numpy.reshape(trainX, (trainX.shape[0], trainX.shape[1], 1)) testX = numpy.reshape(testX, (testX.shape[0], testX.shape[1] ,1 )) # create and fit the LSTM network model = Sequential() model.add(LSTM(4, input_shape=(None,1))) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') model.fit(trainX, trainY, epochs=100, batch_size=1, verbose=2) model.save(os.path.join("DATA","Test" + ".h5")) # make predictions
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
進行預測
#model = load_model(os.path.join("DATA","Test" + ".h5")) trainPredict = model.predict(trainX) testPredict = model.predict(testX) #反歸一化 trainPredict = scaler.inverse_transform(trainPredict) trainY = scaler.inverse_transform(trainY) testPredict = scaler.inverse_transform(testPredict) testY = scaler.inverse_transform(testY)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
查看結果
plt.plot(trainY) plt.plot(trainPredict[1:]) plt.show() plt.plot(testY) plt.plot(testPredict[1:]) plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
這個時候我們的結果為
參考
用 LSTM 做時間序列預測的一個小例子
Keras中文文檔-Sequential model
注:代碼已上傳