用 LSTM 做時間序列預測的一個小例子

問題:航班乘客預測
數(shù)據(jù):1949 到 1960 一共 12 年酌予,每年 12 個月的數(shù)據(jù),一共 144 個數(shù)據(jù)呕寝,單位是 1000
下載地址
目標:預測國際航班未來 1 個月的乘客數(shù)

import numpy
import matplotlib.pyplot as plt
from pandas import read_csv
import math
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
%matplotlib inline

導入數(shù)據(jù):

# load the dataset
dataframe = read_csv('international-airline-passengers.csv', usecols=[1], engine='python', skipfooter=3)
dataset = dataframe.values
# 將整型變?yōu)閒loat
dataset = dataset.astype('float32')

plt.plot(dataset)
plt.show()

從這 12 年的數(shù)據(jù)可以看到上升的趨勢唠叛,每一年內的 12 個月里又有周期性季節(jié)性的規(guī)律

需要把數(shù)據(jù)做一下轉化:

將一列變成兩列,第一列是 t 月的乘客數(shù)腻贰,第二列是 t+1 列的乘客數(shù)。
look_back 就是預測下一步所需要的 time steps:

timesteps 就是 LSTM 認為每個輸入數(shù)據(jù)與前多少個陸續(xù)輸入的數(shù)據(jù)有聯(lián)系装诡。例如具有這樣用段序列數(shù)據(jù) “…ABCDBCEDF…”银受,當 timesteps 為 3 時,在模型預測中如果輸入數(shù)據(jù)為“D”鸦采,那么之前接收的數(shù)據(jù)如果為“B”和“C”則此時的預測輸出為 B 的概率更大宾巍,之前接收的數(shù)據(jù)如果為“C”和“E”,則此時的預測輸出為 F 的概率更大渔伯。

# X is the number of passengers at a given time (t) and Y is the number of passengers at the next time (t + 1).

# convert an array of values into a dataset matrix
def create_dataset(dataset, look_back=1):
    dataX, dataY = [], []
    for i in range(len(dataset)-look_back-1):
        a = dataset[i:(i+look_back), 0]
        dataX.append(a)
        dataY.append(dataset[i + look_back, 0])
    return numpy.array(dataX), numpy.array(dataY)

# fix random seed for reproducibility
numpy.random.seed(7)

當激活函數(shù)為 sigmoid 或者 tanh 時顶霞,要把數(shù)據(jù)正則話,此時 LSTM 比較敏感
設定 67% 是訓練數(shù)據(jù)锣吼,余下的是測試數(shù)據(jù)

# normalize the dataset
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)


# split into train and test sets
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]

X=t and Y=t+1 時的數(shù)據(jù)选浑,并且此時的維度為 [samples, features]

# use this function to prepare the train and test datasets for modeling
look_back = 1
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)

投入到 LSTM 的 X 需要有這樣的結構: [samples, time steps, features],所以做一下變換

# reshape input to be [samples, time steps, features]
trainX = numpy.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
testX = numpy.reshape(testX, (testX.shape[0], 1, testX.shape[1]))

建立 LSTM 模型:
輸入層有 1 個input玄叠,隱藏層有 4 個神經(jīng)元古徒,輸出層就是預測一個值,激活函數(shù)用 sigmoid读恃,迭代 100 次隧膘,batch size 為 1

# create and fit the LSTM network
model = Sequential()
model.add(LSTM(4, input_shape=(1, look_back)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, epochs=100, batch_size=1, verbose=2)

Epoch 100/100
1s - loss: 0.0020

預測:

# make predictions
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)

計算誤差之前要先把預測數(shù)據(jù)轉換成同一單位

# invert predictions
trainPredict = scaler.inverse_transform(trainPredict)
trainY = scaler.inverse_transform([trainY])
testPredict = scaler.inverse_transform(testPredict)
testY = scaler.inverse_transform([testY])

計算 mean squared error

trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))
print('Train Score: %.2f RMSE' % (trainScore))
testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0]))
print('Test Score: %.2f RMSE' % (testScore))

Train Score: 22.92 RMSE
Test Score: 47.53 RMSE

畫出結果:藍色為原數(shù)據(jù),綠色為訓練集的預測值寺惫,紅色為測試集的預測值

# shift train predictions for plotting
trainPredictPlot = numpy.empty_like(dataset)
trainPredictPlot[:, :] = numpy.nan
trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict

# shift test predictions for plotting
testPredictPlot = numpy.empty_like(dataset)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict

# plot baseline and predictions
plt.plot(scaler.inverse_transform(dataset))
plt.plot(trainPredictPlot)
plt.plot(testPredictPlot)
plt.show()

上面的結果并不是最佳的疹吃,只是舉一個例子來看 LSTM 是如何做時間序列的預測的
可以改進的地方,最直接的 隱藏層的神經(jīng)元個數(shù)是不是變?yōu)?128 更好呢西雀,隱藏層數(shù)是不是可以變成 2 或者更多呢萨驶,time steps 如果變成 3 會不會好一點

另外感興趣的筒子可以想想,RNN 做時間序列的預測到底好不好呢 ??

參考資料:
http://machinelearningmastery.com/time-series-prediction-lstm-recurrent-neural-networks-python-keras/


推薦閱讀 歷史技術博文鏈接匯總
http://www.reibang.com/p/28f02bb59fe5
也許可以找到你想要的

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末艇肴,一起剝皮案震驚了整個濱河市腔呜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌再悼,老刑警劉巖核畴,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異帮哈,居然都是意外死亡,警方通過查閱死者的電腦和手機锰镀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門娘侍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咖刃,“玉大人,你說我怎么就攤上這事憾筏『垦睿” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵氧腰,是天一觀的道長枫浙。 經(jīng)常有香客問我,道長古拴,這世上最難降的妖魔是什么箩帚? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮黄痪,結果婚禮上紧帕,老公的妹妹穿的比我還像新娘。我一直安慰自己桅打,他們只是感情好是嗜,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挺尾,像睡著了一般鹅搪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上遭铺,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天丽柿,我揣著相機與錄音,去河邊找鬼掂僵。 笑死航厚,一個胖子當著我的面吹牛,可吹牛的內容都是我干的锰蓬。 我是一名探鬼主播幔睬,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼芹扭!你這毒婦竟也來了麻顶?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤舱卡,失蹤者是張志新(化名)和其女友劉穎辅肾,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轮锥,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡矫钓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片新娜。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡赵辕,死狀恐怖,靈堂內的尸體忽然破棺而出概龄,到底是詐尸還是另有隱情还惠,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布私杜,位于F島的核電站蚕键,受9級特大地震影響,放射性物質發(fā)生泄漏衰粹。R本人自食惡果不足惜锣光,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一挨厚、第九天 我趴在偏房一處隱蔽的房頂上張望膳音。 院中可真熱鬧,春花似錦敛滋、人聲如沸田篇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泊柬。三九已至椎镣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兽赁,已是汗流浹背状答。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留刀崖,地道東北人惊科。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像亮钦,于是被迫代替她去往敵國和親馆截。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內容