# 如何開發單變量時間序列預測的深度學習模型
> 原文: [https://machinelearningmastery.com/how-to-develop-deep-learning-models-for-univariate-time-series-forecasting/](https://machinelearningmastery.com/how-to-develop-deep-learning-models-for-univariate-time-series-forecasting/)
深度學習神經網絡能夠自動學習和從原始數據中提取特征。
神經網絡的這一特征可用于時間序列預測問題,其中模型可以直接在原始觀測上開發,而不需要使用歸一化和標準化來擴展數據或通過差分使數據靜止。
令人印象深刻的是,簡單的深度學習神經網絡模型能夠進行熟練的預測,與樸素模型和調整 SARIMA 模型相比,單變量時間序列預測存在趨勢和季節性成分且無需預處理的問題。
在本教程中,您將了解如何開發一套用于單變量時間序列預測的深度學習模型。
完成本教程后,您將了解:
* 如何使用前向驗證開發一個強大的測試工具來評估神經網絡模型的表現。
* 如何開發和評估簡單多層感知器和卷積神經網絡的時間序列預測。
* 如何開發和評估 LSTM,CNN-LSTM 和 ConvLSTM 神經網絡模型用于時間序列預測。
讓我們開始吧。

如何開發單變量時間序列預測的深度學習模型
照片由 [Nathaniel McQueen](https://www.flickr.com/photos/nmcqueenphotography/40518405705/) ,保留一些權利。
## 教程概述
本教程分為五個部分;他們是:
1. 問題描述
2. 模型評估測試線束
3. 多層感知器模型
4. 卷積神經網絡模型
5. 循環神經網絡模型
## 問題描述
'_ 月度汽車銷售 _'數據集總結了 1960 年至 1968 年間加拿大魁北克省的月度汽車銷量。
您可以從 [DataMarket](https://datamarket.com/data/set/22n4/monthly-car-sales-in-quebec-1960-1968#!ds=22n4&display=line) 了解有關數據集的更多信息。
直接從這里下載數據集:
* [month-car-sales.csv](https://raw.githubusercontent.com/jbrownlee/Datasets/master/monthly-car-sales.csv)
在當前工作目錄中使用文件名“ _monthly-car-sales.csv_ ”保存文件。
我們可以使用函數 _read_csv()_ 將此數據集作為 Pandas 系列加載。
```py
# load
series = read_csv('monthly-car-sales.csv', header=0, index_col=0)
```
加載后,我們可以總結數據集的形狀,以確定觀察的數量。
```py
# summarize shape
print(series.shape)
```
然后我們可以創建該系列的線圖,以了解該系列的結構。
```py
# plot
pyplot.plot(series)
pyplot.show()
```
我們可以將所有這些結合在一起;下面列出了完整的示例。
```py
# load and plot dataset
from pandas import read_csv
from matplotlib import pyplot
# load
series = read_csv('monthly-car-sales.csv', header=0, index_col=0)
# summarize shape
print(series.shape)
# plot
pyplot.plot(series)
pyplot.show()
```
首先運行該示例將打印數據集的形狀。
```py
(108, 1)
```
該數據集是每月一次,有 9 年或 108 次觀測。在我們的測試中,將使用去年或 12 個觀測值作為測試集。
創建線圖。數據集具有明顯的趨勢和季節性成分。季節性成分的期限可能是六個月或 12 個月。

月度汽車銷售線圖
從之前的實驗中,我們知道一個幼稚的模型可以通過取預測月份的前三年的觀測值的中位數來實現 1841.155 的均方根誤差或 RMSE;例如:
```py
yhat = median(-12, -24, -36)
```
負指數是指相對于預測月份的歷史數據末尾的序列中的觀察值。
從之前的實驗中,我們知道 SARIMA 模型可以達到 1551.842 的 RMSE,其配置為 SARIMA(0,0,0),(1,1,0),12 其中沒有為趨勢指定元素和季節性差異計算周期為 12,并使用一個季節的 AR 模型。
樸素模型的表現為被認為熟練的模型提供了下限。任何在過去 12 個月內達到低于 1841.155 的預測表現的模型都具有技巧。
SARIMA 模型的表現可以衡量問題的良好模型。任何在過去 12 個月內達到預測表現低于 1551.842 的模型都應采用 SARIMA 模型。
現在我們已經定義了模型技能的問題和期望,我們可以看看定義測試工具。
## 模型評估測試線束
在本節中,我們將開發一個測試工具,用于開發和評估不同類型的神經網絡模型,用于單變量時間序列預測。
本節分為以下幾部分:
1. 訓練 - 測試分裂
2. 系列作為監督學習
3. 前瞻性驗證
4. 重復評估
5. 總結表現
6. 工作示例
### 訓練 - 測試分裂
第一步是將加載的系列分成訓練和測試集。
我們將使用前八年(96 個觀測值)進行訓練,最后 12 個用于測試集。
下面的 _train_test_split()_ 函數將拆分系列,將原始觀察值和在測試集中使用的觀察數作為參數。
```py
# split a univariate dataset into train/test sets
def train_test_split(data, n_test):
return data[:-n_test], data[-n_test:]
```
### 系列作為監督學習
接下來,我們需要能夠將單變量觀測系列框架化為監督學習問題,以便我們可以訓練神經網絡模型。
系列的監督學習框架意味著需要將數據拆分為模型從中學習和概括的多個示例。
每個樣本必須同時具有輸入組件和輸出組件。
輸入組件將是一些先前的觀察,例如三年或 36 個時間步驟。
輸出組件將是下個月的總銷售額,因為我們有興趣開發一個模型來進行一步預測。
我們可以使用 pandas DataFrame 上的 [shift()函數](http://pandas-docs.github.io/pandas-docs-travis/generated/pandas.DataFrame.shift.html)來實現它。它允許我們向下移動一列(向前移動)或向后移動(向后移動)。我們可以將該系列作為一列數據,然后創建列的多個副本,向前或向后移動,以便使用我們需要的輸入和輸出元素創建樣本。
當一個系列向下移動時,會引入 _NaN_ 值,因為我們沒有超出系列開頭的值。
例如,系列定義為列:
```py
(t)
1
2
3
4
```
可以預先移位和插入列:
```py
(t-1), (t)
Nan, 1
1, 2
2, 3
3, 4
4 NaN
```
我們可以看到,在第二行,值 1 作為輸入提供,作為前一時間步的觀察,2 是系列中可以預測的下一個值,或者當 1 是預測模型時要學習的值作為輸入呈現。
可以去除具有 _NaN_ 值的行。
下面的 _series_to_supervised()_ 函數實現了這種行為,允許您指定輸入中使用的滯后觀察數和每個樣本的輸出中使用的數。它還將刪除具有 _NaN_ 值的行,因為它們不能用于訓練或測試模型。
```py
# transform list into supervised learning format
def series_to_supervised(data, n_in=1, n_out=1):
df = DataFrame(data)
cols = list()
# input sequence (t-n, ... t-1)
for i in range(n_in, 0, -1):
cols.append(df.shift(i))
# forecast sequence (t, t+1, ... t+n)
for i in range(0, n_out):
cols.append(df.shift(-i))
# put it all together
agg = concat(cols, axis=1)
# drop rows with NaN values
agg.dropna(inplace=True)
return agg.values
```
### 前瞻性驗證
可以使用[前進驗證](https://machinelearningmastery.com/backtest-machine-learning-models-time-series-forecasting/)在測試集上評估時間序列預測模型。
前瞻性驗證是一種方法,其中模型一次一個地對測試數據集中的每個觀察進行預測。在對測試數據集中的時間步長進行每個預測之后,將預測的真實觀察結果添加到測試數據集并使其可用于模型。
在進行后續預測之前,可以使用觀察結果更簡單的模型。考慮到更高的計算成本,更復雜的模型,例如神經網絡,不會被改裝。
然而,時間步驟的真實觀察可以用作輸入的一部分,用于在下一個時間步驟上進行預測。
首先,數據集分為訓練集和測試集。我們將調用 _train_test_split()_ 函數來執行此拆分并傳入預先指定數量的觀察值以用作測試數據。
對于給定配置,模型將適合訓練數據集一次。
我們將定義一個通用的 _model_fit()_ 函數來執行此操作,可以為我們稍后可能感興趣的給定類型的神經網絡填充該操作。該函數獲取訓練數據集和模型配置,并返回準備好進行預測的擬合模型。
```py
# fit a model
def model_fit(train, config):
return None
```
枚舉測試數據集的每個時間步。使用擬合模型進行預測。
同樣,我們將定義一個名為 _model_predict()_ 的通用函數,它采用擬合模型,歷史和模型配置,并進行單個一步預測。
```py
# forecast with a pre-fit model
def model_predict(model, history, config):
return 0.0
```
將預測添加到預測列表中,并將來自測試集的真實觀察結果添加到用訓練數據集中的所有觀察結果播種的觀察列表中。此列表在前向驗證的每個步驟中構建,允許模型使用最新歷史記錄進行一步預測。
然后可以將所有預測與測試集中的真實值進行比較,并計算誤差測量值。
我們將計算預測和真實值之間的均方根誤差或 RMSE。
RMSE 計算為預測值與實際值之間的平方差的平均值的平方根。 _measure_rmse()_ 使用 [mean_squared_error()scikit-learn 函數](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html)在計算平方根之前首先計算均方誤差或 MSE。
```py
# root mean squared error or rmse
def measure_rmse(actual, predicted):
return sqrt(mean_squared_error(actual, predicted))
```
下面列出了將所有這些聯系在一起的完整 _walk_forward_validation()_ 函數。
它采用數據集,用作測試集的觀察數量以及模型的配置,并返回測試集上模型表現的 RMSE。
```py
# walk-forward validation for univariate data
def walk_forward_validation(data, n_test, cfg):
predictions = list()
# split dataset
train, test = train_test_split(data, n_test)
# fit model
model = model_fit(train, cfg)
# seed history with training dataset
history = [x for x in train]
# step over each time-step in the test set
for i in range(len(test)):
# fit model and make forecast for history
yhat = model_predict(model, history, cfg)
# store forecast in list of predictions
predictions.append(yhat)
# add actual observation to history for the next loop
history.append(test[i])
# estimate prediction error
error = measure_rmse(test, predictions)
print(' > %.3f' % error)
return error
```
### 重復評估
神經網絡模型是隨機的。
這意味著,在給定相同的模型配置和相同的訓練數據集的情況下,每次訓練模型時將產生不同的內部權重集,這反過來將具有不同的表現。
這是一個好處,允許模型自適應并找到復雜問題的高表現配置。
在評估模型的表現和選擇用于進行預測的最終模型時,這也是一個問題。
為了解決模型評估問題,我們將通過前向驗證多次評估模型配置,并將錯誤報告為每次評估的平均誤差。
對于大型神經網絡而言,這并不總是可行的,并且可能僅適用于能夠在幾分鐘或幾小時內完成的小型網絡。
下面的 _repeat_evaluate()_ 函數實現了這一點,并允許將重復次數指定為默認為 30 的可選參數,并返回模型表現得分列表:在本例中為 RMSE 值。
```py
# repeat evaluation of a config
def repeat_evaluate(data, config, n_test, n_repeats=30):
# fit and evaluate the model n times
scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)]
return scores
```
### 總結表現
最后,我們需要從多個重復中總結模型的表現。
我們將首先使用匯總統計匯總表現,特別是平均值和標準差。
我們還將使用盒子和須狀圖繪制模型表現分數的分布,以幫助了解表現的傳播。
下面的 _summarize_scores()_ 函數實現了這一點,取了評估模型的名稱和每次重復評估的分數列表,打印摘要并顯示圖表。
```py
# summarize model performance
def summarize_scores(name, scores):
# print a summary
scores_m, score_std = mean(scores), std(scores)
print('%s: %.3f RMSE (+/- %.3f)' % (name, scores_m, score_std))
# box and whisker plot
pyplot.boxplot(scores)
pyplot.show()
```
### 工作示例
現在我們已經定義了測試工具的元素,我們可以將它們綁定在一起并定義一個簡單的持久性模型。
具體而言,我們將計算先前觀察的子集相對于預測時間的中值。
我們不需要擬合模型,因此 _model_fit()_ 函數將被實現為簡單地返回 _ 無 _。
```py
# fit a model
def model_fit(train, config):
return None
```
我們將使用配置來定義先前觀察中的索引偏移列表,該列表相對于將被用作預測的預測時間。例如,12 將使用 12 個月前(-12)相對于預測時間的觀察。
```py
# define config
config = [12, 24, 36]
```
可以實現 model_predict()函數以使用此配置來收集觀察值,然后返回這些觀察值的中值。
```py
# forecast with a pre-fit model
def model_predict(model, history, config):
values = list()
for offset in config:
values.append(history[-offset])
return median(values)
```
下面列出了使用簡單持久性模型使用框架的完整示例。
```py
# persistence
from math import sqrt
from numpy import mean
from numpy import std
from pandas import DataFrame
from pandas import concat
from pandas import read_csv
from sklearn.metrics import mean_squared_error
from matplotlib import pyplot
# split a univariate dataset into train/test sets
def train_test_split(data, n_test):
return data[:-n_test], data[-n_test:]
# transform list into supervised learning format
def series_to_supervised(data, n_in=1, n_out=1):
df = DataFrame(data)
cols = list()
# input sequence (t-n, ... t-1)
for i in range(n_in, 0, -1):
cols.append(df.shift(i))
# forecast sequence (t, t+1, ... t+n)
for i in range(0, n_out):
cols.append(df.shift(-i))
# put it all together
agg = concat(cols, axis=1)
# drop rows with NaN values
agg.dropna(inplace=True)
return agg.values
# root mean squared error or rmse
def measure_rmse(actual, predicted):
return sqrt(mean_squared_error(actual, predicted))
# difference dataset
def difference(data, interval):
return [data[i] - data[i - interval] for i in range(interval, len(data))]
# fit a model
def model_fit(train, config):
return None
# forecast with a pre-fit model
def model_predict(model, history, config):
values = list()
for offset in config:
values.append(history[-offset])
return median(values)
# walk-forward validation for univariate data
def walk_forward_validation(data, n_test, cfg):
predictions = list()
# split dataset
train, test = train_test_split(data, n_test)
# fit model
model = model_fit(train, cfg)
# seed history with training dataset
history = [x for x in train]
# step over each time-step in the test set
for i in range(len(test)):
# fit model and make forecast for history
yhat = model_predict(model, history, cfg)
# store forecast in list of predictions
predictions.append(yhat)
# add actual observation to history for the next loop
history.append(test[i])
# estimate prediction error
error = measure_rmse(test, predictions)
print(' > %.3f' % error)
return error
# repeat evaluation of a config
def repeat_evaluate(data, config, n_test, n_repeats=30):
# fit and evaluate the model n times
scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)]
return scores
# summarize model performance
def summarize_scores(name, scores):
# print a summary
scores_m, score_std = mean(scores), std(scores)
print('%s: %.3f RMSE (+/- %.3f)' % (name, scores_m, score_std))
# box and whisker plot
pyplot.boxplot(scores)
pyplot.show()
series = read_csv('monthly-car-sales.csv', header=0, index_col=0)
data = series.values
# data split
n_test = 12
# define config
config = [12, 24, 36]
# grid search
scores = repeat_evaluate(data, config, n_test)
# summarize scores
summarize_scores('persistence', scores)
```
運行該示例將打印在最近 12 個月的數據中使用前向驗證評估的模型的 RMSE。
該模型被評估 30 次,但由于該模型沒有隨機元素,因此每次得分相同。
```py
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
> 1841.156
persistence: 1841.156 RMSE (+/- 0.000)
```
我們可以看到模型的 RMSE 是 1841,提供了表現的下限,通過它我們可以評估模型是否熟練掌握問題。

持久性 RMSE 預測汽車銷售的盒子和晶須圖
既然我們擁有強大的測試工具,我們就可以用它來評估一套神經網絡模型。
## 多層感知器模型
我們將評估的第一個網絡是多層感知器,簡稱 MLP。
這是一個簡單的前饋神經網絡模型,應該在考慮更復雜的模型之前進行評估。
MLP 可用于時間序列預測,方法是在先前時間步驟中進行多次觀測,稱為滯后觀測,并將其用作輸入要素并根據這些觀測預測一個或多個時間步長。
這正是上一節中 _series_to_supervised()_ 函數提供的問題的框架。
因此,訓練數據集是樣本列表,其中每個樣本在預測時間之前的幾個月具有一定數量的觀察,并且預測是序列中的下個月。例如:
```py
X, y
month1, month2, month3, month4
month2, month3, month4, month5
month3, month4, month5, month6
...
```
該模型將嘗試概括這些樣本,以便當提供超出模型已知的新樣本時,它可以預測有用的東西;例如:
```py
X, y
month4, month5, month6, ???
```
我們將使用 Keras 深度學習庫實現一個簡單的 MLP。
該模型將具有輸入層,其具有一些先前的觀察結果。當我們定義第一個隱藏層時,可以使用 _input_dim_ 參數指定。該模型將具有單個隱藏層,其具有一定數量的節點,然后是單個輸出層。
我們將在隱藏層上使用經過校正的線性激活函數,因為它表現良好。我們將在輸出層使用線性激活函數(默認值),因為我們正在預測連續值。
網絡的損失函數將是均方誤差損失或 MSE,我們將使用隨機梯度下降的高效 [Adam 風格來訓練網絡。](https://machinelearningmastery.com/adam-optimization-algorithm-for-deep-learning/)
```py
# define model
model = Sequential()
model.add(Dense(n_nodes, activation='relu', input_dim=n_input))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
```
該模型將適合一些訓練時期(對訓練數據的暴露),并且可以指定批量大小以定義在每個時期內權重的更新頻率。
下面列出了用于在訓練數據集上擬合 MLP 模型的 _model_fit()_ 函數。
該函數要求配置為具有以下配置超參數的列表:
* **n_input** :用作模型輸入的滯后觀察數。
* **n_nodes** :隱藏層中使用的節點數。
* **n_epochs** :將模型公開給整個訓練數據集的次數。
* **n_batch** :更新權重的時期內的樣本數。
```py
# fit a model
def model_fit(train, config):
# unpack config
n_input, n_nodes, n_epochs, n_batch = config
# prepare data
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
# define model
model = Sequential()
model.add(Dense(n_nodes, activation='relu', input_dim=n_input))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
# fit
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
```
使用擬合 MLP 模型進行預測與調用 _predict()_ 函數并傳入進行預測所需的一個樣本值輸入值一樣簡單。
```py
yhat = model.predict(x_input, verbose=0)
```
為了使預測超出已知數據的限制,這要求將最后 n 個已知觀察值作為數組并用作輸入。
_predict()_ 函數在進行預測時需要一個或多個輸入樣本,因此提供單個樣本需要陣列具有[ _1,n_input_ ]形狀??,其中 _] n_input_ 是模型期望作為輸入的時間步數。
類似地, _predict()_ 函數返回一個預測數組,每個樣本一個作為輸入提供。在一個預測的情況下,將存在具有一個值的數組。
下面的 _model_predict()_ 函數實現了這種行為,將模型,先前觀察和模型配置作為參數,制定輸入樣本并進行一步預測,然后返回。
```py
# forecast with a pre-fit model
def model_predict(model, history, config):
# unpack config
n_input, _, _, _ = config
# prepare data
x_input = array(history[-n_input:]).reshape(1, n_input)
# forecast
yhat = model.predict(x_input, verbose=0)
return yhat[0]
```
我們現在擁有在月度汽車銷售數據集上評估 MLP 模型所需的一切。
進行模型超參數的簡單網格搜索,并選擇下面的配置。這可能不是最佳配置,但卻是最好的配置。
* **n_input** :24(例如 24 個月)
* **n_nodes** :500
* **n_epochs** :100
* **n_batch** :100
此配置可以定義為列表:
```py
# define config
config = [24, 500, 100, 100]
```
請注意,當訓練數據被構建為監督學習問題時,只有 72 個樣本可用于訓練模型。
使用 72 或更大的批量大小意味著使用批量梯度下降而不是小批量梯度下降來訓練模型。這通常用于小數據集,并且意味著在每個時期結束時執行權重更新和梯度計算,而不是在每個時期內多次執行。
完整的代碼示例如下所示。
```py
# evaluate mlp
from math import sqrt
from numpy import array
from numpy import mean
from numpy import std
from pandas import DataFrame
from pandas import concat
from pandas import read_csv
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from matplotlib import pyplot
# split a univariate dataset into train/test sets
def train_test_split(data, n_test):
return data[:-n_test], data[-n_test:]
# transform list into supervised learning format
def series_to_supervised(data, n_in=1, n_out=1):
df = DataFrame(data)
cols = list()
# input sequence (t-n, ... t-1)
for i in range(n_in, 0, -1):
cols.append(df.shift(i))
# forecast sequence (t, t+1, ... t+n)
for i in range(0, n_out):
cols.append(df.shift(-i))
# put it all together
agg = concat(cols, axis=1)
# drop rows with NaN values
agg.dropna(inplace=True)
return agg.values
# root mean squared error or rmse
def measure_rmse(actual, predicted):
return sqrt(mean_squared_error(actual, predicted))
# fit a model
def model_fit(train, config):
# unpack config
n_input, n_nodes, n_epochs, n_batch = config
# prepare data
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
# define model
model = Sequential()
model.add(Dense(n_nodes, activation='relu', input_dim=n_input))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
# fit
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
# forecast with a pre-fit model
def model_predict(model, history, config):
# unpack config
n_input, _, _, _ = config
# prepare data
x_input = array(history[-n_input:]).reshape(1, n_input)
# forecast
yhat = model.predict(x_input, verbose=0)
return yhat[0]
# walk-forward validation for univariate data
def walk_forward_validation(data, n_test, cfg):
predictions = list()
# split dataset
train, test = train_test_split(data, n_test)
# fit model
model = model_fit(train, cfg)
# seed history with training dataset
history = [x for x in train]
# step over each time-step in the test set
for i in range(len(test)):
# fit model and make forecast for history
yhat = model_predict(model, history, cfg)
# store forecast in list of predictions
predictions.append(yhat)
# add actual observation to history for the next loop
history.append(test[i])
# estimate prediction error
error = measure_rmse(test, predictions)
print(' > %.3f' % error)
return error
# repeat evaluation of a config
def repeat_evaluate(data, config, n_test, n_repeats=30):
# fit and evaluate the model n times
scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)]
return scores
# summarize model performance
def summarize_scores(name, scores):
# print a summary
scores_m, score_std = mean(scores), std(scores)
print('%s: %.3f RMSE (+/- %.3f)' % (name, scores_m, score_std))
# box and whisker plot
pyplot.boxplot(scores)
pyplot.show()
series = read_csv('monthly-car-sales.csv', header=0, index_col=0)
data = series.values
# data split
n_test = 12
# define config
config = [24, 500, 100, 100]
# grid search
scores = repeat_evaluate(data, config, n_test)
# summarize scores
summarize_scores('mlp', scores)
```
運行該示例為模型的 30 次重復評估中的每一次打印 RMSE。
在運行結束時,報告的平均和標準偏差 RMSE 約為 1,526 銷售。
我們可以看到,平均而言,所選配置的表現優于樸素模型(1841.155)和 SARIMA 模型(1551.842)。
這是令人印象深刻的,因為該模型直接對原始數據進行操作而不進行縮放或數據靜止。
```py
> 1629.203
> 1642.219
> 1472.483
> 1662.055
> 1452.480
> 1465.535
> 1116.253
> 1682.667
> 1642.626
> 1700.183
> 1444.481
> 1673.217
> 1602.342
> 1655.895
> 1319.387
> 1591.972
> 1592.574
> 1361.607
> 1450.348
> 1314.529
> 1549.505
> 1569.750
> 1427.897
> 1478.926
> 1474.990
> 1458.993
> 1643.383
> 1457.925
> 1558.934
> 1708.278
mlp: 1526.688 RMSE (+/- 134.789)
```
創建 RMSE 分數的方框和胡須圖,以總結模型表現的傳播。
這有助于理解分數的傳播。我們可以看到,盡管平均而言模型的表現令人印象深刻,但傳播幅度很大。標準偏差略大于 134 銷售額,這意味著更糟糕的案例模型運行,誤差與平均誤差相差 2 或 3 個標準差可能比樸素模型差。
使用 MLP 模型的一個挑戰是如何利用更高的技能并在多次運行中最小化模型的方差。
該問題通常適用于神經網絡。您可以使用許多策略,但最簡單的方法可能就是在所有可用數據上訓練多個最終模型,并在進行預測時在集合中使用它們,例如:預測是 10 到 30 個模型的平均值。

多層感知器 RMSE 預測汽車銷售的盒子和晶須圖
## 卷積神經網絡模型
卷積神經網絡(CNN)是為二維圖像數據開發的一種神經網絡,盡管它們可用于一維數據,例如文本序列和時間序列。
當對一維數據進行操作時,CNN 讀取一系列滯后觀察并學習提取與進行預測相關的特征。
我們將定義具有兩個卷積層的 CNN,用于從輸入序列中提取特征。每個都將具有可配置數量的濾波器和內核大小,并將使用經過整流的線性激活功能。濾波器的數量決定了讀取和投影加權輸入的并行字段的數量。內核大小定義了網絡沿輸入序列讀取時每個快照內讀取的時間步數。
```py
model.add(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu', input_shape=(n_input, 1)))
model.add(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu'))
```
在卷積層之后使用最大池化層將加權輸入特征提取為最顯著的特征,將輸入大小減小 1/4。匯總輸入在被解釋之前被平展為一個長向量,并用于進行一步預測。
```py
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(1))
```
CNN 模型期望輸入數據采用多個樣本的形式,其中每個樣本具有多個輸入時間步長,與上一節中的 MLP 相同。
一個區別是 CNN 可以在每個時間步驟支持多個特征或類型的觀察,其被解釋為圖像的通道。我們在每個時間步都只有一個特征,因此輸入數據所需的三維形狀將是[ _n_samples,n_input,1_ ]。
```py
train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], 1))
```
下面列出了用于在訓練數據集上擬合 CNN 模型的 _model_fit()_ 函數。
該模型將以下五個配置參數作為列表:
* **n_input** :用作模型輸入的滯后觀察數。
* **n_filters** :并行濾波器的數量。
* **n_kernel** :每次讀取輸入序列時考慮的時間步數。
* **n_epochs** :將模型公開給整個訓練數據集的次數。
* **n_batch** :更新權重的時期內的樣本數。
```py
# fit a model
def model_fit(train, config):
# unpack config
n_input, n_filters, n_kernel, n_epochs, n_batch = config
# prepare data
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], 1))
# define model
model = Sequential()
model.add(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu', input_shape=(n_input, 1)))
model.add(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
# fit
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
```
使用擬合 CNN 模型進行預測非常類似于使用上一節中的擬合 MLP 模型進行預測。
一個區別在于我們要求我們指定在每個時間步驟觀察到的特征數量,在這種情況下為 1.因此,當進行單個一步預測時,輸入數組的形狀必須是:
```py
[1, n_input, 1]
```
下面的 _model_predict()_ 函數實現了這種行為。
```py
# forecast with a pre-fit model
def model_predict(model, history, config):
# unpack config
n_input, _, _, _, _ = config
# prepare data
x_input = array(history[-n_input:]).reshape((1, n_input, 1))
# forecast
yhat = model.predict(x_input, verbose=0)
return yhat[0]
```
進行模型超參數的簡單網格搜索,并選擇下面的配置。這不是最佳配置,但卻是最好的配置。
所選配置如下:
* **n_input** :36(例如 3 年或 3 * 12)
* **n_filters** :256
* **n_kernel** :3
* **n_epochs** :100
* **n_batch** :100(例如批量梯度下降)
這可以指定為如下列表:
```py
# define config
config = [36, 256, 3, 100, 100]
```
將所有這些結合在一起,下面列出了完整的示例。
```py
# evaluate cnn
from math import sqrt
from numpy import array
from numpy import mean
from numpy import std
from pandas import DataFrame
from pandas import concat
from pandas import read_csv
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from matplotlib import pyplot
# split a univariate dataset into train/test sets
def train_test_split(data, n_test):
return data[:-n_test], data[-n_test:]
# transform list into supervised learning format
def series_to_supervised(data, n_in=1, n_out=1):
df = DataFrame(data)
cols = list()
# input sequence (t-n, ... t-1)
for i in range(n_in, 0, -1):
cols.append(df.shift(i))
# forecast sequence (t, t+1, ... t+n)
for i in range(0, n_out):
cols.append(df.shift(-i))
# put it all together
agg = concat(cols, axis=1)
# drop rows with NaN values
agg.dropna(inplace=True)
return agg.values
# root mean squared error or rmse
def measure_rmse(actual, predicted):
return sqrt(mean_squared_error(actual, predicted))
# fit a model
def model_fit(train, config):
# unpack config
n_input, n_filters, n_kernel, n_epochs, n_batch = config
# prepare data
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], 1))
# define model
model = Sequential()
model.add(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu', input_shape=(n_input, 1)))
model.add(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
# fit
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
# forecast with a pre-fit model
def model_predict(model, history, config):
# unpack config
n_input, _, _, _, _ = config
# prepare data
x_input = array(history[-n_input:]).reshape((1, n_input, 1))
# forecast
yhat = model.predict(x_input, verbose=0)
return yhat[0]
# walk-forward validation for univariate data
def walk_forward_validation(data, n_test, cfg):
predictions = list()
# split dataset
train, test = train_test_split(data, n_test)
# fit model
model = model_fit(train, cfg)
# seed history with training dataset
history = [x for x in train]
# step over each time-step in the test set
for i in range(len(test)):
# fit model and make forecast for history
yhat = model_predict(model, history, cfg)
# store forecast in list of predictions
predictions.append(yhat)
# add actual observation to history for the next loop
history.append(test[i])
# estimate prediction error
error = measure_rmse(test, predictions)
print(' > %.3f' % error)
return error
# repeat evaluation of a config
def repeat_evaluate(data, config, n_test, n_repeats=30):
# fit and evaluate the model n times
scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)]
return scores
# summarize model performance
def summarize_scores(name, scores):
# print a summary
scores_m, score_std = mean(scores), std(scores)
print('%s: %.3f RMSE (+/- %.3f)' % (name, scores_m, score_std))
# box and whisker plot
pyplot.boxplot(scores)
pyplot.show()
series = read_csv('monthly-car-sales.csv', header=0, index_col=0)
data = series.values
# data split
n_test = 12
# define config
config = [36, 256, 3, 100, 100]
# grid search
scores = repeat_evaluate(data, config, n_test)
# summarize scores
summarize_scores('cnn', scores)
```
首先運行該示例,為每次重復的模型評估打印 RMSE。
在運行結束時,我們可以看到模型確實熟練,達到平均 RMSE 1,524.067,這比樸素模型,SARIMA 模型,甚至上一節中的 MLP 模型更好。
這是令人印象深刻的,因為該模型直接對原始數據進行操作而不進行縮放或數據靜止。
分數的標準偏差很大,約為 57 個銷售額,但卻是前一部分 MLP 模型觀察到的方差大小的 1/3。我們有信心在壞情況下(3 個標準偏差),模型 RMSE 將保持低于(優于)樸素模型的表現。
```py
> 1551.031
> 1495.743
> 1449.408
> 1526.017
> 1466.118
> 1566.535
> 1649.204
> 1455.782
> 1574.214
> 1541.790
> 1489.140
> 1506.035
> 1513.197
> 1530.714
> 1511.328
> 1471.518
> 1555.596
> 1552.026
> 1531.727
> 1472.978
> 1620.242
> 1424.153
> 1456.393
> 1581.114
> 1539.286
> 1489.795
> 1652.620
> 1537.349
> 1443.777
> 1567.179
cnn: 1524.067 RMSE (+/- 57.148)
```
創建分數的框和胡須圖以幫助理解運行中的錯誤傳播。
我們可以看到,差價看起來似乎偏向于更大的誤差值,正如我們所預期的那樣,盡管圖的上部胡須(在這種情況下,最大誤差不是異常值)仍然受限于 1,650 銷售的 RMSE 。

卷積神經網絡 RMSE 預測汽車銷售的盒子和晶須圖
## 循環神經網絡模型
循環神經網絡或 RNN 是那些類型的神經網絡,其使用來自先前步驟的網絡輸出作為輸入以嘗試跨序列數據自動學習。
長短期內存或 LSTM 網絡是一種 RNN,其實現解決了在序列數據上訓練 RNN 導致穩定模型的一般困難。它通過學習控制每個節點內的循環連接的內部門的權重來實現這一點。
盡管針對序列數據進行了開發, [LSTM 尚未證明在時間序列預測問題上有效](https://machinelearningmastery.com/suitability-long-short-term-memory-networks-time-series-forecasting/),其中輸出是近期觀測的函數,例如自動回歸類型預測問題,例如汽車銷售數據集。
然而,我們可以開發用于自回歸問題的 LSTM 模型,并將其用作與其他神經網絡模型進行比較的點。
在本節中,我們將探討 LSTM 模型的三變量,用于單變量時間序列預測;他們是:
* **LSTM** :LSTM 網絡原樣。
* **CNN-LSTM** :學習輸入功能的 CNN 網絡和解釋它們的 LSTM。
* **ConvLSTM** :CNN 和 LSTM 的組合,其中 LSTM 單元使用 CNN 的卷積過程讀取輸入數據。
### LSTM
LSTM 神經網絡可用于單變量時間序列預測。
作為 RNN,它將一次一步地讀取輸入序列的每個時間步長。 LSTM 具有內部存儲器,允許它在讀取給定輸入序列的步驟時累積內部狀態。
在序列結束時,隱藏 LSTM 單元層中的每個節點將輸出單個值。該值向量總結了 LSTM 從輸入序列中學習或提取的內容。這可以在完成最終預測之前由完全連接的層解釋。
```py
# define model
model = Sequential()
model.add(LSTM(n_nodes, activation='relu', input_shape=(n_input, 1)))
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
```
與 CNN 一樣,LSTM 可以在每個時間步驟支持多個變量或功能。由于汽車銷售數據集在每個時間步都只有一個值,我們可以將其固定為 1,既可以在 input_shape 參數[ _n_input,1_ ]中定義網絡輸入,也可以定義形狀輸入樣本。
```py
train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], 1))
```
與不一次一步讀取序列數據的 MLP 和 CNN 不同,如果數據是靜止的,LSTM 確實表現更好。這意味著執行差異操作以消除趨勢和季節性結構。
對于汽車銷售數據集,我們可以通過執行季節性調整來制作數據信息,即從每個觀察值中減去一年前的值。
```py
adjusted = value - value[-12]
```
這可以針對整個訓練數據集系統地執行。這也意味著必須放棄觀察的第一年,因為我們沒有前一年的數據來區分它們。
下面的 _ 差異()_ 函數將使提供的數據集與提供的偏移量不同,稱為差異順序,例如差異順序。 12 前一個月的一年。
```py
# difference dataset
def difference(data, interval):
return [data[i] - data[i - interval] for i in range(interval, len(data))]
```
我們可以使差值順序成為模型的超參數,并且只有在提供非零值的情況下才執行操作。
下面提供了用于擬合 LSTM 模型的 _model_fit()_ 函數。
該模型需要一個包含五個模型超參數的列表;他們是:
* **n_input** :用作模型輸入的滯后觀察數。
* **n_nodes** :隱藏層中使用的 LSTM 單元數。
* **n_epochs** :將模型公開給整個訓練數據集的次數。
* **n_batch** :更新權重的時期內的樣本數。
* **n_diff** :差值順序或 0 如果不使用。
```py
# fit a model
def model_fit(train, config):
# unpack config
n_input, n_nodes, n_epochs, n_batch, n_diff = config
# prepare data
if n_diff > 0:
train = difference(train, n_diff)
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], 1))
# define model
model = Sequential()
model.add(LSTM(n_nodes, activation='relu', input_shape=(n_input, 1)))
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
# fit
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
```
使用 LSTM 模型進行預測與使用 CNN 模型進行預測相同。
單個輸入必須具有樣本,時間步長和特征的三維結構,在這種情況下,我們只有 1 個樣本和 1 個特征:[ _1,n_input,1_ ]。
如果執行差異操作,我們必須添加模型進行預測后減去的值。在制定用于進行預測的單個輸入之前,我們還必須區分歷史數據。
下面的 _model_predict()_ 函數實現了這種行為。
```py
# forecast with a pre-fit model
def model_predict(model, history, config):
# unpack config
n_input, _, _, _, n_diff = config
# prepare data
correction = 0.0
if n_diff > 0:
correction = history[-n_diff]
history = difference(history, n_diff)
x_input = array(history[-n_input:]).reshape((1, n_input, 1))
# forecast
yhat = model.predict(x_input, verbose=0)
return correction + yhat[0]
```
進行模型超參數的簡單網格搜索,并選擇下面的配置。這不是最佳配置,但卻是最好的配置。
所選配置如下:
* **n_input** :36(即 3 年或 3 * 12)
* **n_nodes** :50
* **n_epochs** :100
* **n_batch** :100(即批量梯度下降)
* **n_diff** :12(即季節性差異)
這可以指定為一個列表:
```py
# define config
config = [36, 50, 100, 100, 12]
```
將所有這些結合在一起,下面列出了完整的示例。
```py
# evaluate lstm
from math import sqrt
from numpy import array
from numpy import mean
from numpy import std
from pandas import DataFrame
from pandas import concat
from pandas import read_csv
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from matplotlib import pyplot
# split a univariate dataset into train/test sets
def train_test_split(data, n_test):
return data[:-n_test], data[-n_test:]
# transform list into supervised learning format
def series_to_supervised(data, n_in=1, n_out=1):
df = DataFrame(data)
cols = list()
# input sequence (t-n, ... t-1)
for i in range(n_in, 0, -1):
cols.append(df.shift(i))
# forecast sequence (t, t+1, ... t+n)
for i in range(0, n_out):
cols.append(df.shift(-i))
# put it all together
agg = concat(cols, axis=1)
# drop rows with NaN values
agg.dropna(inplace=True)
return agg.values
# root mean squared error or rmse
def measure_rmse(actual, predicted):
return sqrt(mean_squared_error(actual, predicted))
# difference dataset
def difference(data, interval):
return [data[i] - data[i - interval] for i in range(interval, len(data))]
# fit a model
def model_fit(train, config):
# unpack config
n_input, n_nodes, n_epochs, n_batch, n_diff = config
# prepare data
if n_diff > 0:
train = difference(train, n_diff)
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], 1))
# define model
model = Sequential()
model.add(LSTM(n_nodes, activation='relu', input_shape=(n_input, 1)))
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
# fit
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
# forecast with a pre-fit model
def model_predict(model, history, config):
# unpack config
n_input, _, _, _, n_diff = config
# prepare data
correction = 0.0
if n_diff > 0:
correction = history[-n_diff]
history = difference(history, n_diff)
x_input = array(history[-n_input:]).reshape((1, n_input, 1))
# forecast
yhat = model.predict(x_input, verbose=0)
return correction + yhat[0]
# walk-forward validation for univariate data
def walk_forward_validation(data, n_test, cfg):
predictions = list()
# split dataset
train, test = train_test_split(data, n_test)
# fit model
model = model_fit(train, cfg)
# seed history with training dataset
history = [x for x in train]
# step over each time-step in the test set
for i in range(len(test)):
# fit model and make forecast for history
yhat = model_predict(model, history, cfg)
# store forecast in list of predictions
predictions.append(yhat)
# add actual observation to history for the next loop
history.append(test[i])
# estimate prediction error
error = measure_rmse(test, predictions)
print(' > %.3f' % error)
return error
# repeat evaluation of a config
def repeat_evaluate(data, config, n_test, n_repeats=30):
# fit and evaluate the model n times
scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)]
return scores
# summarize model performance
def summarize_scores(name, scores):
# print a summary
scores_m, score_std = mean(scores), std(scores)
print('%s: %.3f RMSE (+/- %.3f)' % (name, scores_m, score_std))
# box and whisker plot
pyplot.boxplot(scores)
pyplot.show()
series = read_csv('monthly-car-sales.csv', header=0, index_col=0)
data = series.values
# data split
n_test = 12
# define config
config = [36, 50, 100, 100, 12]
# grid search
scores = repeat_evaluate(data, config, n_test)
# summarize scores
summarize_scores('lstm', scores)
```
運行該示例,我們可以看到每次重復評估模型的 RMSE。
在運行結束時,我們可以看到平均 RMSE 約為 2,109,這比樸素模型更差。這表明所選擇的模型并不熟練,并且鑒于前面部分中用于查找模型配置的相同資源,它是最好的。
這提供了進一步的證據(雖然證據不足),LSTM,至少單獨,可能不適合自回歸型序列預測問題。
```py
> 2129.480
> 2169.109
> 2078.290
> 2257.222
> 2014.911
> 2197.283
> 2028.176
> 2110.718
> 2100.388
> 2157.271
> 1940.103
> 2086.588
> 1986.696
> 2168.784
> 2188.813
> 2086.759
> 2128.095
> 2126.467
> 2077.463
> 2057.679
> 2209.818
> 2067.082
> 1983.346
> 2157.749
> 2145.071
> 2266.130
> 2105.043
> 2128.549
> 1952.002
> 2188.287
lstm: 2109.779 RMSE (+/- 81.373)
```
還創建了一個盒子和胡須圖,總結了 RMSE 分數的分布。
甚至模型的基本情況也沒有達到樸素模型的表現。

長短期記憶神經網絡 RMSE 預測汽車銷售的盒子和晶須圖
### CNN LSTM
我們已經看到 CNN 模型能夠自動學習和從原始序列數據中提取特征而無需縮放或差分。
我們可以將此功能與 LSTM 結合使用,其中 CNN 模型應用于輸入數據的子序列,其結果一起形成可由 LSTM 模型解釋的提取特征的時間序列。
用于通過 LSTM 隨時間讀取多個子序列的 CNN 模型的這種組合稱為 CNN-LSTM 模型。
該模型要求每個輸入序列,例如, 36 個月,分為多個子序列,每個子序列由 CNN 模型讀取,例如, 12 個時間步驟的 3 個子序列。將子序列劃分多年可能是有意義的,但這只是一個假設,可以使用其他分裂,例如六個時間步驟的六個子序列。因此,對于子序列的數量和每個子序列參數的步數,使用 _n_seq_ 和 _n_steps_ 參數化該分裂。
```py
train_x = train_x.reshape((train_x.shape[0], n_seq, n_steps, 1))
```
每個樣本的滯后觀察數量簡單( _n_seq * n_steps_ )。
這是一個 4 維輸入數組,現在尺寸為:
```py
[samples, subsequences, timesteps, features]
```
必須對每個輸入子序列應用相同的 CNN 模型。
我們可以通過將整個 CNN 模型包裝在 _TimeDistributed_ 層包裝器中來實現這一點。
```py
model = Sequential()
model.add(TimeDistributed(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu', input_shape=(None,n_steps,1))))
model.add(TimeDistributed(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu')))
model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
model.add(TimeDistributed(Flatten()))
```
CNN 子模型的一個應用程序的輸出將是向量。子模型到每個輸入子序列的輸出將是可由 LSTM 模型解釋的時間序列的解釋。接下來是完全連接的層,用于解釋 LSTM 的結果,最后是輸出層,用于進行一步預測。
```py
model.add(LSTM(n_nodes, activation='relu'))
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(1))
```
完整的 _model_fit()_ 功能如下所示。
該模型需要一個包含七個超參數的列表;他們是:
* **n_seq** :樣本中的子序列數。
* **n_steps** :每個子序列中的時間步數。
* **n_filters** :并行濾波器的數量。
* **n_kernel** :每次讀取輸入序列時考慮的時間步數。
* **n_nodes** :隱藏層中使用的 LSTM 單元數。
* **n_epochs** :將模型公開給整個訓練數據集的次數。
* **n_batch** :更新權重的時期內的樣本數。
```py
# fit a model
def model_fit(train, config):
# unpack config
n_seq, n_steps, n_filters, n_kernel, n_nodes, n_epochs, n_batch = config
n_input = n_seq * n_steps
# prepare data
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
train_x = train_x.reshape((train_x.shape[0], n_seq, n_steps, 1))
# define model
model = Sequential()
model.add(TimeDistributed(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu', input_shape=(None,n_steps,1))))
model.add(TimeDistributed(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu')))
model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(n_nodes, activation='relu'))
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
# fit
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
```
使用擬合模型進行預測與 LSTM 或 CNN 大致相同,盡管添加了將每個樣本分成具有給定數量的時間步長的子序列。
```py
# prepare data
x_input = array(history[-n_input:]).reshape((1, n_seq, n_steps, 1))
```
更新后的 _model_predict()_ 功能如下所示。
```py
# forecast with a pre-fit model
def model_predict(model, history, config):
# unpack config
n_seq, n_steps, _, _, _, _, _ = config
n_input = n_seq * n_steps
# prepare data
x_input = array(history[-n_input:]).reshape((1, n_seq, n_steps, 1))
# forecast
yhat = model.predict(x_input, verbose=0)
return yhat[0]
```
進行模型超參數的簡單網格搜索,并選擇下面的配置。這可能不是最佳配置,但它是最好的配置。
* **n_seq** :3(即 3 年)
* **n_steps** :12(即 1 個月)
* **n_filters** :64
* **n_kernel** :3
* **n_nodes** :100
* **n_epochs** :200
* **n_batch** :100(即批量梯度下降)
我們可以將配置定義為列表;例如:
```py
# define config
config = [3, 12, 64, 3, 100, 200, 100]
```
下面列出了評估用于預測單變量月度汽車銷售的 CNN-LSTM 模型的完整示例。
```py
# evaluate cnn lstm
from math import sqrt
from numpy import array
from numpy import mean
from numpy import std
from pandas import DataFrame
from pandas import concat
from pandas import read_csv
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import TimeDistributed
from keras.layers import Flatten
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from matplotlib import pyplot
# split a univariate dataset into train/test sets
def train_test_split(data, n_test):
return data[:-n_test], data[-n_test:]
# transform list into supervised learning format
def series_to_supervised(data, n_in=1, n_out=1):
df = DataFrame(data)
cols = list()
# input sequence (t-n, ... t-1)
for i in range(n_in, 0, -1):
cols.append(df.shift(i))
# forecast sequence (t, t+1, ... t+n)
for i in range(0, n_out):
cols.append(df.shift(-i))
# put it all together
agg = concat(cols, axis=1)
# drop rows with NaN values
agg.dropna(inplace=True)
return agg.values
# root mean squared error or rmse
def measure_rmse(actual, predicted):
return sqrt(mean_squared_error(actual, predicted))
# fit a model
def model_fit(train, config):
# unpack config
n_seq, n_steps, n_filters, n_kernel, n_nodes, n_epochs, n_batch = config
n_input = n_seq * n_steps
# prepare data
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
train_x = train_x.reshape((train_x.shape[0], n_seq, n_steps, 1))
# define model
model = Sequential()
model.add(TimeDistributed(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu', input_shape=(None,n_steps,1))))
model.add(TimeDistributed(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu')))
model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(n_nodes, activation='relu'))
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
# fit
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
# forecast with a pre-fit model
def model_predict(model, history, config):
# unpack config
n_seq, n_steps, _, _, _, _, _ = config
n_input = n_seq * n_steps
# prepare data
x_input = array(history[-n_input:]).reshape((1, n_seq, n_steps, 1))
# forecast
yhat = model.predict(x_input, verbose=0)
return yhat[0]
# walk-forward validation for univariate data
def walk_forward_validation(data, n_test, cfg):
predictions = list()
# split dataset
train, test = train_test_split(data, n_test)
# fit model
model = model_fit(train, cfg)
# seed history with training dataset
history = [x for x in train]
# step over each time-step in the test set
for i in range(len(test)):
# fit model and make forecast for history
yhat = model_predict(model, history, cfg)
# store forecast in list of predictions
predictions.append(yhat)
# add actual observation to history for the next loop
history.append(test[i])
# estimate prediction error
error = measure_rmse(test, predictions)
print(' > %.3f' % error)
return error
# repeat evaluation of a config
def repeat_evaluate(data, config, n_test, n_repeats=30):
# fit and evaluate the model n times
scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)]
return scores
# summarize model performance
def summarize_scores(name, scores):
# print a summary
scores_m, score_std = mean(scores), std(scores)
print('%s: %.3f RMSE (+/- %.3f)' % (name, scores_m, score_std))
# box and whisker plot
pyplot.boxplot(scores)
pyplot.show()
series = read_csv('monthly-car-sales.csv', header=0, index_col=0)
data = series.values
# data split
n_test = 12
# define config
config = [3, 12, 64, 3, 100, 200, 100]
# grid search
scores = repeat_evaluate(data, config, n_test)
# summarize scores
summarize_scores('cnn-lstm', scores)
```
運行該示例為每次重復的模型評估打印 RMSE。
最終平均 RMSE 報告在約 1,626 的末尾,低于幼稚模型,但仍高于 SARIMA 模型。該分數的標準偏差也非常大,表明所選配置可能不如獨立 CNN 模型穩定。
```py
> 1543.533
> 1421.895
> 1467.927
> 1441.125
> 1750.995
> 1321.498
> 1571.657
> 1845.298
> 1621.589
> 1425.065
> 1675.232
> 1807.288
> 2922.295
> 1391.861
> 1626.655
> 1633.177
> 1667.572
> 1577.285
> 1590.235
> 1557.385
> 1784.982
> 1664.839
> 1741.729
> 1437.992
> 1772.076
> 1289.794
> 1685.976
> 1498.123
> 1618.627
> 1448.361
cnn-lstm: 1626.735 RMSE (+/- 279.850)
```
還創建了一個盒子和胡須圖,總結了 RMSE 分數的分布。
該圖顯示了一個非常差的表現異常值,僅低于 3,000 個銷售額。

CNN-LSTM RMSE 預測汽車銷售的盒子和晶須圖
### ConvLSTM
作為讀取每個 LSTM 單元內的輸入序列的一部分,可以執行卷積運算。
這意味著,LSTM 不是一次一步地讀取序列,而是使用卷積過程(如 CNN)一次讀取觀察的塊或子序列。
這與使用 LSTM 首先讀取提取特征并使用 LSTM 解釋結果不同;這是作為 LSTM 的一部分在每個時間步執行 CNN 操作。
這種類型的模型稱為卷積 LSTM,簡稱 ConvLSTM。它在 Keras 中作為 2D 數據稱為 ConvLSTM2D 的層提供。我們可以通過假設我們有一行包含多列來配置它以用于 1D 序列數據。
與 CNN-LSTM 一樣,輸入數據被分成子序列,其中每個子序列具有固定數量的時間步長,盡管我們還必須指定每個子序列中的行數,在這種情況下固定為 1。
```py
train_x = train_x.reshape((train_x.shape[0], n_seq, 1, n_steps, 1))
```
形狀是五維的,尺寸為:
```py
[samples, subsequences, rows, columns, features]
```
與 CNN 一樣,ConvLSTM 層允許我們指定過濾器映射的數量以及讀取輸入序列時使用的內核的大小。
```py
model.add(ConvLSTM2D(filters=n_filters, kernel_size=(1,n_kernel), activation='relu', input_shape=(n_seq, 1, n_steps, 1)))
```
層的輸出是一系列過濾器映射,在解釋之前必須首先將其展平,然后是輸出層。
該模型需要一個包含七個超參數的列表,與 CNN-LSTM 相同;他們是:
* **n_seq** :樣本中的子序列數。
* **n_steps** :每個子序列中的時間步數。
* **n_filters** :并行濾波器的數量。
* **n_kernel** :每次讀取輸入序列時考慮的時間步數。
* **n_nodes** :隱藏層中使用的 LSTM 單元數。
* **n_epochs** :將模型公開給整個訓練數據集的次數。
* **n_batch** :更新權重的時期內的樣本數。
下面列出了實現所有這些功能的 _model_fit()_ 函數。
```py
# fit a model
def model_fit(train, config):
# unpack config
n_seq, n_steps, n_filters, n_kernel, n_nodes, n_epochs, n_batch = config
n_input = n_seq * n_steps
# prepare data
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
train_x = train_x.reshape((train_x.shape[0], n_seq, 1, n_steps, 1))
# define model
model = Sequential()
model.add(ConvLSTM2D(filters=n_filters, kernel_size=(1,n_kernel), activation='relu', input_shape=(n_seq, 1, n_steps, 1)))
model.add(Flatten())
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
# fit
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
```
使用擬合模型以與 CNN-LSTM 相同的方式進行預測,盡管我們將附加行維度固定為 1。
```py
# prepare data
x_input = array(history[-n_input:]).reshape((1, n_seq, 1, n_steps, 1))
```
下面列出了用于進行單個一步預測的 _model_predict()_ 函數。
```py
# forecast with a pre-fit model
def model_predict(model, history, config):
# unpack config
n_seq, n_steps, _, _, _, _, _ = config
n_input = n_seq * n_steps
# prepare data
x_input = array(history[-n_input:]).reshape((1, n_seq, 1, n_steps, 1))
# forecast
yhat = model.predict(x_input, verbose=0)
return yhat[0]
```
進行模型超參數的簡單網格搜索,并選擇下面的配置。
這可能不是最佳配置,但卻是最好的配置。
* **n_seq** :3(即 3 年)
* **n_steps** :12(即 1 個月)
* **n_filters** :256
* **n_kernel** :3
* **n_nodes** :200
* **n_epochs** :200
* **n_batch** :100(即批量梯度下降)
我們可以將配置定義為列表;例如:
```py
# define config
config = [3, 12, 256, 3, 200, 200, 100]
```
我們可以將所有這些結合在一起。下面列出了評估每月汽車銷售數據集一步預測的 ConvLSTM 模型的完整代碼清單。
```py
# evaluate convlstm
from math import sqrt
from numpy import array
from numpy import mean
from numpy import std
from pandas import DataFrame
from pandas import concat
from pandas import read_csv
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers import ConvLSTM2D
from matplotlib import pyplot
# split a univariate dataset into train/test sets
def train_test_split(data, n_test):
return data[:-n_test], data[-n_test:]
# transform list into supervised learning format
def series_to_supervised(data, n_in=1, n_out=1):
df = DataFrame(data)
cols = list()
# input sequence (t-n, ... t-1)
for i in range(n_in, 0, -1):
cols.append(df.shift(i))
# forecast sequence (t, t+1, ... t+n)
for i in range(0, n_out):
cols.append(df.shift(-i))
# put it all together
agg = concat(cols, axis=1)
# drop rows with NaN values
agg.dropna(inplace=True)
return agg.values
# root mean squared error or rmse
def measure_rmse(actual, predicted):
return sqrt(mean_squared_error(actual, predicted))
# difference dataset
def difference(data, interval):
return [data[i] - data[i - interval] for i in range(interval, len(data))]
# fit a model
def model_fit(train, config):
# unpack config
n_seq, n_steps, n_filters, n_kernel, n_nodes, n_epochs, n_batch = config
n_input = n_seq * n_steps
# prepare data
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
train_x = train_x.reshape((train_x.shape[0], n_seq, 1, n_steps, 1))
# define model
model = Sequential()
model.add(ConvLSTM2D(filters=n_filters, kernel_size=(1,n_kernel), activation='relu', input_shape=(n_seq, 1, n_steps, 1)))
model.add(Flatten())
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
# fit
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
# forecast with a pre-fit model
def model_predict(model, history, config):
# unpack config
n_seq, n_steps, _, _, _, _, _ = config
n_input = n_seq * n_steps
# prepare data
x_input = array(history[-n_input:]).reshape((1, n_seq, 1, n_steps, 1))
# forecast
yhat = model.predict(x_input, verbose=0)
return yhat[0]
# walk-forward validation for univariate data
def walk_forward_validation(data, n_test, cfg):
predictions = list()
# split dataset
train, test = train_test_split(data, n_test)
# fit model
model = model_fit(train, cfg)
# seed history with training dataset
history = [x for x in train]
# step over each time-step in the test set
for i in range(len(test)):
# fit model and make forecast for history
yhat = model_predict(model, history, cfg)
# store forecast in list of predictions
predictions.append(yhat)
# add actual observation to history for the next loop
history.append(test[i])
# estimate prediction error
error = measure_rmse(test, predictions)
print(' > %.3f' % error)
return error
# repeat evaluation of a config
def repeat_evaluate(data, config, n_test, n_repeats=30):
# fit and evaluate the model n times
scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)]
return scores
# summarize model performance
def summarize_scores(name, scores):
# print a summary
scores_m, score_std = mean(scores), std(scores)
print('%s: %.3f RMSE (+/- %.3f)' % (name, scores_m, score_std))
# box and whisker plot
pyplot.boxplot(scores)
pyplot.show()
series = read_csv('monthly-car-sales.csv', header=0, index_col=0)
data = series.values
# data split
n_test = 12
# define config
config = [3, 12, 256, 3, 200, 200, 100]
# grid search
scores = repeat_evaluate(data, config, n_test)
# summarize scores
summarize_scores('convlstm', scores)
```
運行該示例為每次重復的模型評估打印 RMSE。
最終的平均 RMSE 報告在約 1,660 結束時,低于幼稚模型,但仍高于 SARIMA 模型。
這個結果可能與 CNN-LSTM 模型相當。該分數的標準偏差也非常大,表明所選配置可能不如獨立 CNN 模型穩定。
```py
> 1825.246
> 1862.674
> 1684.313
> 1310.448
> 2109.668
> 1507.912
> 1431.118
> 1442.692
> 1400.548
> 1732.381
> 1523.824
> 1611.898
> 1805.970
> 1616.015
> 1649.466
> 1521.884
> 2025.655
> 1622.886
> 2536.448
> 1526.532
> 1866.631
> 1562.625
> 1491.386
> 1506.270
> 1843.981
> 1653.084
> 1650.430
> 1291.353
> 1558.616
> 1653.231
convlstm: 1660.840 RMSE (+/- 248.826)
```
還創建了一個盒子和胡須圖,總結了 RMSE 分數的分布。

ConvLSTM RMSE 預測汽車銷售的盒子和晶須圖
## 擴展
本節列出了一些擴展您可能希望探索的教程的想法。
* **數據準備**。探索數據準備(例如規范化,標準化和/或差異化)是否可以列出任何模型的表現。
* **網格搜索超參數**。對一個模型實施超參數的網格搜索,以查看是否可以進一步提升表現。
* **學習曲線診斷**。創建一個模型的單一擬合并查看數據集的訓練和驗證分割的學習曲線,然后使用學習曲線的診斷來進一步調整模型超參數以提高模型表現。
* **歷史規模**。探索一種模型的不同數量的歷史數據(滯后輸入),以了解您是否可以進一步提高模型表現
* **減少最終模型的差異**。探索一種或多種策略來減少其中一種神經網絡模型的方差。
* **前進期間更新**。探索作為前進驗證的一部分重新擬合或更新神經網絡模型是否可以進一步提高模型表現。
* **更多參數化**。探索為一個模型添加更多模型參數化,例如使用其他層。
如果你探索任何這些擴展,我很想知道。
## 進一步閱讀
如果您希望深入了解,本節將提供有關該主題的更多資源。
* [pandas.DataFrame.shift API](http://pandas-docs.github.io/pandas-docs-travis/generated/pandas.DataFrame.shift.html)
* [sklearn.metrics.mean_squared_error API](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html)
* [matplotlib.pyplot.boxplot API](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.boxplot.html)
* [Keras 序列模型 API](https://keras.io/models/sequential/)
## 摘要
在本教程中,您了解了如何開發一套用于單變量時間序列預測的深度學習模型。
具體來說,你學到了:
* 如何使用前向驗證開發一個強大的測試工具來評估神經網絡模型的表現。
* 如何開發和評估簡單多層感知器和卷積神經網絡的時間序列預測。
* 如何開發和評估 LSTM,CNN-LSTM 和 ConvLSTM 神經網絡模型用于時間序列預測。
你有任何問題嗎?
在下面的評論中提出您的問題,我會盡力回答。
- Machine Learning Mastery 應用機器學習教程
- 5競爭機器學習的好處
- 過度擬合的簡單直覺,或者為什么測試訓練數據是一個壞主意
- 特征選擇簡介
- 應用機器學習作為一個搜索問題的溫和介紹
- 為什么應用機器學習很難
- 為什么我的結果不如我想的那么好?你可能過度擬合了
- 用ROC曲線評估和比較分類器表現
- BigML評論:發現本機學習即服務平臺的聰明功能
- BigML教程:開發您的第一個決策樹并進行預測
- 構建生產機器學習基礎設施
- 分類準確性不夠:可以使用更多表現測量
- 一種預測模型的巧妙應用
- 機器學習項目中常見的陷阱
- 數據清理:將凌亂的數據轉換為整潔的數據
- 機器學習中的數據泄漏
- 數據,學習和建模
- 數據管理至關重要以及為什么需要認真對待它
- 將預測模型部署到生產中
- 參數和超參數之間有什么區別?
- 測試和驗證數據集之間有什么區別?
- 發現特征工程,如何設計特征以及如何獲得它
- 如何開始使用Kaggle
- 超越預測
- 如何在評估機器學習算法時選擇正確的測試選項
- 如何定義機器學習問題
- 如何評估機器學習算法
- 如何獲得基線結果及其重要性
- 如何充分利用機器學習數據
- 如何識別數據中的異常值
- 如何提高機器學習效果
- 如何在競爭機器學習中踢屁股
- 如何知道您的機器學習模型是否具有良好的表現
- 如何布局和管理您的機器學習項目
- 如何為機器學習準備數據
- 如何減少最終機器學習模型中的方差
- 如何使用機器學習結果
- 如何解決像數據科學家這樣的問題
- 通過數據預處理提高模型精度
- 處理機器學習的大數據文件的7種方法
- 建立機器學習系統的經驗教訓
- 如何使用機器學習清單可靠地獲得準確的預測(即使您是初學者)
- 機器學習模型運行期間要做什么
- 機器學習表現改進備忘單
- 來自世界級從業者的機器學習技巧:Phil Brierley
- 模型預測精度與機器學習中的解釋
- 競爭機器學習的模型選擇技巧
- 機器學習需要多少訓練數據?
- 如何系統地規劃和運行機器學習實驗
- 應用機器學習過程
- 默認情況下可重現的機器學習結果
- 10個實踐應用機器學習的標準數據集
- 簡單的三步法到最佳機器學習算法
- 打擊機器學習數據集中不平衡類的8種策略
- 模型表現不匹配問題(以及如何處理)
- 黑箱機器學習的誘惑陷阱
- 如何培養最終的機器學習模型
- 使用探索性數據分析了解您的問題并獲得更好的結果
- 什么是數據挖掘和KDD
- 為什么One-Hot在機器學習中編碼數據?
- 為什么你應該在你的機器學習問題上進行抽樣檢查算法
- 所以,你正在研究機器學習問題......
- Machine Learning Mastery Keras 深度學習教程
- Keras 中神經網絡模型的 5 步生命周期
- 在 Python 迷你課程中應用深度學習
- Keras 深度學習庫的二元分類教程
- 如何用 Keras 構建多層感知器神經網絡模型
- 如何在 Keras 中檢查深度學習模型
- 10 個用于 Amazon Web Services 深度學習的命令行秘籍
- 機器學習卷積神經網絡的速成課程
- 如何在 Python 中使用 Keras 進行深度學習的度量
- 深度學習書籍
- 深度學習課程
- 你所知道的深度學習是一種謊言
- 如何設置 Amazon AWS EC2 GPU 以訓練 Keras 深度學習模型(分步)
- 神經網絡中批量和迭代之間的區別是什么?
- 在 Keras 展示深度學習模型訓練歷史
- 基于 Keras 的深度學習模型中的dropout正則化
- 評估 Keras 中深度學習模型的表現
- 如何評價深度學習模型的技巧
- 小批量梯度下降的簡要介紹以及如何配置批量大小
- 在 Keras 中獲得深度學習幫助的 9 種方法
- 如何使用 Keras 在 Python 中網格搜索深度學習模型的超參數
- 用 Keras 在 Python 中使用卷積神經網絡進行手寫數字識別
- 如何用 Keras 進行預測
- 用 Keras 進行深度學習的圖像增強
- 8 個深度學習的鼓舞人心的應用
- Python 深度學習庫 Keras 簡介
- Python 深度學習庫 TensorFlow 簡介
- Python 深度學習庫 Theano 簡介
- 如何使用 Keras 函數式 API 進行深度學習
- Keras 深度學習庫的多類分類教程
- 多層感知器神經網絡速成課程
- 基于卷積神經網絡的 Keras 深度學習庫中的目標識別
- 流行的深度學習庫
- 用深度學習預測電影評論的情感
- Python 中的 Keras 深度學習庫的回歸教程
- 如何使用 Keras 獲得可重現的結果
- 如何在 Linux 服務器上運行深度學習實驗
- 保存并加載您的 Keras 深度學習模型
- 用 Keras 逐步開發 Python 中的第一個神經網絡
- 用 Keras 理解 Python 中的有狀態 LSTM 循環神經網絡
- 在 Python 中使用 Keras 深度學習模型和 Scikit-Learn
- 如何使用預訓練的 VGG 模型對照片中的物體進行分類
- 在 Python 和 Keras 中對深度學習模型使用學習率調度
- 如何在 Keras 中可視化深度學習神經網絡模型
- 什么是深度學習?
- 何時使用 MLP,CNN 和 RNN 神經網絡
- 為什么用隨機權重初始化神經網絡?
- Machine Learning Mastery 深度學習 NLP 教程
- 深度學習在自然語言處理中的 7 個應用
- 如何實現自然語言處理的波束搜索解碼器
- 深度學習文檔分類的最佳實踐
- 關于自然語言處理的熱門書籍
- 在 Python 中計算文本 BLEU 分數的溫和介紹
- 使用編碼器 - 解碼器模型的用于字幕生成的注入和合并架構
- 如何用 Python 清理機器學習的文本
- 如何配置神經機器翻譯的編碼器 - 解碼器模型
- 如何開始深度學習自然語言處理(7 天迷你課程)
- 自然語言處理的數據集
- 如何開發一種深度學習的詞袋模型來預測電影評論情感
- 深度學習字幕生成模型的溫和介紹
- 如何在 Keras 中定義神經機器翻譯的編碼器 - 解碼器序列 - 序列模型
- 如何利用小實驗在 Keras 中開發字幕生成模型
- 如何從頭開發深度學習圖片標題生成器
- 如何在 Keras 中開發基于字符的神經語言模型
- 如何開發用于情感分析的 N-gram 多通道卷積神經網絡
- 如何從零開始開發神經機器翻譯系統
- 如何在 Python 中用 Keras 開發基于單詞的神經語言模型
- 如何開發一種預測電影評論情感的詞嵌入模型
- 如何使用 Gensim 在 Python 中開發詞嵌入
- 用于文本摘要的編碼器 - 解碼器深度學習模型
- Keras 中文本摘要的編碼器 - 解碼器模型
- 用于神經機器翻譯的編碼器 - 解碼器循環神經網絡模型
- 淺談詞袋模型
- 文本摘要的溫和介紹
- 編碼器 - 解碼器循環神經網絡中的注意力如何工作
- 如何利用深度學習自動生成照片的文本描述
- 如何開發一個單詞級神經語言模型并用它來生成文本
- 淺談神經機器翻譯
- 什么是自然語言處理?
- 牛津自然語言處理深度學習課程
- 如何為機器翻譯準備法語到英語的數據集
- 如何為情感分析準備電影評論數據
- 如何為文本摘要準備新聞文章
- 如何準備照片標題數據集以訓練深度學習模型
- 如何使用 Keras 為深度學習準備文本數據
- 如何使用 scikit-learn 為機器學習準備文本數據
- 自然語言處理神經網絡模型入門
- 對自然語言處理的深度學習的承諾
- 在 Python 中用 Keras 進行 LSTM 循環神經網絡的序列分類
- 斯坦福自然語言處理深度學習課程評價
- 統計語言建模和神經語言模型的簡要介紹
- 使用 Keras 在 Python 中進行 LSTM 循環神經網絡的文本生成
- 淺談機器學習中的轉換
- 如何使用 Keras 將詞嵌入層用于深度學習
- 什么是用于文本的詞嵌入
- Machine Learning Mastery 深度學習時間序列教程
- 如何開發人類活動識別的一維卷積神經網絡模型
- 人類活動識別的深度學習模型
- 如何評估人類活動識別的機器學習算法
- 時間序列預測的多層感知器網絡探索性配置
- 比較經典和機器學習方法進行時間序列預測的結果
- 如何通過深度學習快速獲得時間序列預測的結果
- 如何利用 Python 處理序列預測問題中的缺失時間步長
- 如何建立預測大氣污染日的概率預測模型
- 如何開發一種熟練的機器學習時間序列預測模型
- 如何構建家庭用電自回歸預測模型
- 如何開發多步空氣污染時間序列預測的自回歸預測模型
- 如何制定多站點多元空氣污染時間序列預測的基線預測
- 如何開發時間序列預測的卷積神經網絡模型
- 如何開發卷積神經網絡用于多步時間序列預測
- 如何開發單變量時間序列預測的深度學習模型
- 如何開發 LSTM 模型用于家庭用電的多步時間序列預測
- 如何開發 LSTM 模型進行時間序列預測
- 如何開發多元多步空氣污染時間序列預測的機器學習模型
- 如何開發多層感知器模型進行時間序列預測
- 如何開發人類活動識別時間序列分類的 RNN 模型
- 如何開始深度學習的時間序列預測(7 天迷你課程)
- 如何網格搜索深度學習模型進行時間序列預測
- 如何對單變量時間序列預測的網格搜索樸素方法
- 如何在 Python 中搜索 SARIMA 模型超參數用于時間序列預測
- 如何在 Python 中進行時間序列預測的網格搜索三次指數平滑
- 一個標準的人類活動識別問題的溫和介紹
- 如何加載和探索家庭用電數據
- 如何加載,可視化和探索復雜的多變量多步時間序列預測數據集
- 如何從智能手機數據模擬人類活動
- 如何根據環境因素預測房間占用率
- 如何使用腦波預測人眼是開放還是閉合
- 如何在 Python 中擴展長短期內存網絡的數據
- 如何使用 TimeseriesGenerator 進行 Keras 中的時間序列預測
- 基于機器學習算法的室內運動時間序列分類
- 用于時間序列預測的狀態 LSTM 在線學習的不穩定性
- 用于罕見事件時間序列預測的 LSTM 模型體系結構
- 用于時間序列預測的 4 種通用機器學習數據變換
- Python 中長短期記憶網絡的多步時間序列預測
- 家庭用電機器學習的多步時間序列預測
- Keras 中 LSTM 的多變量時間序列預測
- 如何開發和評估樸素的家庭用電量預測方法
- 如何為長短期記憶網絡準備單變量時間序列數據
- 循環神經網絡在時間序列預測中的應用
- 如何在 Python 中使用差異變換刪除趨勢和季節性
- 如何在 LSTM 中種子狀態用于 Python 中的時間序列預測
- 使用 Python 進行時間序列預測的有狀態和無狀態 LSTM
- 長短時記憶網絡在時間序列預測中的適用性
- 時間序列預測問題的分類
- Python 中長短期記憶網絡的時間序列預測
- 基于 Keras 的 Python 中 LSTM 循環神經網絡的時間序列預測
- Keras 中深度學習的時間序列預測
- 如何用 Keras 調整 LSTM 超參數進行時間序列預測
- 如何在時間序列預測訓練期間更新 LSTM 網絡
- 如何使用 LSTM 網絡的 Dropout 進行時間序列預測
- 如何使用 LSTM 網絡中的特征進行時間序列預測
- 如何在 LSTM 網絡中使用時間序列進行時間序列預測
- 如何利用 LSTM 網絡進行權重正則化進行時間序列預測
- Machine Learning Mastery 線性代數教程
- 機器學習數學符號的基礎知識
- 用 NumPy 陣列輕松介紹廣播
- 如何從 Python 中的 Scratch 計算主成分分析(PCA)
- 用于編碼器審查的計算線性代數
- 10 機器學習中的線性代數示例
- 線性代數的溫和介紹
- 用 NumPy 輕松介紹 Python 中的 N 維數組
- 機器學習向量的溫和介紹
- 如何在 Python 中為機器學習索引,切片和重塑 NumPy 數組
- 機器學習的矩陣和矩陣算法簡介
- 溫和地介紹機器學習的特征分解,特征值和特征向量
- NumPy 對預期價值,方差和協方差的簡要介紹
- 機器學習矩陣分解的溫和介紹
- 用 NumPy 輕松介紹機器學習的張量
- 用于機器學習的線性代數中的矩陣類型簡介
- 用于機器學習的線性代數備忘單
- 線性代數的深度學習
- 用于機器學習的線性代數(7 天迷你課程)
- 機器學習的線性代數
- 機器學習矩陣運算的溫和介紹
- 線性代數評論沒有廢話指南
- 學習機器學習線性代數的主要資源
- 淺談機器學習的奇異值分解
- 如何用線性代數求解線性回歸
- 用于機器學習的稀疏矩陣的溫和介紹
- 機器學習中向量規范的溫和介紹
- 學習線性代數用于機器學習的 5 個理由
- Machine Learning Mastery LSTM 教程
- Keras中長短期記憶模型的5步生命周期
- 長短時記憶循環神經網絡的注意事項
- CNN長短期記憶網絡
- 逆向神經網絡中的深度學習速成課程
- 可變長度輸入序列的數據準備
- 如何用Keras開發用于Python序列分類的雙向LSTM
- 如何開發Keras序列到序列預測的編碼器 - 解碼器模型
- 如何診斷LSTM模型的過度擬合和欠擬合
- 如何開發一種編碼器 - 解碼器模型,注重Keras中的序列到序列預測
- 編碼器 - 解碼器長短期存儲器網絡
- 神經網絡中爆炸梯度的溫和介紹
- 對時間反向傳播的溫和介紹
- 生成長短期記憶網絡的溫和介紹
- 專家對長短期記憶網絡的簡要介紹
- 在序列預測問題上充分利用LSTM
- 編輯器 - 解碼器循環神經網絡全局注意的溫和介紹
- 如何利用長短時記憶循環神經網絡處理很長的序列
- 如何在Python中對一個熱編碼序列數據
- 如何使用編碼器 - 解碼器LSTM來回顯隨機整數序列
- 具有注意力的編碼器 - 解碼器RNN體系結構的實現模式
- 學習使用編碼器解碼器LSTM循環神經網絡添加數字
- 如何學習長短時記憶循環神經網絡回聲隨機整數
- 具有Keras的長短期記憶循環神經網絡的迷你課程
- LSTM自動編碼器的溫和介紹
- 如何用Keras中的長短期記憶模型進行預測
- 用Python中的長短期內存網絡演示內存
- 基于循環神經網絡的序列預測模型的簡要介紹
- 深度學習的循環神經網絡算法之旅
- 如何重塑Keras中長短期存儲網絡的輸入數據
- 了解Keras中LSTM的返回序列和返回狀態之間的差異
- RNN展開的溫和介紹
- 5學習LSTM循環神經網絡的簡單序列預測問題的例子
- 使用序列進行預測
- 堆疊長短期內存網絡
- 什么是教師強制循環神經網絡?
- 如何在Python中使用TimeDistributed Layer for Long Short-Term Memory Networks
- 如何準備Keras中截斷反向傳播的序列預測
- 如何在使用LSTM進行訓練和預測時使用不同的批量大小
- Machine Learning Mastery 機器學習算法教程
- 機器學習算法之旅
- 用于機器學習的裝袋和隨機森林集合算法
- 從頭開始實施機器學習算法的好處
- 更好的樸素貝葉斯:從樸素貝葉斯算法中獲取最多的12個技巧
- 機器學習的提升和AdaBoost
- 選擇機器學習算法:Microsoft Azure的經驗教訓
- 機器學習的分類和回歸樹
- 什么是機器學習中的混淆矩陣
- 如何使用Python從頭開始創建算法測試工具
- 通過創建機器學習算法的目標列表來控制
- 從頭開始停止編碼機器學習算法
- 在實現機器學習算法時,不要從開源代碼開始
- 不要使用隨機猜測作為基線分類器
- 淺談機器學習中的概念漂移
- 溫和介紹機器學習中的偏差 - 方差權衡
- 機器學習的梯度下降
- 機器學習算法如何工作(他們學習輸入到輸出的映射)
- 如何建立機器學習算法的直覺
- 如何實現機器學習算法
- 如何研究機器學習算法行為
- 如何學習機器學習算法
- 如何研究機器學習算法
- 如何研究機器學習算法
- 如何在Python中從頭開始實現反向傳播算法
- 如何用Python從頭開始實現Bagging
- 如何用Python從頭開始實現基線機器學習算法
- 如何在Python中從頭開始實現決策樹算法
- 如何用Python從頭開始實現學習向量量化
- 如何利用Python從頭開始隨機梯度下降實現線性回歸
- 如何利用Python從頭開始隨機梯度下降實現Logistic回歸
- 如何用Python從頭開始實現機器學習算法表現指標
- 如何在Python中從頭開始實現感知器算法
- 如何在Python中從零開始實現隨機森林
- 如何在Python中從頭開始實現重采樣方法
- 如何用Python從頭開始實現簡單線性回歸
- 如何用Python從頭開始實現堆棧泛化(Stacking)
- K-Nearest Neighbors for Machine Learning
- 學習機器學習的向量量化
- 機器學習的線性判別分析
- 機器學習的線性回歸
- 使用梯度下降進行機器學習的線性回歸教程
- 如何在Python中從頭開始加載機器學習數據
- 機器學習的Logistic回歸
- 機器學習的Logistic回歸教程
- 機器學習算法迷你課程
- 如何在Python中從頭開始實現樸素貝葉斯
- 樸素貝葉斯機器學習
- 樸素貝葉斯機器學習教程
- 機器學習算法的過擬合和欠擬合
- 參數化和非參數機器學習算法
- 理解任何機器學習算法的6個問題
- 在機器學習中擁抱隨機性
- 如何使用Python從頭開始擴展機器學習數據
- 機器學習的簡單線性回歸教程
- 有監督和無監督的機器學習算法
- 用于機器學習的支持向量機
- 在沒有數學背景的情況下理解機器學習算法的5種技術
- 最好的機器學習算法
- 教程從頭開始在Python中實現k-Nearest Neighbors
- 通過從零開始實現它們來理解機器學習算法(以及繞過壞代碼的策略)
- 使用隨機森林:在121個數據集上測試179個分類器
- 為什么從零開始實現機器學習算法
- Machine Learning Mastery 機器學習入門教程
- 機器學習入門的四個步驟:初學者入門與實踐的自上而下策略
- 你應該培養的 5 個機器學習領域
- 一種選擇機器學習算法的數據驅動方法
- 機器學習中的分析與數值解
- 應用機器學習是一種精英政治
- 機器學習的基本概念
- 如何成為數據科學家
- 初學者如何在機器學習中弄錯
- 機器學習的最佳編程語言
- 構建機器學習組合
- 機器學習中分類與回歸的區別
- 評估自己作為數據科學家并利用結果建立驚人的數據科學團隊
- 探索 Kaggle 大師的方法論和心態:對 Diogo Ferreira 的采訪
- 擴展機器學習工具并展示掌握
- 通過尋找地標開始機器學習
- 溫和地介紹預測建模
- 通過提供結果在機器學習中獲得夢想的工作
- 如何開始機器學習:自學藍圖
- 開始并在機器學習方面取得進展
- 應用機器學習的 Hello World
- 初學者如何使用小型項目開始機器學習并在 Kaggle 上進行競爭
- 我如何開始機器學習? (簡短版)
- 我是如何開始機器學習的
- 如何在機器學習中取得更好的成績
- 如何從在銀行工作到擔任 Target 的高級數據科學家
- 如何學習任何機器學習工具
- 使用小型目標項目深入了解機器學習工具
- 獲得付費申請機器學習
- 映射機器學習工具的景觀
- 機器學習開發環境
- 機器學習金錢
- 程序員的機器學習
- 機器學習很有意思
- 機器學習是 Kaggle 比賽
- 機器學習現在很受歡迎
- 機器學習掌握方法
- 機器學習很重要
- 機器學習 Q& A:概念漂移,更好的結果和學習更快
- 缺乏自學機器學習的路線圖
- 機器學習很重要
- 快速了解任何機器學習工具(即使您是初學者)
- 機器學習工具
- 找到你的機器學習部落
- 機器學習在一年
- 通過競爭一致的大師 Kaggle
- 5 程序員在機器學習中開始犯錯誤
- 哲學畢業生到機器學習從業者(Brian Thomas 采訪)
- 機器學習入門的實用建議
- 實用機器學習問題
- 使用來自 UCI 機器學習庫的數據集練習機器學習
- 使用秘籍的任何機器學習工具快速啟動
- 程序員可以進入機器學習
- 程序員應該進入機器學習
- 項目焦點:Shashank Singh 的人臉識別
- 項目焦點:使用 Mahout 和 Konstantin Slisenko 進行堆棧交換群集
- 機器學習自學指南
- 4 個自學機器學習項目
- álvaroLemos 如何在數據科學團隊中獲得機器學習實習
- 如何思考機器學習
- 現實世界機器學習問題之旅
- 有關機器學習的有用知識
- 如果我沒有學位怎么辦?
- 如果我不是一個優秀的程序員怎么辦?
- 如果我不擅長數學怎么辦?
- 為什么機器學習算法會處理以前從未見過的數據?
- 是什么阻礙了你的機器學習目標?
- 什么是機器學習?
- 機器學習適合哪里?
- 為什么要進入機器學習?
- 研究對您來說很重要的機器學習問題
- 你這樣做是錯的。為什么機器學習不必如此困難
- Machine Learning Mastery Sklearn 教程
- Scikit-Learn 的溫和介紹:Python 機器學習庫
- 使用 Python 管道和 scikit-learn 自動化機器學習工作流程
- 如何以及何時使用帶有 scikit-learn 的校準分類模型
- 如何比較 Python 中的機器學習算法與 scikit-learn
- 用于機器學習開發人員的 Python 崩潰課程
- 用 scikit-learn 在 Python 中集成機器學習算法
- 使用重采樣評估 Python 中機器學習算法的表現
- 使用 Scikit-Learn 在 Python 中進行特征選擇
- Python 中機器學習的特征選擇
- 如何使用 scikit-learn 在 Python 中生成測試數據集
- scikit-learn 中的機器學習算法秘籍
- 如何使用 Python 處理丟失的數據
- 如何開始使用 Python 進行機器學習
- 如何使用 Scikit-Learn 在 Python 中加載數據
- Python 中概率評分方法的簡要介紹
- 如何用 Scikit-Learn 調整算法參數
- 如何在 Mac OS X 上安裝 Python 3 環境以進行機器學習和深度學習
- 使用 scikit-learn 進行機器學習簡介
- 從 shell 到一本帶有 Fernando Perez 單一工具的書的 IPython
- 如何使用 Python 3 為機器學習開發創建 Linux 虛擬機
- 如何在 Python 中加載機器學習數據
- 您在 Python 中的第一個機器學習項目循序漸進
- 如何使用 scikit-learn 進行預測
- 用于評估 Python 中機器學習算法的度量標準
- 使用 Pandas 為 Python 中的機器學習準備數據
- 如何使用 Scikit-Learn 為 Python 機器學習準備數據
- 項目焦點:使用 Artem Yankov 在 Python 中進行事件推薦
- 用于機器學習的 Python 生態系統
- Python 是應用機器學習的成長平臺
- Python 機器學習書籍
- Python 機器學習迷你課程
- 使用 Pandas 快速和骯臟的數據分析
- 使用 Scikit-Learn 重新調整 Python 中的機器學習數據
- 如何以及何時使用 ROC 曲線和精確調用曲線進行 Python 分類
- 使用 scikit-learn 在 Python 中保存和加載機器學習模型
- scikit-learn Cookbook 書評
- 如何使用 Anaconda 為機器學習和深度學習設置 Python 環境
- 使用 scikit-learn 在 Python 中進行 Spot-Check 分類機器學習算法
- 如何在 Python 中開發可重復使用的抽樣檢查算法框架
- 使用 scikit-learn 在 Python 中進行 Spot-Check 回歸機器學習算法
- 使用 Python 中的描述性統計來了解您的機器學習數據
- 使用 OpenCV,Python 和模板匹配來播放“哪里是 Waldo?”
- 使用 Pandas 在 Python 中可視化機器學習數據
- Machine Learning Mastery 統計學教程
- 淺談計算正態匯總統計量
- 非參數統計的溫和介紹
- Python中常態測試的溫和介紹
- 淺談Bootstrap方法
- 淺談機器學習的中心極限定理
- 淺談機器學習中的大數定律
- 機器學習的所有統計數據
- 如何計算Python中機器學習結果的Bootstrap置信區間
- 淺談機器學習的Chi-Squared測試
- 機器學習的置信區間
- 隨機化在機器學習中解決混雜變量的作用
- 機器學習中的受控實驗
- 機器學習統計學速成班
- 統計假設檢驗的關鍵值以及如何在Python中計算它們
- 如何在機器學習中談論數據(統計學和計算機科學術語)
- Python中數據可視化方法的簡要介紹
- Python中效果大小度量的溫和介紹
- 估計隨機機器學習算法的實驗重復次數
- 機器學習評估統計的溫和介紹
- 如何計算Python中的非參數秩相關性
- 如何在Python中計算數據的5位數摘要
- 如何在Python中從頭開始編寫學生t檢驗
- 如何在Python中生成隨機數
- 如何轉換數據以更好地擬合正態分布
- 如何使用相關來理解變量之間的關系
- 如何使用統計信息識別數據中的異常值
- 用于Python機器學習的隨機數生成器簡介
- k-fold交叉驗證的溫和介紹
- 如何計算McNemar的比較兩種機器學習量詞的測試
- Python中非參數統計顯著性測試簡介
- 如何在Python中使用參數統計顯著性測試
- 機器學習的預測間隔
- 應用統計學與機器學習的密切關系
- 如何使用置信區間報告分類器表現
- 統計數據分布的簡要介紹
- 15 Python中的統計假設檢驗(備忘單)
- 統計假設檢驗的溫和介紹
- 10如何在機器學習項目中使用統計方法的示例
- Python中統計功效和功耗分析的簡要介紹
- 統計抽樣和重新抽樣的簡要介紹
- 比較機器學習算法的統計顯著性檢驗
- 機器學習中統計容差區間的溫和介紹
- 機器學習統計書籍
- 評估機器學習模型的統計數據
- 機器學習統計(7天迷你課程)
- 用于機器學習的簡明英語統計
- 如何使用統計顯著性檢驗來解釋機器學習結果
- 什么是統計(為什么它在機器學習中很重要)?
- Machine Learning Mastery 時間序列入門教程
- 如何在 Python 中為時間序列預測創建 ARIMA 模型
- 用 Python 進行時間序列預測的自回歸模型
- 如何回溯機器學習模型的時間序列預測
- Python 中基于時間序列數據的基本特征工程
- R 的時間序列預測熱門書籍
- 10 挑戰機器學習時間序列預測問題
- 如何將時間序列轉換為 Python 中的監督學習問題
- 如何將時間序列數據分解為趨勢和季節性
- 如何用 ARCH 和 GARCH 模擬波動率進行時間序列預測
- 如何將時間序列數據集與 Python 區分開來
- Python 中時間序列預測的指數平滑的溫和介紹
- 用 Python 進行時間序列預測的特征選擇
- 淺談自相關和部分自相關
- 時間序列預測的 Box-Jenkins 方法簡介
- 用 Python 簡要介紹時間序列的時間序列預測
- 如何使用 Python 網格搜索 ARIMA 模型超參數
- 如何在 Python 中加載和探索時間序列數據
- 如何使用 Python 對 ARIMA 模型進行手動預測
- 如何用 Python 進行時間序列預測的預測
- 如何使用 Python 中的 ARIMA 進行樣本外預測
- 如何利用 Python 模擬殘差錯誤來糾正時間序列預測
- 使用 Python 進行數據準備,特征工程和時間序列預測的移動平均平滑
- 多步時間序列預測的 4 種策略
- 如何在 Python 中規范化和標準化時間序列數據
- 如何利用 Python 進行時間序列預測的基線預測
- 如何使用 Python 對時間序列預測數據進行功率變換
- 用于時間序列預測的 Python 環境
- 如何重構時間序列預測問題
- 如何使用 Python 重新采樣和插值您的時間序列數據
- 用 Python 編寫 SARIMA 時間序列預測
- 如何在 Python 中保存 ARIMA 時間序列預測模型
- 使用 Python 進行季節性持久性預測
- 基于 ARIMA 的 Python 歷史規模敏感性預測技巧分析
- 簡單的時間序列預測模型進行測試,這樣你就不會欺騙自己
- 標準多變量,多步驟和多站點時間序列預測問題
- 如何使用 Python 檢查時間序列數據是否是固定的
- 使用 Python 進行時間序列數據可視化
- 7 個機器學習的時間序列數據集
- 時間序列預測案例研究與 Python:波士頓每月武裝搶劫案
- Python 的時間序列預測案例研究:巴爾的摩的年度用水量
- 使用 Python 進行時間序列預測研究:法國香檳的月銷售額
- 使用 Python 的置信區間理解時間序列預測不確定性
- 11 Python 中的經典時間序列預測方法(備忘單)
- 使用 Python 進行時間序列預測表現測量
- 使用 Python 7 天迷你課程進行時間序列預測
- 時間序列預測作為監督學習
- 什么是時間序列預測?
- 如何使用 Python 識別和刪除時間序列數據的季節性
- 如何在 Python 中使用和刪除時間序列數據中的趨勢信息
- 如何在 Python 中調整 ARIMA 參數
- 如何用 Python 可視化時間序列殘差預測錯誤
- 白噪聲時間序列與 Python
- 如何通過時間序列預測項目
- Machine Learning Mastery XGBoost 教程
- 通過在 Python 中使用 XGBoost 提前停止來避免過度擬合
- 如何在 Python 中調優 XGBoost 的多線程支持
- 如何配置梯度提升算法
- 在 Python 中使用 XGBoost 進行梯度提升的數據準備
- 如何使用 scikit-learn 在 Python 中開發您的第一個 XGBoost 模型
- 如何在 Python 中使用 XGBoost 評估梯度提升模型
- 在 Python 中使用 XGBoost 的特征重要性和特征選擇
- 淺談機器學習的梯度提升算法
- 應用機器學習的 XGBoost 簡介
- 如何在 macOS 上為 Python 安裝 XGBoost
- 如何在 Python 中使用 XGBoost 保存梯度提升模型
- 從梯度提升開始,比較 165 個數據集上的 13 種算法
- 在 Python 中使用 XGBoost 和 scikit-learn 進行隨機梯度提升
- 如何使用 Amazon Web Services 在云中訓練 XGBoost 模型
- 在 Python 中使用 XGBoost 調整梯度提升的學習率
- 如何在 Python 中使用 XGBoost 調整決策樹的數量和大小
- 如何在 Python 中使用 XGBoost 可視化梯度提升決策樹
- 在 Python 中開始使用 XGBoost 的 7 步迷你課程