Python時間序列LSTM預測系列學習筆記(10)-多步預測
阿新 • • 發佈:2018-12-08
本文是對:
https://blog.csdn.net/iyangdi/article/details/77881755
博文的學習筆記,博主筆風都很浪,有些細節一筆帶過,本人以謙遜的態度進行了學習和整理,筆記內容都在程式碼的註釋中。有不清楚的可以去原博主文中檢視。
資料集下載:https://datamarket.com/data/set/22r0/sales-of-shampoo-over-a-three-year-period
後期我會補上我的github
本文主要是告訴我們一種多步預測的方法。
什麼是多步預測?可以理解為我取最新的3條資料去預測下一條資料,再用最近的2條資料和剛預測出來的1條資料去重新進行預測。
文章中沒有對資料進行正常的預測,只是簡單的把最後一次觀測值作為預測值,演示了一下多步預測的流程,最後算了一下損失函式的數值。
資料上並沒有參考意義,所以最後做出的圖形也沒有參考意義,我們只需理解其思路即可。
本人對文章的批註都載入程式碼的註釋中,文章整理如下:
資料準備與模型評估
1、拆分成訓練和測試資料。
訓練資料=前兩年香皂銷售資料
測試資料=剩下一年的香皂銷售資料
2、Multi-Step 預測
假設需要預測3個月的銷售資料
3、模型評估
用rolling-forcast(walk-forward)方式模型驗證
測試資料每個時間步,滑動一個值,預測;之後測試資料的下一個真實觀測值加入模型,並預測
用RMSE評估
持久模型(Persistence Model)
他是很好的時間序列預測的基準
是最簡單的預測
原理:
用當前值作為之後的預測值
# coding=utf-8 from pandas import read_csv from pandas import DataFrame from pandas import concat from sklearn.metrics import mean_squared_error from math import sqrt from matplotlib import pyplot from pandas import datetime def parser(x): return datetime.strptime(x, '%Y/%m/%d') # 把資料拆分,線性資料變成四個一組的監督型資料 def series_to_supervised(data, n_in=1, n_out=1, dropnan=True): n_vars = 1 if type(data) is list else data.shape[1] df = DataFrame(data) # 資料多了行標、列標 cols, names = list(), list() for i in range(n_in, 0, -1): cols.append(df.shift(i)) names += [('var%d(t-%d)' % (j + 1, i)) for j in range(n_vars)] for i in range(0, n_out, 1): cols.append(df.shift(-i)) if i == 0: names += [('var%d(t)' % (j + 1)) for j in range(n_vars)] else: names += [('var%d(t+%d)' % (j + 1, i)) for j in range(n_vars)] agg = concat(cols, axis=1) agg.columns = names if dropnan: agg.dropna(inplace=True) return agg # 拆分正訓練+測試資料 def prepare_data(series, n_test, n_lay, n_seq): raw_values = series.values raw_values = raw_values.reshape(len(raw_values), 1) #轉換成四個一組的監督型資料 supervised = series_to_supervised(raw_values, n_lay, n_seq) supervised_values = supervised.values # 前3/4作為訓練資料,後1/4作為預測 測試資料 train, test = supervised_values[0:-n_test], supervised_values[-n_test:] return train, test # persistence model預測 # 用上一次觀察值作為之後n_seq的預測值 # 其實只是單純的把上一次的觀測值,重複三次寫入一個包含三個元素的陣列,作為一個包含三個元素的預測結果 def persistence(last_ob, n_seq): return [last_ob for i in range(n_seq)] # 評估persistence model # 把由 def make_forcast(train, test, n_lay, n_seq): forcasts = list() for i in range(len(test)): x, y = test[i, 0:n_lag], test[i, n_lag:] # 這裡的預測其實就是抄寫上一次的觀測值,把觀測值變成一個數組列表 forcast = persistence(x[-1], n_seq) forcasts.append(forcast) return forcasts # 預測評估 # 計算預測結果的損失值,把抄寫的觀測值結果帶入運算損失值,輸出。 def evaluate_forcasts(test, forcasts, n_lag, n_seq): for i in range(n_seq): actual = test[:, (n_lag + i)] predicted = [forcast[i] for forcast in forcasts] print('predicted') print(predicted) rmse = sqrt(mean_squared_error(actual, predicted)) print('t+%d RMSE:%f' % ((i + 1), rmse)) # 1~n_seq各個長度的預測的rmse def plot_forcasts(series, forcasts, n_test): # 原始資料 pyplot.plot(series.values) # 預測資料 for i in range(len(forcasts)): off_s = len(series) - n_test + i - 1 off_e = off_s + len(forcasts[i]) + 1 xaxis = [x for x in range(off_s, off_e)] yaxis = [series.values[off_s]] + forcasts[i] print('xaxis') print(xaxis) print('yaxis') print(yaxis) print('series.values[off_s]') print(series.values[off_s]) pyplot.plot(xaxis, yaxis, color='red') pyplot.show() series = read_csv('data_set/shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser) # 一步資料,預測3步 n_lag = 1 n_seq = 3 n_test = 10 # 給了最後12個月,預測3個月,則能預測的次數是10,即10個3個月,即1,2,3->4 2,3,4->5 3,4,5->6 ... train, test = prepare_data(series, n_test, n_lag, n_seq) print('train data') print(train) print('test data') print(test) forecasts = make_forcast(train, test, n_lag, n_seq) print('forecasts') print(forecasts) # 沒有任何意義,只是為了教你如何進行多步的預測,資料全是根據最後觀測值編造的 evaluate_forcasts(test, forecasts, n_lag, n_seq) plot_forcasts(series, forecasts, n_test + 2)