<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/time-series-forecasting-long-short-term-memory-network-python/](https://machinelearningmastery.com/time-series-forecasting-long-short-term-memory-network-python/) 長期短期記憶復發神經網絡有望學習長序列的觀察。 它似乎是時間序列預測的完美匹配,事實上,它可能是。 在本教程中,您將了解如何為單步單變量時間序列預測問題開發 LSTM 預測模型。 完成本教程后,您將了解: * 如何為預測問題制定績效基準。 * 如何為一步時間序列預測設計一個強大的測試工具。 * 如何為時間序列預測準備數據,開發和評估 LSTM 循環神經網絡。 讓我們開始吧。 * **2017 年 5 月更新**:修正了 invert_scale()函數中的錯誤,謝謝 Max。 ![Time Series Forecasting with the Long Short-Term Memory Network in Python](https://img.kancloud.cn/42/1f/421fa51db80ed06be0e72c39daff2ba1_640x480.jpg) 使用 Python 中的長短期記憶網絡進行時間序列預測 照片由 [Matt MacGillivray](https://www.flickr.com/photos/qmnonic/179791867/) 拍攝,保留一些權利。 ## 教程概述 這是一個很大的話題,我們將涉及很多方面。帶子。 本教程分為 9 個部分;他們是: 1. 洗發水銷售數據集 2. 測試設置 3. 持久性模型預測 4. LSTM 數據準備 5. LSTM 模型開發 6. LSTM 預測 7. 完整的 LSTM 示例 8. 制定穩健的結果 9. 教程擴展 ### Python 環境 本教程假定您已安裝 Python SciPy 環境。您可以在本教程中使用 Python 2 或 3。 您必須安裝帶有 TensorFlow 或 Theano 后端的 Keras(2.0 或更高版本)。 本教程還假設您安裝了 scikit-learn,Pandas,NumPy 和 Matplotlib。 如果您需要有關環境的幫助,請參閱此帖子: * [如何使用 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)。 **更新**:這是數據集的直接鏈接,可以使用: [shampoo.csv](https://raw.githubusercontent.com/jbrownlee/Datasets/master/shampoo.csv) 將數據集下載到當前工作目錄,名稱為“ _shampoo-sales.csv_ ”。請注意,您可能需要刪除 DataMarket 添加的頁腳信息。 下面的示例加載并創建已加載數據集的圖。 ```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 Monthly Shampoo Sales Dataset](https://img.kancloud.cn/11/f1/11f11d2a2ec40c7c0724e4e09f11a4ca_640x480.jpg) 每月洗發水銷售數據集的線圖 ## 實驗測試設置 我們將 Shampoo Sales 數據集分為兩部分:訓練和測試集。 前兩年的數據將用于訓練數據集,剩余的一年數據將用于測試集。 例如: ```py # split data into train and test X = series.values train, test = X[0:-12], X[-12:] ``` 將使用訓練數據集開發模型,并對測試數據集進行預測。 將使用滾動預測場景,也稱為前進模型驗證。 測試數據集的每個時間步驟將一次一個地走。將使用模型對時間步長進行預測,然后將獲取測試集的實際預期值,并使其可用于下一時間步的預測模型。 例如: ```py # walk-forward validation history = [x for x in train] predictions = list() for i in range(len(test)): # make prediction... ``` 這模仿了一個真實世界的場景,每個月都會有新的洗發水銷售觀察結果,并用于下個月的預測。 最后,將收集測試數據集的所有預測,并計算錯誤分數以總結模型的技能。將使用均方根誤差(RMSE),因為它會對大錯誤進行處罰,并產生與預測數據相同的分數,即每月洗發水銷售額。 例如: ```py from sklearn.metrics import mean_squared_error rmse = sqrt(mean_squared_error(test, predictions)) print('RMSE: %.3f' % rmse) ``` ## 持久性模型預測 具有線性增長趨勢的時間序列的良好基線預測是持久性預測。 持續性預測是使用先前時間步驟(t-1)的觀察來預測當前時間步驟(t)的觀察。 我們可以通過從訓練數據和前進驗證累積的歷史記錄中進行最后一次觀察并使用它來預測當前時間步長來實現這一點。 例如: ```py # make prediction yhat = history[-1] ``` 我們將在數組中累積所有預測,以便可以直接將它們與測試數據集進行比較。 下面列出了 Shampoo Sales 數據集上的持久性預測模型的完整示例。 ```py from pandas import read_csv from pandas import datetime from sklearn.metrics import mean_squared_error from math import sqrt 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) # split data into train and test X = series.values train, test = X[0:-12], X[-12:] # walk-forward validation history = [x for x in train] predictions = list() for i in range(len(test)): # make prediction predictions.append(history[-1]) # observation history.append(test[i]) # report performance rmse = sqrt(mean_squared_error(test, predictions)) print('RMSE: %.3f' % rmse) # line plot of observed vs predicted pyplot.plot(test) pyplot.plot(predictions) pyplot.show() ``` 運行該示例將打印出大約 136 個月洗發水銷售額的 RMSE,用于測試數據集的預測。 ```py RMSE: 136.761 ``` 還創建了測試數據集(藍色)與預測值(橙色)的線圖,顯示了上下文中的持久性模型預測。 ![Persistence Forecast of Observed vs Predicted for Shampoo Sales Dataset](https://img.kancloud.cn/52/53/52536b8ad1bf888fccbfa267af02af68_640x480.jpg) 洗發水銷售數據集的觀察與預測持續性預測 有關時間序列預測的持久性模型的更多信息,請參閱此帖子: * [如何使用 Python 進行時間序列預測的基線預測](http://machinelearningmastery.com/persistence-time-series-forecasting-with-python/) 現在我們已經在數據集上有了表現基準,我們可以開始為數據開發 LSTM 模型。 ## LSTM 數據準備 在我們將 LSTM 模型擬合到數據集之前,我們必須轉換數據。 本節分為三個步驟: 1. 將時間序列轉換為監督學習問題 2. 轉換時間序列數據,使其靜止不動。 3. 將觀察結果轉換為具有特定比例。 ### 將時間序列轉換為監督學習 Keras 中的 LSTM 模型假設您的數據分為輸入(X)和輸出(y)組件。 對于時間序列問題,我們可以通過使用從最后時間步驟(t-1)作為輸入的觀察和在當前時間步驟(t)的觀察作為輸出來實現這一點。 我們可以使用 Pandas 中的 [shift()](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.shift.html)函數來實現這一點,它會將一系列中的所有值按下指定的數字位置。我們需要移位 1 個位置,這將成為輸入變量。現在的時間序列將是輸出變量。 然后,我們可以將這兩個系列連接在一起,為監督學習創建一個 DataFrame。推下的系列將在頂部有一個新的位置,沒有任何價值。在此位置將使用 NaN(非數字)值。我們將這些 NaN 值替換為 0 值,LSTM 模型必須將其作為“系列的開頭”或“我這里沒有數據”來學習,因為沒有觀察到該數據集零銷售的月份。 下面的代碼定義了一個名為 _timeseries_to_supervised()_ 的輔助函數。它需要一個原始時間序列數據的 NumPy 數組和一個滯后或移位序列的數量來創建和用作輸入。 ```py # frame a sequence as a supervised learning problem def timeseries_to_supervised(data, lag=1): df = DataFrame(data) columns = [df.shift(i) for i in range(1, lag+1)] columns.append(df) df = concat(columns, axis=1) df.fillna(0, inplace=True) return df ``` 我們可以使用我們加載的 Shampoo Sales 數據集測試此功能,并將其轉換為監督學習問題。 ```py from pandas import read_csv from pandas import datetime from pandas import DataFrame from pandas import concat # frame a sequence as a supervised learning problem def timeseries_to_supervised(data, lag=1): df = DataFrame(data) columns = [df.shift(i) for i in range(1, lag+1)] columns.append(df) df = concat(columns, axis=1) df.fillna(0, inplace=True) return df # 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) # transform to supervised learning X = series.values supervised = timeseries_to_supervised(X, 1) print(supervised.head()) ``` 運行該示例將打印新監督學習問題的前 5 行。 ```py 0 0 0 0.000000 266.000000 1 266.000000 145.899994 2 145.899994 183.100006 3 183.100006 119.300003 4 119.300003 180.300003 ``` 有關將時間序列問題轉換為監督學習問題的更多信息,請參閱帖子: * [時間序列預測作為監督學習](http://machinelearningmastery.com/time-series-forecasting-supervised-learning/) ### 將時間序列轉換為靜止 Shampoo Sales 數據集不是固定的。 這意味著數據中的結構取決于時間。具體而言,數據呈上升趨勢。 固定數據更易于建模,很可能會產生更加熟練的預測。 可以從觀察中移除趨勢,然后將其添加回預測以將預測返回到原始比例并計算可比較的誤差分數。 消除趨勢的標準方法是區分數據。即,從當前觀察(t)中減去前一時間步驟(t-1)的觀察結果。這消除了趨勢,我們留下了差異序列,或者從一個時間步到下一個步驟的觀察結果的變化。 我們可以使用 pandas 中的 [diff()函數](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.diff.html)自動實現。或者,我們可以獲得更精細的控制并編寫我們自己的函數來執行此操作,這在這種情況下是靈活的首選。 下面是一個名為 _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) ``` 我們還需要反轉此過程,以便將差異系列的預測恢復到原始比例。 以下函數稱為 _inverse_difference()_,反轉此操作。 ```py # invert differenced value def inverse_difference(history, yhat, interval=1): return yhat + history[-interval] ``` 我們可以通過對整個系列進行差分來測試這些函數,然后將其返回到原始比例,如下所示: ```py from pandas import read_csv from pandas import datetime from pandas import Series # 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) # invert differenced value def inverse_difference(history, yhat, interval=1): return yhat + history[-interval] # 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) print(series.head()) # transform to be stationary differenced = difference(series, 1) print(differenced.head()) # invert transform inverted = list() for i in range(len(differenced)): value = inverse_difference(series, differenced[i], len(series)-i) inverted.append(value) inverted = Series(inverted) print(inverted.head()) ``` 運行該示例打印加載數據的前 5 行,然后打印差異系列的前 5 行,最后打印差異操作的前 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 0 -120.1 1 37.2 2 -63.8 3 61.0 4 -11.8 dtype: float64 0 145.9 1 183.1 2 119.3 3 180.3 4 168.5 dtype: float64 ``` 有關使時間序列固定和差分的更多信息,請參閱帖子: * [如何使用 Python 檢查時間序列數據是否固定](http://machinelearningmastery.com/time-series-data-stationary-python/) * [如何區分時間序列數據集與 Python](http://machinelearningmastery.com/difference-time-series-dataset-python/) ### 將時間序列轉換為比例 與其他神經網絡一樣,LSTM 期望數據在網絡使用的激活函數的范圍內。 LSTM 的默認激活函數是雙曲正切( _tanh_ ),它輸出介于-1 和 1 之間的值。這是時間序列數據的首選范圍。 為了使實驗公平,必須在訓練數據集上計算縮放系數(最小和最大)值,并應用于縮放測試數據集和任何預測。這是為了避免使用測試數據集中的知識污染實驗,這可能會給模型帶來小的優勢。 我們可以使用 [MinMaxScaler 類](http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html)將數據集轉換為[-1,1]范圍。與其他 scikit-learn 變換類一樣,它需要以行和列的矩陣格式提供數據。因此,我們必須在轉換之前重塑我們的 NumPy 數組。 例如: ```py # transform scale X = series.values X = X.reshape(len(X), 1) scaler = MinMaxScaler(feature_range=(-1, 1)) scaler = scaler.fit(X) scaled_X = scaler.transform(X) ``` 同樣,我們必須反轉預測的比例,以將值返回到原始比例,以便可以解釋結果并計算可比較的誤差分數。 ```py # invert transform inverted_X = scaler.inverse_transform(scaled_X) ``` 將所有這些放在一起,下面的例子改變了 Shampoo Sales 數據的規模。 ```py from pandas import read_csv from pandas import datetime from pandas import Series from sklearn.preprocessing import MinMaxScaler # 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) print(series.head()) # transform scale X = series.values X = X.reshape(len(X), 1) scaler = MinMaxScaler(feature_range=(-1, 1)) scaler = scaler.fit(X) scaled_X = scaler.transform(X) scaled_series = Series(scaled_X[:, 0]) print(scaled_series.head()) # invert transform inverted_X = scaler.inverse_transform(scaled_X) inverted_series = Series(inverted_X[:, 0]) print(inverted_series.head()) ``` 運行該示例首先打印加載數據的前 5 行,然后打印縮放數據的前 5 行,然后是縮放比例變換的前 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 0 -0.478585 1 -0.905456 2 -0.773236 3 -1.000000 4 -0.783188 dtype: float64 0 266.0 1 145.9 2 183.1 3 119.3 4 180.3 dtype: float64 ``` 現在我們知道如何為 LSTM 網絡準備數據,我們可以開始開發我們的模型了。 ## LSTM 模型開發 長短期記憶網絡(LSTM)是一種循環神經網絡(RNN)。 這種類型的網絡的一個好處是它可以學習和記住長序列,并且不依賴于預先指定的窗口滯后觀察作為輸入。 在 Keras 中,這被稱為有狀態,并且涉及在定義 LSTM 層時將“_ 有狀態 _”參數設置為“ _True_ ”。 默認情況下,Keras 中的 LSTM 層維護一批數據之間的狀態。一批數據是來自訓練數據集的固定大小的行數,用于定義在更新網絡權重之前要處理的模式數。默認情況下,批次之間的 LSTM 層中的狀態被清除,因此我們必須使 LSTM 成為有狀態。通過調用 _reset_states()_ 函數,這可以精確控制 LSTM 層的狀態何時被清除。 LSTM 層期望輸入位于具有以下尺寸的矩陣中:[_ 樣本,時間步長,特征 _]。 * **樣本**:這些是來自域的獨立觀察,通常是數據行。 * **時間步長**:這些是給定觀察的給定變量的單獨時間步長。 * **特征**:這些是在觀察時觀察到的單獨測量。 我們在如何為網絡構建 Shampoo Sales 數據集方面具有一定的靈活性。我們將保持簡單并構建問題,因為原始序列中的每個步驟都是一個單獨的樣本,具有一個時間步長和一個特征。 鑒于訓練數據集定義為 X 輸入和 y 輸出,必須將其重新整形為 Samples / TimeSteps / Features 格式,例如: ```py X, y = train[:, 0:-1], train[:, -1] X = X.reshape(X.shape[0], 1, X.shape[1]) ``` 必須在 LSTM 層中使用“ _batch_input_shape_ ”參數指定輸入數據的形狀作為元組,該元組指定讀取每批的預期觀察數,時間步數和數量特征。 批量大小通常遠小于樣本總數。它與時期的數量一起定義了網絡學習數據的速度(權重更新的頻率)。 定義 LSTM 層的最后一個導入參數是神經元的數量,也稱為內存單元或塊的數量。這是一個相當簡單的問題,1 到 5 之間的數字就足夠了。 下面的行創建了一個 LSTM 隱藏層,它還通過“ _batch_input_shape_ ”參數指定輸入層的期望值。 ```py layer = LSTM(neurons, batch_input_shape=(batch_size, X.shape[1], X.shape[2]), stateful=True) ``` 網絡需要輸出層中的單個神經元具有線性激活,以預測下一時間步驟的洗發水銷售數量。 一旦指定了網絡,就必須使用后端數學庫(例如 TensorFlow 或 Theano)將其編譯成有效的符號表示。 在編譯網絡時,我們必須指定一個損失函數和優化算法。我們將使用“ _mean_squared_error_ ”作為損失函數,因為它與我們感興趣的 RMSE 緊密匹配,以及有效的 ADAM 優化算法。 使用 Sequential Keras API 定義網絡,下面的代碼片段創建并編譯網絡。 ```py model = Sequential() model.add(LSTM(neurons, batch_input_shape=(batch_size, X.shape[1], X.shape[2]), stateful=True)) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') ``` 編譯后,它可以適合訓練數據。由于網絡是有狀態的,我們必須控制何時重置內部狀態。因此,我們必須在所需數量的時期內一次手動管理一個時期的訓練過程。 默認情況下,一個迭代內的樣本在暴露給網絡之前進行混洗。同樣,這對于 LSTM 來說是不合需要的,因為我們希望網絡在整個觀察序列中學習時建立狀態。我們可以通過將“ _shuffle_ ”設置為“ _False_ ”來禁用樣本的混洗。 此外,默認情況下,網絡會在每個時代結束時報告有關模型學習進度和技能的大量調試信息。我們可以通過將“ _verbose_ ”參數設置為“ _0_ ”的級別來禁用它。 然后我們可以在訓練時期結束時重置內部狀態,為下一次訓練迭代做好準備。 下面是一個手動使網絡適合訓練數據的循環。 ```py for i in range(nb_epoch): model.fit(X, y, epochs=1, batch_size=batch_size, verbose=0, shuffle=False) model.reset_states() ``` 綜上所述,我們可以定義一個名為 _fit_lstm()_ 的函數來訓練并返回一個 LSTM 模型。作為參數,它將訓練數據集置于監督學習格式,批量大小,多個時期和許多神經元中。 ```py def fit_lstm(train, batch_size, nb_epoch, neurons): X, y = train[:, 0:-1], train[:, -1] X = X.reshape(X.shape[0], 1, X.shape[1]) model = Sequential() model.add(LSTM(neurons, batch_input_shape=(batch_size, X.shape[1], X.shape[2]), stateful=True)) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') for i in range(nb_epoch): model.fit(X, y, epochs=1, batch_size=batch_size, verbose=0, shuffle=False) model.reset_states() return model ``` batch_size 必須設置為 1.這是因為它必須是訓練和測試數據集大小的因子。 模型上的 _predict()_ 函數也受批量大小的限制;它必須設置為 1,因為我們有興趣對測試數據進行一步預測。 我們不會在本教程中調整網絡參數;相反,我們將使用以下配置,通過一些試驗和錯誤找到: * 批量大小:1 * 時代:3000 * 神經元:4 作為本教程的擴展,您可能希望探索不同的模型參數,看看是否可以提高表現。 * **更新**:考慮嘗試 1500 個迭代和 1 個神經元,表現可能更好! 接下來,我們將了解如何使用適合的 LSTM 模型進行一步預測。 ## LSTM 預測 一旦 LSTM 模型適合訓練數據,它就可用于進行預測。 我們再次具有一定的靈活性。我們可以決定在所有訓練數據上擬合一次模型,然后從測試數據中一次預測每個新時間步驟(我們稱之為固定方法),或者我們可以重新擬合模型或更新模型的每一步作為測試數據的新觀察結果的模型都可用(我們稱之為動態方法)。 在本教程中,我們將采用固定方法來實現其簡單性,但我們希望動態方法能夠帶來更好的模型技能。 為了進行預測,我們可以在模型上調用 _predict()_ 函數。這需要 3D NumPy 數組輸入作為參數。在這種情況下,它將是一個值的數組,即前一時間步的觀察值。 _predict()_ 函數返回一個預測數組,每個輸入行一個。因為我們提供單個輸入,所以輸出將是具有一個值的 2D NumPy 數組。 我們可以在下面列出的名為 _forecast()_ 的函數中捕獲此行為。給定擬合模型,在擬合模型時使用的批量大小(例如 1)和測試數據中的行,該函數將從測試行中分離輸入數據,重新整形,并將預測作為單個返回浮點值。 ```py def forecast(model, batch_size, row): X = row[0:-1] X = X.reshape(1, 1, len(X)) yhat = model.predict(X, batch_size=batch_size) return yhat[0,0] ``` 在訓練期間,內部狀態在每個時期之后被重置。在預測時,我們不希望重置預測之間的內部狀態。事實上,我們希望模型在我們預測測試數據集中的每個時間步驟時建立狀態。 這就提出了一個問題,即在預測測試數據集之前,網絡的初始狀態是什么。 在本教程中,我們將通過對訓練數據集中的所有樣本進行預測來播種狀態。從理論上講,應該建立內部狀態,以便預測下一個時間步驟。 我們現在擁有適合 Shampoo Sales 數據集的 LSTM 網絡模型并評估其表現的所有部分。 在下一節中,我們將把所有這些部分放在一起。 ## 完整的 LSTM 示例 在本節中,我們將 LSTM 適用于 Shampoo Sales 數據集并評估模型。 這將涉及將前面部分中的所有元素匯總在一起。其中有很多,所以讓我們回顧一下: 1. 從 CSV 文件加載數據集。 2. 轉換數據集以使其適用于 LSTM 模型,包括: 1. 將數據轉換為監督學習問題。 2. 將數據轉換為靜止。 3. 轉換數據使其具有-1 到 1 的比例。 3. 將有狀態 LSTM 網絡模型擬合到訓練數據。 4. 評估測試數據上的靜態 LSTM 模型。 5. 報告預測的表現。 有關示例的一些注意事項: * 為簡潔起見,縮放和反縮放行為已移至函數 _scale()_ 和 _invert_scale()_。 * 使用縮放器在訓練數據上的擬合來縮放測試數據,這是確保測試數據的最小值/最大值不影響模型所需的。 * 調整數據變換的順序以便于首先使數據靜止,然后是監督學習問題,然后進行縮放。 * 為了方便起見,在分成訓練和測試集之前對整個數據集執行差分。我們可以在前進驗證過程中輕松收集觀察結果,并在我們前進時區分它們。為了便于閱讀,我決定反對它。 下面列出了完整的示例。 ```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 import numpy # date-time parsing function for loading the dataset def parser(x): return datetime.strptime('190'+x, '%Y-%m') # frame a sequence as a supervised learning problem def timeseries_to_supervised(data, lag=1): df = DataFrame(data) columns = [df.shift(i) for i in range(1, lag+1)] columns.append(df) df = concat(columns, axis=1) df.fillna(0, inplace=True) return df # 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) # invert differenced value def inverse_difference(history, yhat, interval=1): return yhat + history[-interval] # scale train and test data to [-1, 1] def scale(train, test): # fit scaler scaler = MinMaxScaler(feature_range=(-1, 1)) scaler = scaler.fit(train) # transform train train = train.reshape(train.shape[0], train.shape[1]) train_scaled = scaler.transform(train) # transform test test = test.reshape(test.shape[0], test.shape[1]) test_scaled = scaler.transform(test) return scaler, train_scaled, test_scaled # inverse scaling for a forecasted value def invert_scale(scaler, X, value): new_row = [x for x in X] + [value] array = numpy.array(new_row) array = array.reshape(1, len(array)) inverted = scaler.inverse_transform(array) return inverted[0, -1] # fit an LSTM network to training data def fit_lstm(train, batch_size, nb_epoch, neurons): X, y = train[:, 0:-1], train[:, -1] X = X.reshape(X.shape[0], 1, X.shape[1]) model = Sequential() model.add(LSTM(neurons, batch_input_shape=(batch_size, X.shape[1], X.shape[2]), stateful=True)) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') for i in range(nb_epoch): model.fit(X, y, epochs=1, batch_size=batch_size, verbose=0, shuffle=False) model.reset_states() return model # make a one-step forecast def forecast_lstm(model, batch_size, X): X = X.reshape(1, 1, len(X)) yhat = model.predict(X, batch_size=batch_size) return yhat[0,0] # load dataset series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser) # transform data to be stationary raw_values = series.values diff_values = difference(raw_values, 1) # transform data to be supervised learning supervised = timeseries_to_supervised(diff_values, 1) supervised_values = supervised.values # split data into train and test-sets train, test = supervised_values[0:-12], supervised_values[-12:] # transform the scale of the data scaler, train_scaled, test_scaled = scale(train, test) # fit the model lstm_model = fit_lstm(train_scaled, 1, 3000, 4) # forecast the entire training dataset to build up state for forecasting train_reshaped = train_scaled[:, 0].reshape(len(train_scaled), 1, 1) lstm_model.predict(train_reshaped, batch_size=1) # walk-forward validation on the test data predictions = list() for i in range(len(test_scaled)): # make one-step forecast X, y = test_scaled[i, 0:-1], test_scaled[i, -1] yhat = forecast_lstm(lstm_model, 1, X) # invert scaling yhat = invert_scale(scaler, X, yhat) # invert differencing yhat = inverse_difference(raw_values, yhat, len(test_scaled)+1-i) # store forecast predictions.append(yhat) expected = raw_values[len(train) + i + 1] print('Month=%d, Predicted=%f, Expected=%f' % (i+1, yhat, expected)) # report performance rmse = sqrt(mean_squared_error(raw_values[-12:], predictions)) print('Test RMSE: %.3f' % rmse) # line plot of observed vs predicted pyplot.plot(raw_values[-12:]) pyplot.plot(predictions) pyplot.show() ``` 運行該示例將在測試數據集中打印 12 個月中每個月的預期值和預測值。 該示例還打印所有預測的 RMSE。該模型顯示每月洗發水銷售量為 71.721 的 RMSE,優于達到 136.761 洗發水銷售 RMSE 的持久性模型。 隨機數用于播種 LSTM,因此,您可能會從模型的單次運行中獲得不同的結果。我們將在下一節進一步討論這個問題。 ```py Month=1, Predicted=351.582196, Expected=339.700000 Month=2, Predicted=432.169667, Expected=440.400000 Month=3, Predicted=378.064505, Expected=315.900000 Month=4, Predicted=441.370077, Expected=439.300000 Month=5, Predicted=446.872627, Expected=401.300000 Month=6, Predicted=514.021244, Expected=437.400000 Month=7, Predicted=525.608903, Expected=575.500000 Month=8, Predicted=473.072365, Expected=407.600000 Month=9, Predicted=523.126979, Expected=682.000000 Month=10, Predicted=592.274106, Expected=475.300000 Month=11, Predicted=589.299863, Expected=581.300000 Month=12, Predicted=584.149152, Expected=646.900000 Test RMSE: 71.721 ``` 還創建了測試數據(藍色)與預測值(橙色)的線圖,為模型技能提供了上下文。 ![Line Plot of LSTM Forecast vs Expected Values](https://img.kancloud.cn/ec/0c/ec0cc89698f72d0b3875a55f57d7ab99_640x480.jpg) LSTM 預測和預期值的線圖 作為 afternote,您可以進行快速實驗,以建立您對測試工具以及所有變換和逆變換的信任。 在前進驗證中注釋掉適合 LSTM 模型的行: ```py yhat = forecast_lstm(lstm_model, 1, X) ``` 并將其替換為以下內容: ```py yhat = y ``` 這應該產生具有完美技能的模型(例如,將預期結果預測為模型輸出的模型)。 結果應如下所示,表明如果 LSTM 模型能夠完美地預測該系列,則逆變換和誤差計算將正確顯示。 ```py Month=1, Predicted=339.700000, Expected=339.700000 Month=2, Predicted=440.400000, Expected=440.400000 Month=3, Predicted=315.900000, Expected=315.900000 Month=4, Predicted=439.300000, Expected=439.300000 Month=5, Predicted=401.300000, Expected=401.300000 Month=6, Predicted=437.400000, Expected=437.400000 Month=7, Predicted=575.500000, Expected=575.500000 Month=8, Predicted=407.600000, Expected=407.600000 Month=9, Predicted=682.000000, Expected=682.000000 Month=10, Predicted=475.300000, Expected=475.300000 Month=11, Predicted=581.300000, Expected=581.300000 Month=12, Predicted=646.900000, Expected=646.900000 Test RMSE: 0.000 ``` ## 制定穩健的結果 神經網絡的一個難點是它們在不同的起始條件下給出不同的結果。 一種方法可能是修復 Keras 使用的隨機數種子,以確保結果可重復。另一種方法是使用不同的實驗設置來控制隨機初始條件。 有關機器學習中隨機性的更多信息,請參閱帖子: * [在機器學習中擁抱隨機性](http://machinelearningmastery.com/randomness-in-machine-learning/) 我們可以多次重復上一節中的實驗,然后將平均 RMSE 作為預期配置在平均看不見的數據上的表現的指示。 這通常稱為多次重復或多次重啟。 我們可以在固定數量的重復循環中包裝模型擬合和前進驗證。每次迭代都可以記錄運行的 RMSE。然后我們可以總結 RMSE 分數的分布。 ```py # repeat experiment repeats = 30 error_scores = list() for r in range(repeats): # fit the model lstm_model = fit_lstm(train_scaled, 1, 3000, 4) # forecast the entire training dataset to build up state for forecasting train_reshaped = train_scaled[:, 0].reshape(len(train_scaled), 1, 1) lstm_model.predict(train_reshaped, batch_size=1) # walk-forward validation on the test data predictions = list() for i in range(len(test_scaled)): # make one-step forecast X, y = test_scaled[i, 0:-1], test_scaled[i, -1] yhat = forecast_lstm(lstm_model, 1, X) # invert scaling yhat = invert_scale(scaler, X, yhat) # invert differencing yhat = inverse_difference(raw_values, yhat, len(test_scaled)+1-i) # store forecast predictions.append(yhat) # report performance rmse = sqrt(mean_squared_error(raw_values[-12:], predictions)) print('%d) Test RMSE: %.3f' % (r+1, rmse)) error_scores.append(rmse) ``` 數據準備與以前相同。 我們將使用 30 次重復,因為這足以提供 RMSE 分數的良好分布。 下面列出了完整的示例。 ```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 import numpy # date-time parsing function for loading the dataset def parser(x): return datetime.strptime('190'+x, '%Y-%m') # frame a sequence as a supervised learning problem def timeseries_to_supervised(data, lag=1): df = DataFrame(data) columns = [df.shift(i) for i in range(1, lag+1)] columns.append(df) df = concat(columns, axis=1) df.fillna(0, inplace=True) return df # 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) # invert differenced value def inverse_difference(history, yhat, interval=1): return yhat + history[-interval] # scale train and test data to [-1, 1] def scale(train, test): # fit scaler scaler = MinMaxScaler(feature_range=(-1, 1)) scaler = scaler.fit(train) # transform train train = train.reshape(train.shape[0], train.shape[1]) train_scaled = scaler.transform(train) # transform test test = test.reshape(test.shape[0], test.shape[1]) test_scaled = scaler.transform(test) return scaler, train_scaled, test_scaled # inverse scaling for a forecasted value def invert_scale(scaler, X, value): new_row = [x for x in X] + [value] array = numpy.array(new_row) array = array.reshape(1, len(array)) inverted = scaler.inverse_transform(array) return inverted[0, -1] # fit an LSTM network to training data def fit_lstm(train, batch_size, nb_epoch, neurons): X, y = train[:, 0:-1], train[:, -1] X = X.reshape(X.shape[0], 1, X.shape[1]) model = Sequential() model.add(LSTM(neurons, batch_input_shape=(batch_size, X.shape[1], X.shape[2]), stateful=True)) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') for i in range(nb_epoch): model.fit(X, y, epochs=1, batch_size=batch_size, verbose=0, shuffle=False) model.reset_states() return model # make a one-step forecast def forecast_lstm(model, batch_size, X): X = X.reshape(1, 1, len(X)) yhat = model.predict(X, batch_size=batch_size) return yhat[0,0] # load dataset series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser) # transform data to be stationary raw_values = series.values diff_values = difference(raw_values, 1) # transform data to be supervised learning supervised = timeseries_to_supervised(diff_values, 1) supervised_values = supervised.values # split data into train and test-sets train, test = supervised_values[0:-12], supervised_values[-12:] # transform the scale of the data scaler, train_scaled, test_scaled = scale(train, test) # repeat experiment repeats = 30 error_scores = list() for r in range(repeats): # fit the model lstm_model = fit_lstm(train_scaled, 1, 3000, 4) # forecast the entire training dataset to build up state for forecasting train_reshaped = train_scaled[:, 0].reshape(len(train_scaled), 1, 1) lstm_model.predict(train_reshaped, batch_size=1) # walk-forward validation on the test data predictions = list() for i in range(len(test_scaled)): # make one-step forecast X, y = test_scaled[i, 0:-1], test_scaled[i, -1] yhat = forecast_lstm(lstm_model, 1, X) # invert scaling yhat = invert_scale(scaler, X, yhat) # invert differencing yhat = inverse_difference(raw_values, yhat, len(test_scaled)+1-i) # store forecast predictions.append(yhat) # report performance rmse = sqrt(mean_squared_error(raw_values[-12:], predictions)) print('%d) Test RMSE: %.3f' % (r+1, rmse)) error_scores.append(rmse) # summarize results results = DataFrame() results['rmse'] = error_scores print(results.describe()) results.boxplot() pyplot.show() ``` 運行該示例每次重復打印 RMSE 分數。運行結束提供收集的 RMSE 分數的摘要統計。 我們可以看到平均值和標準差 RMSE 分數分別為 138.491905 和 46.313783 月洗發水銷售額。 這是一個非常有用的結果,因為它表明上面報告的結果可能是一個統計上的僥幸。實驗表明,該模型可能與持久性模型一樣好(136.761),如果不是稍差的話。 這表明,至少需要進一步的模型調整。 ```py 1) Test RMSE: 136.191 2) Test RMSE: 169.693 3) Test RMSE: 176.553 4) Test RMSE: 198.954 5) Test RMSE: 148.960 6) Test RMSE: 103.744 7) Test RMSE: 164.344 8) Test RMSE: 108.829 9) Test RMSE: 232.282 10) Test RMSE: 110.824 11) Test RMSE: 163.741 12) Test RMSE: 111.535 13) Test RMSE: 118.324 14) Test RMSE: 107.486 15) Test RMSE: 97.719 16) Test RMSE: 87.817 17) Test RMSE: 92.920 18) Test RMSE: 112.528 19) Test RMSE: 131.687 20) Test RMSE: 92.343 21) Test RMSE: 173.249 22) Test RMSE: 182.336 23) Test RMSE: 101.477 24) Test RMSE: 108.171 25) Test RMSE: 135.880 26) Test RMSE: 254.507 27) Test RMSE: 87.198 28) Test RMSE: 122.588 29) Test RMSE: 228.449 30) Test RMSE: 94.427 rmse count 30.000000 mean 138.491905 std 46.313783 min 87.198493 25% 104.679391 50% 120.456233 75% 168.356040 max 254.507272 ``` 根據下面顯示的分布創建一個盒子和胡須圖。這將捕獲數據的中間以及范圍和異常值結果。 ![LSTM Repeated Experiment Box and Whisker Plot](https://img.kancloud.cn/c1/8c/c18c54fa205622fd17616db896118185_640x480.jpg) LSTM 重復實驗箱和晶須圖 這是一個實驗設置,可用于比較 LSTM 模型的一個配置或設置到另一個配置。 ## 教程擴展 我們可能會考慮本教程的許多擴展。 也許您可以自己探索其中一些,并在下面的評論中發布您的發現。 * **多步預測**。可以改變實驗設置以預測下一個 _n_ - 時間步驟而不是下一個單一時間步驟。這也將允許更大的批量和更快的訓練。請注意,我們基本上在本教程中執行了一種 12 步一步預測,因為模型未更新,盡管有新的觀察結果并且可用作輸入變量。 * **調諧 LSTM 模型**。該模型沒有調整;相反,配置被發現有一些快速的試驗和錯誤。我相信通過至少調整神經元的數量和訓練時期的數量可以獲得更好的結果。我還認為通過回調提前停止可能在訓練期間很有用。 * **種子狀態實驗**。目前尚不清楚在預測之前通過預測所有訓練數據來播種系統是否有益。理論上這似乎是一個好主意,但這需要得到證明。此外,也許在預測之前播種模型的其他方法也是有益的。 * **更新模型**。可以在前進驗證的每個時間步驟中更新模型。需要進行實驗以確定從頭開始重新修改模型是否更好,或者使用包括新樣本在內的更多訓練時期更新權重。 * **輸入時間步**。 LSTM 輸入支持樣本的多個時間步長。需要進行實驗以查看是否包括滯后觀察作為時間步驟提供任何益處。 * **輸入延遲功能**。可以包括滯后觀察作為輸入特征。需要進行實驗以查看包含滯后特征是否提供任何益處,與 AR(k)線性模型不同。 * **輸入錯誤系列**。可以構造誤差序列(來自持久性模型的預測誤差)并且用作附加輸入特征,與 MA(k)線性模型不同。需要進行實驗以確定這是否會帶來任何好處。 * **學習非固定**。 LSTM 網絡可能能夠了解數據中的趨勢并做出合理的預測。需要進行實驗以了解 LSTM 是否可以學習和有效預測數據中剩余的時間依賴結構,如趨勢和季節性。 * **對比無狀態**。本教程中使用了有狀態 LSTM。應將結果與無狀態 LSTM 配置進行比較。 * **統計學意義**。可以進一步擴展多重復實驗方案以包括統計顯著性檢驗,以證明具有不同構型的 RMSE 結果群體之間的差異是否具有統計學顯著性。 ## 摘要 在本教程中,您了解了如何為時間序列預測開發 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>

                              哎呀哎呀视频在线观看