分別用CNN犁功、GRU和LSTM實現(xiàn)時間序列預測(2019-04-06)

卷積神經網絡(CNN)浸卦、長短期記憶網絡(LSTM)以及門控單元網絡(GRU)是最常見的一類算法案糙,在kaggle比賽中經常被用來做預測和回歸靴庆。今天怒医,我們就拋磚引玉,做一個簡單的教程焰薄,如何用這些網絡預測時間序列扒袖。因為是做一個簡單教程季率,所以本例子中網絡的層數(shù)和每層的神經元個數(shù)沒有調試到最佳。根據不同的數(shù)據集飒泻,同學們可以自己調網絡結構和具體參數(shù)蠢络。


1.環(huán)境搭建

我們運行的環(huán)境是下載anaconda,然后在里面安裝keras刹孔,打開spyder運行程序即可髓霞。其中下載anaconda和安裝keras的教程在我們另一個博客“用CNN做電能質量擾動分類(2019-03-28)”中寫過了,這里就不贅述了结序。

2.數(shù)據集下載

下載時間序列數(shù)據集和程序纵潦。其中,網盤連接是:

https://pan.baidu.com/s/1TASK3gMZoDFvoE89LzR-5A返敬,密碼是“o0sl”寥院。

“nihe.csv”是我自己做的一個時間序列的數(shù)據集,一共有1000行4列其中凛澎,1-3列可以認為是X,第4列認為是Y沫换。我們現(xiàn)在要做的就是訓練3個X和Y之間的關系轧叽,然后給定X去預測Y刊棕。

3.預測

把下載的nihe.csv文件放到spyder 的默認路徑下,我的默認路徑是“D:\Matlab2018a\42”网严,新建一個.py文件嗤无,把程序放進去,運行即可铺峭。

4.CNN,LSTM,GRU預測時間序列的程序

1)GRU的程序

#1. load dataset

from pandas import read_csv

dataset = read_csv('nihe.csv')

values = dataset.values

#2.tranform data to [0,1]

from sklearn.preprocessing importMinMaxScaler

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

XY= scaler.fit_transform(values)

X= XY[:,0:3]?? ?

Y = XY[:,3]

#3.split into train and test sets

n_train_hours = 950

trainX = X[:n_train_hours, :]

trainY =Y[:n_train_hours]

testX = X[n_train_hours:, :]

testY =Y[n_train_hours:]

train3DX =trainX.reshape((trainX.shape[0], 1, trainX.shape[1]))

test3DX = testX.reshape((testX.shape[0],1, testX.shape[1]))

#4. Define Network

from keras.models importSequential

from keras.layers import Dense

from keras.layers.recurrentimport GRU

model = Sequential()

model.add(GRU(units=5,input_shape=(train3DX.shape[1],train3DX.shape[2]),return_sequences=True))

model.add(GRU(units=3))

model.add(Dense(units=4,kernel_initializer='normal',activation='relu'))????

model.add(Dense(units=1,kernel_initializer='normal',activation='sigmoid'))?

#最后輸出層1個神經元和輸出的個數(shù)對應

# 5. compile the network

model.compile(loss='mae',optimizer='adam')

# 6. fit the network

history =model.fit(train3DX,trainY, epochs=100, batch_size=10,validation_data=(test3DX,testY), verbose=2, shuffle=False)

# 7. evaluate the network

from matplotlib import pyplot

pyplot.plot(history.history['loss'],label='train')

pyplot.plot(history.history['val_loss'],label='test')

pyplot.legend()

pyplot.show()

#8. make a prediction and invertscaling for forecast

from pandas import concat

forecasttestY0 =model.predict(test3DX)

inv_yhat=np.concatenate((testX,forecasttestY0), axis=1)

inv_y =scaler.inverse_transform(inv_yhat)

forecasttestY = inv_y[:,3]

# calculate RMSE

from math import sqrt

from sklearn.metrics importmean_squared_error

actualtestY=values[n_train_hours:,3]

rmse = sqrt(mean_squared_error(forecasttestY,actualtestY))

print('Test RMSE: %.3f' % rmse)

#plot the testY and actualtestY

pyplot.plot(actualtestY,label='train')

pyplot.plot(forecasttestY,label='test')

pyplot.legend()

pyplot.show()


2)LSTM的程序

#1. load dataset

from pandas import read_csv

dataset = read_csv('nihe.csv')

values = dataset.values

#2.tranform data to [0,1]

from sklearn.preprocessing importMinMaxScaler

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

XY= scaler.fit_transform(values)

X= XY[:,0:3]???

Y = XY[:,3]

#3.split into train and test sets

n_train_hours = 950

trainX = X[:n_train_hours, :]

trainY =Y[:n_train_hours]

testX = X[n_train_hours:, :]

testY =Y[n_train_hours:]

train3DX =trainX.reshape((trainX.shape[0], 1, trainX.shape[1]))

test3DX = testX.reshape((testX.shape[0],1, testX.shape[1]))

#4. Define Network

from keras.models importSequential

from keras.layers import Dense

from keras.layers.recurrentimport LSTM

model = Sequential()

model.add(LSTM(units=5,input_shape=(train3DX.shape[1],train3DX.shape[2]),return_sequences=True))

model.add(LSTM(units=3))

model.add(Dense(units=4,kernel_initializer='normal',activation='relu'))????

model.add(Dense(units=1,kernel_initializer='normal',activation='sigmoid'))?

#最后輸出層1個神經元和輸出的個數(shù)對應

# 5. compile the network

model.compile(loss='mae',optimizer='adam')

# 6. fit the network

history =model.fit(train3DX,trainY, epochs=100, batch_size=10,validation_data=(test3DX,testY), verbose=2, shuffle=False)

# 7. evaluate the network

from matplotlib import pyplot

pyplot.plot(history.history['loss'],label='train')

pyplot.plot(history.history['val_loss'],label='test')

pyplot.legend()

pyplot.show()

#8. make a prediction and invertscaling for forecast

from pandas import concat

import numpy as np

forecasttestY0 =model.predict(test3DX)

#forecasttestY= np.expand_dims(a,axis=1)

inv_yhat=np.concatenate((testX,forecasttestY0), axis=1)

inv_y =scaler.inverse_transform(inv_yhat)

forecasttestY = inv_y[:,3]

# calculate RMSE

from math import sqrt

from sklearn.metrics importmean_squared_error

actualtestY=values[n_train_hours:,3]

rmse =sqrt(mean_squared_error(forecasttestY, actualtestY))

print('Test RMSE: %.3f' % rmse)

#plot the testY and actualtestY

pyplot.plot(actualtestY,label='train')

pyplot.plot(forecasttestY,label='test')

pyplot.legend()

pyplot.show()



3)CNN和LSTM的合并

#1. load dataset

from pandas import read_csv

dataset = read_csv('nihe.csv')

values = dataset.values

#2.tranform data to [0,1]? 3個屬性,第4個是待預測量

from sklearn.preprocessing importMinMaxScaler

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

XY= scaler.fit_transform(values)

X= XY[:,0:3]???

Y = XY[:,3]

#3.split into train and test sets

950個訓練集桑李,剩下的都是驗證集

n_train_hours = 950

trainX = X[:n_train_hours, :]

trainY =Y[:n_train_hours]

testX = X[n_train_hours:, :]

testY =Y[n_train_hours:]

#LSTM的輸入格式要3維奠支,因此先做變換

train3DX =trainX.reshape((trainX.shape[0], 1, trainX.shape[1]))

test3DX =testX.reshape((testX.shape[0], 1, testX.shape[1]))

#4. Define Network

from keras.models importSequential

from keras.layers import Dense

from keras.layers.recurrentimport LSTM

from keras.layers.convolutionalimport Conv1D

from keras.layers.convolutionalimport MaxPooling1D

from keras.layers import Flatten

model = Sequential()

model.add(Conv1D(filters=10,kernel_size=1, padding='same', strides=1, activation='relu',input_shape=(1,3)))

model.add(MaxPooling1D(pool_size=1))

model.add(LSTM(units=3,return_sequences=True))

model.add(Flatten())

#可以把LSTM和Flatten刪除,僅保留LSTM

#model.add(LSTM(units=3))?

model.add(Dense(5,activation='relu'))

#在lstm層之后可以添加隱含層倍谜,也可以不加,直接加輸出層

#model.add(Dense(units=4,kernel_initializer='normal',activation='relu'))?

model.add(Dense(units=1,kernel_initializer='normal',activation='sigmoid'))??????

?#最后輸出層1個神經元和輸出的個數(shù)對應

# 5. compile the network

model.compile(loss='mae',optimizer='adam')

# 6. fit the network

history =model.fit(train3DX,trainY, epochs=100, batch_size=10,validation_data=(test3DX,testY), verbose=2, shuffle=False)

# 7. evaluate the network

from matplotlib import pyplot

pyplot.plot(history.history['loss'],label='train')

pyplot.plot(history.history['val_loss'],label='test')

pyplot.legend()

pyplot.show()

#8. make a prediction and invertscaling for forecast

from pandas import concat

import numpy as np

forecasttestY0 =model.predict(test3DX)

inv_yhat=np.concatenate((testX,forecasttestY0), axis=1)

inv_y =scaler.inverse_transform(inv_yhat)

forecasttestY = inv_y[:,3]

# calculate RMSE

from math import sqrt

from sklearn.metrics importmean_squared_error

actualtestY=values[n_train_hours:,3]

rmse =sqrt(mean_squared_error(forecasttestY, actualtestY))

print('Test RMSE: %.3f' % rmse)

#plot the testY and actualtestY

pyplot.plot(actualtestY,label='train')

pyplot.plot(forecasttestY,label='test')

pyplot.legend()

pyplot.show()

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市您旁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蚕脏,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秦驯,死亡現(xiàn)場離奇詭異挣棕,居然都是意外死亡,警方通過查閱死者的電腦和手機固耘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門词身,熙熙樓的掌柜王于貴愁眉苦臉地迎上來法严,“玉大人,你說我怎么就攤上這事深啤。” “怎么了诱桂?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵访诱,是天一觀的道長韩肝。 經常有香客問我,道長哀峻,這世上最難降的妖魔是什么剩蟀? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮丙号,結果婚禮上,老公的妹妹穿的比我還像新娘犬缨。我一直安慰自己,他們只是感情好刺彩,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布创倔。 她就那樣靜靜地躺著焚碌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪呐能。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音偎漫,去河邊找鬼有缆。 笑死,一個胖子當著我的面吹牛杯矩,可吹牛的內容都是我干的袖外。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼泌射,長吁一口氣:“原來是場噩夢啊……” “哼鬓照!你這毒婦竟也來了?” 一聲冷哼從身側響起拒秘,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咙轩,沒想到半個月后阴颖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡钾菊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年煞烫,在試婚紗的時候發(fā)現(xiàn)自己被綠了累颂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡料饥,死狀恐怖朱监,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情赫编,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布悦荒,位于F島的核電站搬味,受9級特大地震影響躺苦,放射性物質發(fā)生泄漏。R本人自食惡果不足惜匹厘,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一愈诚、第九天 我趴在偏房一處隱蔽的房頂上張望牛隅。 院中可真熱鬧酌泰,春花似錦、人聲如沸陵刹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽羡宙。三九已至,卻和暖如春钞馁,著一層夾襖步出監(jiān)牢的瞬間匿刮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工允悦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留虑啤,地道東北人架馋。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓叉寂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親屏鳍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內容