<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # Python 中長短期記憶網絡的多步時間序列預測 > 原文: [https://machinelearningmastery.com/multi-step-time-series-forecasting-long-short-term-memory-networks-python/](https://machinelearningmastery.com/multi-step-time-series-forecasting-long-short-term-memory-networks-python/) 長期短期記憶網絡或 LSTM 是一種可以學習和預測長序列的循環神經網絡。 除了學習長序列之外,LSTM 的一個好處是它們可以學習進行一次性多步預測,這對于時間序列預測可能是有用的。 LSTM 的一個難點是它們配置起來很棘手,需要大量準備才能以正確的格式獲取數據進行學習。 在本教程中,您將了解如何使用 Keras 在 Python 中開發用于多步驟時間序列預測的 LSTM。 完成本教程后,您將了解: * 如何為多步時間序列預測準備數據。 * 如何開發 LSTM 模型進行多步時間序列預測。 * 如何評估多步時間序列預測。 讓我們開始吧。 ![Multi-step Time Series Forecasting with Long Short-Term Memory Networks in Python](https://img.kancloud.cn/7f/c8/7fc8390761e184a7f8f6e6aed71a5046_640x424.jpg) Python 中長期短期記憶網絡的多步時間序列預測 [Tom Babich](https://www.flickr.com/photos/100308777@N07/10345460005/) 的照片,保留一些權利。 ## 教程概述 本教程分為 4 個部分;他們是: 1. 洗發水銷售數據集 2. 數據準備和模型評估 3. 持久性模型 4. 多步驟 LSTM ### 環境 本教程假定您已安裝 Python SciPy 環境。您可以在此示例中使用 Python 2 或 3。 本教程假設您安裝了 TensorFlow 或 Theano 后端的 Keras v2.0 或更高版本。 本教程還假設您安裝了 scikit-learn,Pandas,NumPy 和 Matplotlib。 如果您在設置 Python 環境時需要幫助,請參閱以下帖子: * [如何使用 Anaconda 設置用于機器學習和深度學習的 Python 環境](http://machinelearningmastery.com/setup-python-environment-machine-learning-deep-learning-anaconda/) 接下來,讓我們看看標準時間序列預測問題,我們可以將其用作此實驗的上下文。 ## 洗發水銷售數據集 該數據集描述了 3 年期間每月洗發水的銷售數量。 單位是銷售計數,有 36 個觀察。原始數據集歸功于 Makridakis,Wheelwright 和 Hyndman(1998)。 [您可以在此處下載并了解有關數據集的更多信息](https://datamarket.com/data/set/22r0/sales-of-shampoo-over-a-three-year-period)。 下面的示例加載并創建已加載數據集的圖。 ```py # load and plot dataset from pandas import read_csv from pandas import datetime from matplotlib import pyplot # load dataset def parser(x): return datetime.strptime('190'+x, '%Y-%m') series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser) # summarize first few rows print(series.head()) # line plot series.plot() pyplot.show() ``` 運行該示例將數據集作為 Pandas Series 加載并打印前 5 行。 ```py Month 1901-01-01 266.0 1901-02-01 145.9 1901-03-01 183.1 1901-04-01 119.3 1901-05-01 180.3 Name: Sales, dtype: float64 ``` 然后創建該系列的線圖,顯示明顯的增加趨勢。 ![Line Plot of Shampoo Sales Dataset](https://img.kancloud.cn/11/f1/11f11d2a2ec40c7c0724e4e09f11a4ca_640x480.jpg) 洗發水銷售數據集的線圖 接下來,我們將看一下實驗中使用的模型配置和測試工具。 ## 數據準備和模型評估 本節介紹本教程中使用的數據準備和模型評估 ### 數據拆分 我們將 Shampoo Sales 數據集分為兩部分:訓練和測試集。 前兩年的數據將用于訓練數據集,剩余的一年數據將用于測試集。 將使用訓練數據集開發模型,并對測試數據集進行預測。 作為參考,過去 12 個月的觀察如下: ```py "3-01",339.7 "3-02",440.4 "3-03",315.9 "3-04",439.3 "3-05",401.3 "3-06",437.4 "3-07",575.5 "3-08",407.6 "3-09",682.0 "3-10",475.3 "3-11",581.3 "3-12",646.9 ``` ### 多步預測 我們將設計一個多步預測。 對于數據集最后 12 個月的特定月份,我們將需要進行 3 個月的預測。 這是歷史觀察(t-1,t-2,... t-n)預測 t,t + 1 和 t + 2。 具體而言,從第 2 年 12??月開始,我們必須預測 1 月,2 月和 3 月。從 1 月開始,我們必須預測 2 月,3 月和 4 月。一直到 10 月,11 月,12 月預測從 9 月到 3 年。 需要總共 10 個 3 個月的預測,如下: ```py Dec, Jan, Feb, Mar Jan, Feb, Mar, Apr Feb, Mar, Apr, May Mar, Apr, May, Jun Apr, May, Jun, Jul May, Jun, Jul, Aug Jun, Jul, Aug, Sep Jul, Aug, Sep, Oct Aug, Sep, Oct, Nov Sep, Oct, Nov, Dec ``` ### 模型評估 將使用滾動預測場景,也稱為前進模型驗證。 測試數據集的每個時間步驟將一次一個地走。將使用模型對時間步長進行預測,然后將從測試集中獲取下個月的實際預期值,并使其可用于下一時間步的預測模型。 這模仿了一個真實世界的場景,每個月都會有新的洗發水銷售觀察結果,并用于下個月的預測。 這將通過訓練和測試數據集的結構進行模擬。 將收集關于測試數據集的所有預測并計算錯誤分數以總結每個預測時間步驟的模型技能。將使用均方根誤差(RMSE),因為它會對大錯誤進行處罰,并產生與預測數據相同的分數,即每月洗發水銷售額。 ## 持久性模型 時間序列預測的良好基線是持久性模型。 這是一個預測模型,其中最后一個觀察結果是持續的。由于它的簡單性,它通常被稱為樸素的預測。 您可以在帖子中了解有關時間序列預測的持久性模型的更多信息: * [如何使用 Python 進行時間序列預測的基線預測](http://machinelearningmastery.com/persistence-time-series-forecasting-with-python/) ### 準備數據 第一步是將數據從一系列轉換為監督學習問題。 這是從數字列表到輸入和輸出模式列表。我們可以使用一個名為 _series_to_supervised()_ 的預先準備的函數來實現這一點。 有關此功能的更多信息,請參閱帖子: * [如何將時間序列轉換為 Python 中的監督學習問題](http://machinelearningmastery.com/convert-time-series-supervised-learning-problem-python) 該功能如下所列。 ```py # convert time series into supervised learning problem 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() # input sequence (t-n, ... t-1) 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)] # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): 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)] # put it all together agg = concat(cols, axis=1) agg.columns = names # drop rows with NaN values if dropnan: agg.dropna(inplace=True) return agg ``` 可以通過將加載的系列值傳入 _n_in_ 值 1 和 n_out 值 3 來調用該函數;例如: ```py supervised = series_to_supervised(raw_values, 1, 3) ``` 接下來,我們可以將監督學習數據集分成訓練和測試集。 我們知道,在這種形式中,最后 10 行包含最后一年的數據。這些行包含測試集,其余數據構成訓練數據集。 我們可以將所有這些放在一個新函數中,該函數接受加載的系列和一些參數,并返回準備建模的訓練和測試集。 ```py # transform series into train and test sets for supervised learning def prepare_data(series, n_test, n_lag, n_seq): # extract raw values raw_values = series.values raw_values = raw_values.reshape(len(raw_values), 1) # transform into supervised learning problem X, y supervised = series_to_supervised(raw_values, n_lag, n_seq) supervised_values = supervised.values # split into train and test sets train, test = supervised_values[0:-n_test], supervised_values[-n_test:] return train, test ``` 我們可以使用 Shampoo 數據集對此進行測試。下面列出了完整的示例。 ```py from pandas import DataFrame from pandas import concat from pandas import read_csv from pandas import datetime # date-time parsing function for loading the dataset def parser(x): return datetime.strptime('190'+x, '%Y-%m') # convert time series into supervised learning problem 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() # input sequence (t-n, ... t-1) 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)] # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): 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)] # put it all together agg = concat(cols, axis=1) agg.columns = names # drop rows with NaN values if dropnan: agg.dropna(inplace=True) return agg # transform series into train and test sets for supervised learning def prepare_data(series, n_test, n_lag, n_seq): # extract raw values raw_values = series.values raw_values = raw_values.reshape(len(raw_values), 1) # transform into supervised learning problem X, y supervised = series_to_supervised(raw_values, n_lag, n_seq) supervised_values = supervised.values # split into train and test sets train, test = supervised_values[0:-n_test], supervised_values[-n_test:] return train, test # load dataset series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser) # configure n_lag = 1 n_seq = 3 n_test = 10 # prepare data train, test = prepare_data(series, n_test, n_lag, n_seq) print(test) print('Train: %s, Test: %s' % (train.shape, test.shape)) ``` 首先運行該示例將打印整個測試數據集,即最后 10 行。還打印了訓練測試數據集的形狀和大小。 ```py [[ 342.3 339.7 440.4 315.9] [ 339.7 440.4 315.9 439.3] [ 440.4 315.9 439.3 401.3] [ 315.9 439.3 401.3 437.4] [ 439.3 401.3 437.4 575.5] [ 401.3 437.4 575.5 407.6] [ 437.4 575.5 407.6 682\. ] [ 575.5 407.6 682\. 475.3] [ 407.6 682\. 475.3 581.3] [ 682\. 475.3 581.3 646.9]] Train: (23, 4), Test: (10, 4) ``` 我們可以看到測試數據集第一行的單個輸入值(第一列)與第二年 12 月的洗發水銷售中的觀察結果相符: ```py "2-12",342.3 ``` 我們還可以看到每行包含 4 列用于 1 個輸入,3 個輸出值用于每個觀察。 ### 進行預測 下一步是進行持久性預測。 我們可以在名為 _persistence()_ 的函數中輕松實現持久性預測,該函數將最后一次觀察和預測步驟的數量保持不變。此函數返回包含預測的數組。 ```py # make a persistence forecast def persistence(last_ob, n_seq): return [last_ob for i in range(n_seq)] ``` 然后,我們可以在測試數據集中的每個時間步驟調用此函數,從第 2 年的 12 月到第 3 年的 9 月。 下面是一個函數 _make_forecasts()_,它執行此操作并將數據集的訓練,測試和配置作為參數,并返回預測列表。 ```py # evaluate the persistence model def make_forecasts(train, test, n_lag, n_seq): forecasts = list() for i in range(len(test)): X, y = test[i, 0:n_lag], test[i, n_lag:] # make forecast forecast = persistence(X[-1], n_seq) # store the forecast forecasts.append(forecast) return forecasts ``` 我們可以調用這個函數如下: ```py forecasts = make_forecasts(train, test, 1, 3) ``` ### 評估預測 最后一步是評估預測。 我們可以通過計算多步預測的每個時間步長的 RMSE 來做到這一點,在這種情況下給出 3 個 RMSE 分數。下面的函數 _evaluate_forecasts()_ 計算并打印每個預測時間步的 RMSE。 ```py # evaluate the RMSE for each forecast time step def evaluate_forecasts(test, forecasts, n_lag, n_seq): for i in range(n_seq): actual = test[:,(n_lag+i)] predicted = [forecast[i] for forecast in forecasts] rmse = sqrt(mean_squared_error(actual, predicted)) print('t+%d RMSE: %f' % ((i+1), rmse)) ``` 我們可以這樣稱呼它: ```py evaluate_forecasts(test, forecasts, 1, 3) ``` 在原始數據集的上下文中繪制預測圖也有助于了解 RMSE 分數如何與上下文中的問題相關聯。 我們可以首先繪制整個 Shampoo 數據集,然后將每個預測繪制為紅線。下面的函數 _plot_forecasts()_ 將創建并顯示此圖。 ```py # plot the forecasts in the context of the original dataset def plot_forecasts(series, forecasts, n_test): # plot the entire dataset in blue pyplot.plot(series.values) # plot the forecasts in red for i in range(len(forecasts)): off_s = len(series) - n_test + i off_e = off_s + len(forecasts[i]) xaxis = [x for x in range(off_s, off_e)] pyplot.plot(xaxis, forecasts[i], color='red') # show the plot pyplot.show() ``` 我們可以按如下方式調用該函數。請注意,12 個月內在測試集上保留的觀察數為 12,而上述使用的 10 個監督學習輸入/輸出模式則為 10。 ```py # plot forecasts plot_forecasts(series, forecasts, 12) ``` 我們可以通過將持久預測與原始數據集中的實際持久值相關聯來使繪圖更好。 這將需要將最后觀察到的值添加到預測的前面。以下是具有此改進的 _plot_forecasts()_ 功能的更新版本。 ```py # plot the forecasts in the context of the original dataset def plot_forecasts(series, forecasts, n_test): # plot the entire dataset in blue pyplot.plot(series.values) # plot the forecasts in red for i in range(len(forecasts)): off_s = len(series) - 12 + i - 1 off_e = off_s + len(forecasts[i]) + 1 xaxis = [x for x in range(off_s, off_e)] yaxis = [series.values[off_s]] + forecasts[i] pyplot.plot(xaxis, yaxis, color='red') # show the plot pyplot.show() ``` ### 完整的例子 我們可以將所有這些部分組合在一起。 下面列出了多步持久性預測的完整代碼示例。 ```py from pandas import DataFrame from pandas import concat from pandas import read_csv from pandas import datetime from sklearn.metrics import mean_squared_error from math import sqrt from matplotlib import pyplot # date-time parsing function for loading the dataset def parser(x): return datetime.strptime('190'+x, '%Y-%m') # convert time series into supervised learning problem 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() # input sequence (t-n, ... t-1) 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)] # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): 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)] # put it all together agg = concat(cols, axis=1) agg.columns = names # drop rows with NaN values if dropnan: agg.dropna(inplace=True) return agg # transform series into train and test sets for supervised learning def prepare_data(series, n_test, n_lag, n_seq): # extract raw values raw_values = series.values raw_values = raw_values.reshape(len(raw_values), 1) # transform into supervised learning problem X, y supervised = series_to_supervised(raw_values, n_lag, n_seq) supervised_values = supervised.values # split into train and test sets train, test = supervised_values[0:-n_test], supervised_values[-n_test:] return train, test # make a persistence forecast def persistence(last_ob, n_seq): return [last_ob for i in range(n_seq)] # evaluate the persistence model def make_forecasts(train, test, n_lag, n_seq): forecasts = list() for i in range(len(test)): X, y = test[i, 0:n_lag], test[i, n_lag:] # make forecast forecast = persistence(X[-1], n_seq) # store the forecast forecasts.append(forecast) return forecasts # evaluate the RMSE for each forecast time step def evaluate_forecasts(test, forecasts, n_lag, n_seq): for i in range(n_seq): actual = test[:,(n_lag+i)] predicted = [forecast[i] for forecast in forecasts] rmse = sqrt(mean_squared_error(actual, predicted)) print('t+%d RMSE: %f' % ((i+1), rmse)) # plot the forecasts in the context of the original dataset def plot_forecasts(series, forecasts, n_test): # plot the entire dataset in blue pyplot.plot(series.values) # plot the forecasts in red for i in range(len(forecasts)): off_s = len(series) - n_test + i - 1 off_e = off_s + len(forecasts[i]) + 1 xaxis = [x for x in range(off_s, off_e)] yaxis = [series.values[off_s]] + forecasts[i] pyplot.plot(xaxis, yaxis, color='red') # show the plot pyplot.show() # load dataset series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser) # configure n_lag = 1 n_seq = 3 n_test = 10 # prepare data train, test = prepare_data(series, n_test, n_lag, n_seq) # make forecasts forecasts = make_forecasts(train, test, n_lag, n_seq) # evaluate forecasts evaluate_forecasts(test, forecasts, n_lag, n_seq) # plot forecasts plot_forecasts(series, forecasts, n_test+2) ``` 首先運行該示例為每個預測的時間步驟打印 RMSE。 這為我們提供了每個時間步的表現基線,我們希望 LSTM 能夠表現出色。 ```py t+1 RMSE: 144.535304 t+2 RMSE: 86.479905 t+3 RMSE: 121.149168 ``` 還創建了原始時間序列與多步持久性預測的關系圖。這些行連接到每個預測的相應輸入值。 此上下文顯示了持久性預測實際上是多么幼稚。 ![Line Plot of Shampoo Sales Dataset with Multi-Step Persistence Forecasts](https://img.kancloud.cn/ef/18/ef18af120bffe18d01d9f15920f72b05_640x480.jpg) 具有多步持續性預測的洗發水銷售數據集線圖 ## 多步 LSTM 網絡 在本節中,我們將使用持久性示例作為起點,并查看將 LSTM 擬合到訓練數據所需的更改,并對測試數據集進行多步預測。 ### 準備數據 在我們使用它來訓練 LSTM 之前,必須準備好數據。 具體而言,還需要進行兩項更改: 1. **固定**。數據顯示必須通過差分消除的增加趨勢。 2. **比例**。必須將數據的比例縮小到-1 到 1 之間的值,即 LSTM 單元的激活功能。 我們可以引入一個函數使數據靜止稱為 _difference()_。這會將一系列值轉換為一系列差異,這是一種更簡單的表示方式。 ```py # create a differenced series def difference(dataset, interval=1): diff = list() for i in range(interval, len(dataset)): value = dataset[i] - dataset[i - interval] diff.append(value) return Series(diff) ``` 我們可以使用 sklearn 庫中的 _MinMaxScaler_ 來縮放數據。 將這些放在一起,我們可以更新 _prepare_data()_ 函數以首先區分數據并重新調整它,然后執行轉換為監督學習問題并訓練測試集,就像我們之前使用持久性示例一樣。 除了訓練和測試數據集之外,該函數現在返回一個縮放器。 ```py # transform series into train and test sets for supervised learning def prepare_data(series, n_test, n_lag, n_seq): # extract raw values raw_values = series.values # transform data to be stationary diff_series = difference(raw_values, 1) diff_values = diff_series.values diff_values = diff_values.reshape(len(diff_values), 1) # rescale values to -1, 1 scaler = MinMaxScaler(feature_range=(-1, 1)) scaled_values = scaler.fit_transform(diff_values) scaled_values = scaled_values.reshape(len(scaled_values), 1) # transform into supervised learning problem X, y supervised = series_to_supervised(scaled_values, n_lag, n_seq) supervised_values = supervised.values # split into train and test sets train, test = supervised_values[0:-n_test], supervised_values[-n_test:] return scaler, train, test ``` 我們可以調用這個函數如下: ```py # prepare data scaler, train, test = prepare_data(series, n_test, n_lag, n_seq) ``` ### 適合 LSTM 網絡 接下來,我們需要將 LSTM 網絡模型與訓練數據相匹配。 這首先要求將訓練數據集從 2D 陣列[_ 樣本,特征 _]轉換為 3D 陣列[_ 樣本,時間步長,特征 _]。我們將時間步長固定為 1,因此這種變化很簡單。 接下來,我們需要設計一個 LSTM 網絡。我們將使用一個簡單的結構,其中 1 個隱藏層具有 1 個 LSTM 單元,然后是具有線性激活和 3 個輸出值的輸出層。網絡將使用均方誤差丟失函數和有效的 ADAM 優化算法。 LSTM 是有狀態的;這意味著我們必須在每個訓練時代結束時手動重置網絡狀態。該網絡將適合 1500 個時代。 必須使用相同的批量大小進行訓練和預測,并且我們需要在測試數據集的每個時間步進行預測。這意味著必須使用批量大小為 1。批量大小為 1 也稱為在線學習,因為在每個訓練模式之后的訓練期間將更新網絡權重(與小批量或批量更新相反)。 我們可以將所有這些放在一個名為 _fit_lstm()_ 的函數中。該函數采用了許多可用于稍后調整網絡的關鍵參數,并且該函數返回適合 LSTM 模型以備預測。 ```py # fit an LSTM network to training data def fit_lstm(train, n_lag, n_seq, n_batch, nb_epoch, n_neurons): # reshape training into [samples, timesteps, features] X, y = train[:, 0:n_lag], train[:, n_lag:] X = X.reshape(X.shape[0], 1, X.shape[1]) # design network model = Sequential() model.add(LSTM(n_neurons, batch_input_shape=(n_batch, X.shape[1], X.shape[2]), stateful=True)) model.add(Dense(y.shape[1])) model.compile(loss='mean_squared_error', optimizer='adam') # fit network for i in range(nb_epoch): model.fit(X, y, epochs=1, batch_size=n_batch, verbose=0, shuffle=False) model.reset_states() return model ``` 該函數可以調用如下: ```py # fit model model = fit_lstm(train, 1, 3, 1, 1500, 1) ``` 網絡配置沒有調整;如果你愿意,嘗試不同的參數。 在下面的評論中報告您的發現。我很想看看你能得到什么。 ### 進行 LSTM 預測 下一步是使用適合的 LSTM 網絡進行預測。 通過調用 _model.predict()_,可以使用擬合 LSTM 網絡進行單個預測。同樣,必須將數據格式化為具有[_ 樣本,時間步長,特征 _]格式的 3D 陣列。 我們可以將它包裝成一個名為 _forecast_lstm()_ 的函數。 ```py # make one forecast with an LSTM, def forecast_lstm(model, X, n_batch): # reshape input pattern to [samples, timesteps, features] X = X.reshape(1, 1, len(X)) # make forecast forecast = model.predict(X, batch_size=n_batch) # convert to array return [x for x in forecast[0, :]] ``` 我們可以從 _make_forecasts()_ 函數調用此函數并更新它以接受模型作為參數。更新版本如下所示。 ```py # evaluate the persistence model def make_forecasts(model, n_batch, train, test, n_lag, n_seq): forecasts = list() for i in range(len(test)): X, y = test[i, 0:n_lag], test[i, n_lag:] # make forecast forecast = forecast_lstm(model, X, n_batch) # store the forecast forecasts.append(forecast) return forecasts ``` 可以按如下方式調用 _make_forecasts()_ 函數的更新版本: ```py # make forecasts forecasts = make_forecasts(model, 1, train, test, 1, 3) ``` ### 反轉變換 在做出預測之后,我們需要反轉變換以將值返回到原始比例。 這是必要的,以便我們可以計算與其他模型相當的錯誤分數和圖,例如上面的持久性預測。 我們可以使用提供 _inverse_transform()_ 函數的 _MinMaxScaler_ 對象直接反轉預測的比例。 我們可以通過將最后一個觀察值(前幾個月的洗發水銷售額)添加到第一個預測值來反轉差異,然后將值傳播到預測值之下。 這有點兒繁瑣;我們可以在函數名 _inverse_difference()_ 中包含行為,它將預測之前的最后觀察值和預測作為參數,并返回反向預測。 ```py # invert differenced forecast def inverse_difference(last_ob, forecast): # invert first forecast inverted = list() inverted.append(forecast[0] + last_ob) # propagate difference forecast using inverted first value for i in range(1, len(forecast)): inverted.append(forecast[i] + inverted[i-1]) return inverted ``` 將它們放在一起,我們可以創建一個 _inverse_transform()_ 函數,該函數可以處理每個預測,首先反轉比例,然后反轉差異,將預測恢復到原始比例。 ```py # inverse data transform on forecasts def inverse_transform(series, forecasts, scaler, n_test): inverted = list() for i in range(len(forecasts)): # create array from forecast forecast = array(forecasts[i]) forecast = forecast.reshape(1, len(forecast)) # invert scaling inv_scale = scaler.inverse_transform(forecast) inv_scale = inv_scale[0, :] # invert differencing index = len(series) - n_test + i - 1 last_ob = series.values[index] inv_diff = inverse_difference(last_ob, inv_scale) # store inverted.append(inv_diff) return inverted ``` 我們可以使用以下預測來調用此函數: ```py # inverse transform forecasts and test forecasts = inverse_transform(series, forecasts, scaler, n_test+2) ``` 我們還可以反轉輸出部分測試數據集上的變換,以便我們可以正確計算 RMSE 分數,如下所示: ```py actual = [row[n_lag:] for row in test] actual = inverse_transform(series, actual, scaler, n_test+2) ``` 我們還可以簡化 RMSE 分數的計算,以期望測試數據僅包含輸出值,如下所示: ```py def evaluate_forecasts(test, forecasts, n_lag, n_seq): for i in range(n_seq): actual = [row[i] for row in test] predicted = [forecast[i] for forecast in forecasts] rmse = sqrt(mean_squared_error(actual, predicted)) print('t+%d RMSE: %f' % ((i+1), rmse)) ``` ### 完整的例子 我們可以將所有這些部分組合在一起,使 LSTM 網絡適應多步驟時間序列預測問題。 完整的代碼清單如下。 ```py from pandas import DataFrame from pandas import Series from pandas import concat from pandas import read_csv from pandas import datetime from sklearn.metrics import mean_squared_error from sklearn.preprocessing import MinMaxScaler from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM from math import sqrt from matplotlib import pyplot from numpy import array # date-time parsing function for loading the dataset def parser(x): return datetime.strptime('190'+x, '%Y-%m') # convert time series into supervised learning problem 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() # input sequence (t-n, ... t-1) 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)] # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): 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)] # put it all together agg = concat(cols, axis=1) agg.columns = names # drop rows with NaN values if dropnan: agg.dropna(inplace=True) return agg # create a differenced series def difference(dataset, interval=1): diff = list() for i in range(interval, len(dataset)): value = dataset[i] - dataset[i - interval] diff.append(value) return Series(diff) # transform series into train and test sets for supervised learning def prepare_data(series, n_test, n_lag, n_seq): # extract raw values raw_values = series.values # transform data to be stationary diff_series = difference(raw_values, 1) diff_values = diff_series.values diff_values = diff_values.reshape(len(diff_values), 1) # rescale values to -1, 1 scaler = MinMaxScaler(feature_range=(-1, 1)) scaled_values = scaler.fit_transform(diff_values) scaled_values = scaled_values.reshape(len(scaled_values), 1) # transform into supervised learning problem X, y supervised = series_to_supervised(scaled_values, n_lag, n_seq) supervised_values = supervised.values # split into train and test sets train, test = supervised_values[0:-n_test], supervised_values[-n_test:] return scaler, train, test # fit an LSTM network to training data def fit_lstm(train, n_lag, n_seq, n_batch, nb_epoch, n_neurons): # reshape training into [samples, timesteps, features] X, y = train[:, 0:n_lag], train[:, n_lag:] X = X.reshape(X.shape[0], 1, X.shape[1]) # design network model = Sequential() model.add(LSTM(n_neurons, batch_input_shape=(n_batch, X.shape[1], X.shape[2]), stateful=True)) model.add(Dense(y.shape[1])) model.compile(loss='mean_squared_error', optimizer='adam') # fit network for i in range(nb_epoch): model.fit(X, y, epochs=1, batch_size=n_batch, verbose=0, shuffle=False) model.reset_states() return model # make one forecast with an LSTM, def forecast_lstm(model, X, n_batch): # reshape input pattern to [samples, timesteps, features] X = X.reshape(1, 1, len(X)) # make forecast forecast = model.predict(X, batch_size=n_batch) # convert to array return [x for x in forecast[0, :]] # evaluate the persistence model def make_forecasts(model, n_batch, train, test, n_lag, n_seq): forecasts = list() for i in range(len(test)): X, y = test[i, 0:n_lag], test[i, n_lag:] # make forecast forecast = forecast_lstm(model, X, n_batch) # store the forecast forecasts.append(forecast) return forecasts # invert differenced forecast def inverse_difference(last_ob, forecast): # invert first forecast inverted = list() inverted.append(forecast[0] + last_ob) # propagate difference forecast using inverted first value for i in range(1, len(forecast)): inverted.append(forecast[i] + inverted[i-1]) return inverted # inverse data transform on forecasts def inverse_transform(series, forecasts, scaler, n_test): inverted = list() for i in range(len(forecasts)): # create array from forecast forecast = array(forecasts[i]) forecast = forecast.reshape(1, len(forecast)) # invert scaling inv_scale = scaler.inverse_transform(forecast) inv_scale = inv_scale[0, :] # invert differencing index = len(series) - n_test + i - 1 last_ob = series.values[index] inv_diff = inverse_difference(last_ob, inv_scale) # store inverted.append(inv_diff) return inverted # evaluate the RMSE for each forecast time step def evaluate_forecasts(test, forecasts, n_lag, n_seq): for i in range(n_seq): actual = [row[i] for row in test] predicted = [forecast[i] for forecast in forecasts] rmse = sqrt(mean_squared_error(actual, predicted)) print('t+%d RMSE: %f' % ((i+1), rmse)) # plot the forecasts in the context of the original dataset def plot_forecasts(series, forecasts, n_test): # plot the entire dataset in blue pyplot.plot(series.values) # plot the forecasts in red for i in range(len(forecasts)): off_s = len(series) - n_test + i - 1 off_e = off_s + len(forecasts[i]) + 1 xaxis = [x for x in range(off_s, off_e)] yaxis = [series.values[off_s]] + forecasts[i] pyplot.plot(xaxis, yaxis, color='red') # show the plot pyplot.show() # load dataset series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser) # configure n_lag = 1 n_seq = 3 n_test = 10 n_epochs = 1500 n_batch = 1 n_neurons = 1 # prepare data scaler, train, test = prepare_data(series, n_test, n_lag, n_seq) # fit model model = fit_lstm(train, n_lag, n_seq, n_batch, n_epochs, n_neurons) # make forecasts forecasts = make_forecasts(model, n_batch, train, test, n_lag, n_seq) # inverse transform forecasts and test forecasts = inverse_transform(series, forecasts, scaler, n_test+2) actual = [row[n_lag:] for row in test] actual = inverse_transform(series, actual, scaler, n_test+2) # evaluate forecasts evaluate_forecasts(actual, forecasts, n_lag, n_seq) # plot forecasts plot_forecasts(series, forecasts, n_test+2) ``` 首先運行該示例為每個預測的時間步驟打印 RMSE。 我們可以看到,每個預測時間步長的分數比持久性預測更好,在某些情況下要好得多。 這表明配置的 LSTM 確實掌握了問題的技巧。 值得注意的是,RMSE 并沒有像預期的那樣隨著預測范圍的長度而變得越來越差。這是因為 t + 2 似乎比 t + 1 更容易預測。這可能是因為向下滴答比系列中記錄的向上滴答更容易預測(這可以通過對結果進行更深入的分析來確認)。 ```py t+1 RMSE: 95.973221 t+2 RMSE: 78.872348 t+3 RMSE: 105.613951 ``` 還創建了系列(藍色)和預測(紅色)的線圖。 該圖顯示,盡管模型的技能更好,但有些預測并不是很好,而且還有很大的改進空間。 ![Line Plot of Shampoo Sales Dataset with Multi-Step LSTM Forecasts](https://img.kancloud.cn/b7/69/b769c1275c8de31e67a94a673733daf0_640x480.jpg) 洗發水銷售數據集的線圖與多步驟 LSTM 預測 ## 擴展 如果您希望超越本教程,可以考慮一些擴展。 * **更新 LSTM** 。更改示例以在新數據可用時重新安裝或更新 LSTM。一個 10 秒的訓練時期應該足以重新訓練一個新的觀察。 * **調整 LSTM** 。網格搜索教程中使用的一些 LSTM 參數,例如時期數,神經元數和層數,以查看是否可以進一步提升表現。 * **Seq2Seq** 。使用 LSTM 的編碼器 - 解碼器范例來預測每個序列,看看它是否提供任何好處。 * **時間范圍**。嘗試預測不同的時間范圍,并了解網絡的行為在不同的交付周期中如何變化。 你嘗試過這些擴展嗎? 在評論中分享您的結果;我很想聽聽它。 ## 摘要 在本教程中,您了解了如何為多步時間序列預測開發 LSTM 網絡。 具體來說,你學到了: * 如何開發多步時間序列預測的持久性模型。 * 如何開發 LSTM 網絡進行多步時間序列預測。 * 如何評估和繪制多步時間序列預測的結果。 您對 LSTM 的多步驟時間序列預測有任何疑問嗎? 在下面的評論中提出您的問題,我會盡力回答。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看