乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      在Keras中使用LSTM模型進(jìn)行多變量時(shí)間序列預(yù)測

       imelee 2019-08-25

      今天我給大家介紹一個(gè)國外深度學(xué)習(xí)大牛Jason Brownlee寫的一篇關(guān)于多變量時(shí)間序列預(yù)測的博客,我在原文的代碼基礎(chǔ)上做了一點(diǎn)點(diǎn)修改,只是為了便于大家更好的理解。在本文中,您將了解如何在Keras深度學(xué)習(xí)庫中為多變量時(shí)間序列預(yù)測開發(fā)LSTM模型。讀完成本文后,您將了解:

      • 如何將原始數(shù)據(jù)集轉(zhuǎn)換為可用于時(shí)間序列預(yù)測的數(shù)據(jù)。

      • 如何準(zhǔn)備數(shù)據(jù)并使LSTM適合多變量時(shí)間序列預(yù)測問題。

      • 如何進(jìn)行預(yù)測并將結(jié)果重新調(diào)整回原始單位。

      空氣污染的預(yù)測

      在本文中,我們將使用空氣質(zhì)量數(shù)據(jù)集。

      這個(gè)數(shù)據(jù)集來自于在美國駐中國大使館收集的北京五年的每小時(shí)的空氣質(zhì)量數(shù)據(jù)。

      數(shù)據(jù)包括日期時(shí)間,PM2.5濃度,以及包括露點(diǎn),溫度,氣壓,風(fēng)向,風(fēng)速和累積的下雪小時(shí)數(shù)的天氣信息。原始數(shù)據(jù)中的完整功能列表如下:

      • No : 行號(hào)

      • year,month,day,hour : 表示年,月,日,小時(shí)

      • pm2.5 : pm2.5污染濃度

      • DEWP : 露點(diǎn)(空氣中水氣含量達(dá)到飽和的氣溫,低于此溫度時(shí)水氣從空氣中析出凝成水珠) 

      • TEMP : 溫度

      • PRES : 氣壓

      • cbwd :風(fēng)向

      • Iws : 風(fēng)速

      • ls : 累積的下雪小時(shí)數(shù)

      • lr : 累積的下小時(shí)數(shù)

      我們可以使用這些數(shù)據(jù)并構(gòu)建一個(gè)預(yù)測問題,我們想通過前一個(gè)小時(shí)的天氣條件和pm2.5濃度,來預(yù)測下一個(gè)小時(shí)的pm2.5濃度。

      你們可以在這里下載空氣質(zhì)量數(shù)據(jù)。

      下面我們查看一下數(shù)據(jù)

      1. df = pd.read_csv('./data/pollution.csv')
      2. print(len(df))
      3. df.head(10)
      4. print(f.year.unique())

      從上面的數(shù)據(jù)中我們看到數(shù)據(jù)集中總共有43824條記錄,時(shí)間是從2010至2014總共5年的數(shù)據(jù),數(shù)據(jù)集中前n條數(shù)據(jù)的pm2.5的值是空值(NaN),下面我們要對數(shù)據(jù)做一些清洗工作,我們要合并年,月,日,小時(shí)并將其設(shè)置為索引例,同時(shí)刪除原來的年,月,日,小時(shí)字段。

      1. df['date']=df.apply(lambda x:datetime.datetime(x["year"], x["month"], x["day"],x["hour"]), axis=1)
      2. df = df.set_index(['date'])
      3. df.drop(['No','year','month','day','hour'], axis=1, inplace=True)
      4. df.head()

      接下來我們重新命名數(shù)據(jù)集的字段名,并刪除前24條pm2.5的值為空的記錄

      1. df.columns = ['pollution', 'dew', 'temp', 'press', 'wnd_dir', 'wnd_spd', 'snow', 'rain']
      2. df['pollution'].fillna(0, inplace=True)
      3. # 刪除前24小時(shí)的數(shù)據(jù)
      4. df = df[24:]
      5. df.head()

      下面我們對除風(fēng)向(wnd_dir)以外的7個(gè)變量進(jìn)行可視化,我們要查看一下它們的時(shí)序圖

      1. values = df.values
      2. # 指定要可視化的例
      3. groups = [0, 1, 2, 3, 5, 6, 7]
      4. i = 1
      5. # plot each column
      6. plt.figure(figsize=(8,6))
      7. for group in groups:
      8. plt.subplot(len(groups), 1, i)
      9. plt.plot(values[:, group])
      10. plt.title(df.columns[group], y=0.5, loc='right')
      11. i += 1
      12. plt.show()

      多變量LSTM預(yù)測模型

      在目前這個(gè)應(yīng)用場景中,我們的特征變量有7個(gè)(除pollution變量以外的所有變量),而我們的目標(biāo)變量只有一個(gè)(pollution),我們想通過前一小時(shí)的7個(gè)特征境變量來預(yù)測后一小時(shí)的污染濃度變量(pollution),這就是一個(gè)典型的多變量時(shí)間序列預(yù)測的問題。下面我們要使用LSTM模型來解決這個(gè)多變量時(shí)間序列的預(yù)測問題。

      為LSTM模型準(zhǔn)備數(shù)據(jù)

      這里將是本文的一個(gè)重點(diǎn),目前的我們的數(shù)據(jù)集是一個(gè)時(shí)間序列數(shù)據(jù)集,它沒有標(biāo)簽,接下來我們要做的就是將時(shí)間序列數(shù)據(jù)轉(zhuǎn)換成監(jiān)督學(xué)習(xí)的數(shù)據(jù),并且生成標(biāo)簽。然后對輸入的變量進(jìn)行標(biāo)準(zhǔn)化處理。 考慮到污染測量和前一時(shí)刻(t-1)的天氣條件,我們將監(jiān)督學(xué)習(xí)問題設(shè)定為預(yù)測當(dāng)前小時(shí)(t)的污染濃度。

      如何將時(shí)間序列數(shù)據(jù)轉(zhuǎn)換成監(jiān)督學(xué)習(xí)的數(shù)據(jù)?這里我們定義了一個(gè)函數(shù):series_to_supervised(), 它通過數(shù)據(jù)平移的方式將我們的目標(biāo)變量前移一個(gè)時(shí)間單位,這樣就形成了數(shù)據(jù)的標(biāo)簽,有了標(biāo)簽它就變成了監(jiān)督學(xué)習(xí)的數(shù)據(jù),這樣我們就可以訓(xùn)練lstm模型了。

      1. # 將序列轉(zhuǎn)換成監(jiān)督式學(xué)習(xí)
      2. def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
      3. n_vars = 1 if type(data) is list else data.shape[1]
      4. df = pd.DataFrame(data)
      5. cols, names = list(), list()
      6. # 輸入序列(t-n, ... t-1)
      7. for i in range(n_in, 0, -1):
      8. cols.append(df.shift(i))
      9. names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
      10. # 預(yù)測序列 (t, t+1, ... t+n)
      11. for i in range(0, n_out):
      12. cols.append(df.shift(-i))
      13. if i == 0:
      14. names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
      15. else:
      16. names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
      17. # 將他們整合在一起
      18. agg = pd.concat(cols, axis=1)
      19. agg.columns = names
      20. # 刪除那些包含空值(NaN)的行
      21. if dropnan:
      22. agg.dropna(inplace=True)
      23. return agg
      1. values = df.values
      2. #對風(fēng)向字段進(jìn)行編碼
      3. encoder = LabelEncoder()
      4. values[:,4] = encoder.fit_transform(values[:,4])
      5. # 確保所有變量都是實(shí)數(shù)型
      6. values = values.astype('float32')
      7. #對數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化出來
      8. scaler = MinMaxScaler(feature_range=(0, 1))
      9. scaled = scaler.fit_transform(values)
      10. # 將時(shí)間序列數(shù)據(jù)轉(zhuǎn)換成監(jiān)督學(xué)習(xí)數(shù)據(jù)
      11. reframed = series_to_supervised(scaled, 1, 1)
      12. # 刪除那些不需要預(yù)測的列
      13. reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True)
      14. reframed.head()

      從上面的輸出結(jié)果中我們看見var(t-1)至var8(t-1)為我們的前一小時(shí)的特征變量,var1(t)為當(dāng)前時(shí)刻t的目標(biāo)變量,var(t)是var(t-1)進(jìn)行一次數(shù)據(jù)平移所產(chǎn)生的結(jié)果。這樣我們就可以利用t-1時(shí)刻的特征數(shù)據(jù)來預(yù)測t時(shí)刻污染濃度。

      到目前為止我們已經(jīng)有了特征集和標(biāo)簽,下面我們就可以為LSTM模型準(zhǔn)備訓(xùn)練集和測試集了。由于這是時(shí)間序列的數(shù)據(jù),t時(shí)刻的污染濃度和t-1時(shí)刻的天氣條件是有密切關(guān)系的,所以在準(zhǔn)訓(xùn)練集和測試集時(shí),我們不能對原始數(shù)據(jù)進(jìn)行亂序操作。這里我們要按順序?qū)⒌谝荒甑臄?shù)據(jù)作為訓(xùn)練集,將后面四年的數(shù)據(jù)作為測試集。然后我們將訓(xùn)練集和測試集轉(zhuǎn)化成3維數(shù)組的格式。

      1. # 將數(shù)據(jù)分割為訓(xùn)練集和測試集
      2. values = reframed.values
      3. n_train_hours = 365 * 24
      4. train = values[:n_train_hours, :]
      5. test = values[n_train_hours:, :]
      6. # 分離出特征集與標(biāo)簽
      7. train_X, train_y = train[:, :-1], train[:, -1]
      8. test_X, test_y = test[:, :-1], test[:, -1]
      9. # 轉(zhuǎn)換成3維數(shù)組 [樣本數(shù), 時(shí)間步 ,特征數(shù)]
      10. train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
      11. test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
      12. print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)

      定義LSTM模型

      我們將定義一個(gè)LSTM模型,在它的第一個(gè)隱藏層中有50個(gè)神經(jīng)元,在輸出層中有1個(gè)神經(jīng)元用于預(yù)測污染濃度。輸入數(shù)據(jù)的維度將是1個(gè)時(shí)間步(即1小時(shí))和8個(gè)特征。

      我們將使用平均絕對誤差(MAE)損失函數(shù)和隨機(jī)梯度下降的有效Adam版本。該模型的批量大小(batch_size)為72的50個(gè)訓(xùn)練周期。請記住,Keras中LSTM的內(nèi)部狀態(tài)在每個(gè)批次結(jié)束時(shí)重置,因此內(nèi)部狀態(tài)可能是天數(shù)的函數(shù),這可能會(huì)對你有幫助。

      最后,我們通過在fit()方法中設(shè)置validation_data參數(shù)來跟蹤訓(xùn)練期間的訓(xùn)練和測試損失。在訓(xùn)練結(jié)束時(shí),對訓(xùn)練和測試損失進(jìn)行可視化。

      1. # 創(chuàng)建模型
      2. model = Sequential()
      3. model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
      4. model.add(Dense(1))
      5. model.compile(loss='mae', optimizer='adam')
      6. print(model.summary())

      訓(xùn)練LSTM模型

      1. # 訓(xùn)練模型
      2. history = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
      3. # 對損失進(jìn)行可視化
      4. plt.plot(history.history['loss'], label='train')
      5. plt.plot(history.history['val_loss'], label='test')
      6. plt.legend()
      7. plt.show()

      評估LSTM模型

      在模型訓(xùn)練結(jié)束后,我們可以預(yù)測整個(gè)測試數(shù)據(jù)集。由于我們在訓(xùn)練模型之前已經(jīng)將所有的特征集和標(biāo)簽進(jìn)行了標(biāo)準(zhǔn)化處理即將數(shù)據(jù)值縮放到了0-1之間,因此我們的預(yù)測結(jié)果也是在0-1之間,為了對預(yù)測結(jié)果進(jìn)行有效評估,我們必須將預(yù)測結(jié)果和標(biāo)簽值全部轉(zhuǎn)換成沒有標(biāo)準(zhǔn)處理之前的實(shí)際值,這樣我們才能進(jìn)行有效評估。

      通過將預(yù)測結(jié)果和測試集的標(biāo)簽值進(jìn)行逆向縮放,我們就得到了實(shí)際值,這樣我們可以計(jì)算模型的誤差分?jǐn)?shù)。我們使用均方根誤差(RMSE)作為評估指標(biāo)。

      1. # 對測試集進(jìn)行預(yù)測
      2. yhat = model.predict(test_X)
      3. test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
      4. # 對預(yù)測值進(jìn)行逆標(biāo)準(zhǔn)處理
      5. inv_yhat = np.concatenate((yhat, test_X[:, 1:]), axis=1)
      6. inv_yhat = scaler.inverse_transform(inv_yhat)
      7. inv_yhat = inv_yhat[:,0]
      8. # 對測試集標(biāo)簽進(jìn)行逆標(biāo)準(zhǔn)化處理
      9. test_y = test_y.reshape((len(test_y), 1))
      10. inv_y = np.concatenate((test_y, test_X[:, 1:]), axis=1)
      11. inv_y = scaler.inverse_transform(inv_y)
      12. inv_y = inv_y[:,0]
      13. # 計(jì)算 RMSE
      14. rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
      15. print('Test RMSE: %.3f' % rmse)

      完善LSTM模型:預(yù)測未來多天的污染濃度

      前面這個(gè)模型我們是用t-1時(shí)刻的天氣數(shù)據(jù)來預(yù)測t時(shí)刻的污染濃度,也就是說我們只能預(yù)測未來1小時(shí)的污染情況,有沒有辦法讓我們的模型可以預(yù)測未來幾個(gè)小時(shí)的空氣污染情況呢?

      為了解決預(yù)測未來n個(gè)小時(shí)的空氣污染濃度,我們只要將原先的特征集平移n個(gè)時(shí)間步,例如我們要預(yù)測未來3小時(shí)的污染濃度,我們只需要調(diào)用series_to_supervised方法,并將參數(shù)n_in設(shè)置為3,就可以將特征集往前平移3個(gè)時(shí)間步。

      1. # 設(shè)置預(yù)測未來3小時(shí)的污染
      2. n_hours = 3
      3. n_features = 8
      4. # 將時(shí)間序列轉(zhuǎn)換成監(jiān)督學(xué)習(xí)數(shù)據(jù)集
      5. reframed = series_to_supervised(scaled, n_hours, 1)

      我們的數(shù)據(jù)集中有3 * 8 + 8列。我們將前24列作為前3小時(shí)(t-3,t-2,t-1)的特征。我們將在下一個(gè)小時(shí)(t)的污染變量作為標(biāo)簽,如下所示:

      下面我們要做的是步驟和之間模型的步驟一樣,首頁要分離出訓(xùn)練集和測試集,然后要分離出特征集與標(biāo)簽:

      1. # 分離訓(xùn)練集和測試集
      2. values = reframed.values
      3. n_train_hours = 365 * 24
      4. train = values[:n_train_hours, :]
      5. test = values[n_train_hours:, :]
      6. # 分離特征集和標(biāo)簽
      7. n_obs = n_hours * n_features
      8. train_X, train_y = train[:, :n_obs], train[:, -n_features]
      9. test_X, test_y = test[:, :n_obs], test[:, -n_features]
      10. print(train_X.shape, len(train_X), train_y.shape)

      接下來我們要講訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù)轉(zhuǎn)換成3維數(shù)組格式,與之前的3維數(shù)組不一樣的是,此時(shí)我們?nèi)S數(shù)組的第二個(gè)維度將是3。

      1. # 轉(zhuǎn)換成3維數(shù)據(jù)格式 [樣本數(shù), 時(shí)間步, 特征數(shù)]
      2. train_X = train_X.reshape((train_X.shape[0], n_hours, n_features))
      3. test_X = test_X.reshape((test_X.shape[0], n_hours, n_features))

      訓(xùn)練模型

      1. # 定義模型
      2. model = Sequential()
      3. model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
      4. model.add(Dense(1))
      5. model.compile(loss='mae', optimizer='adam')
      6. # 訓(xùn)練模型
      7. history = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
      8. # 可視化
      9. plt.plot(history.history['loss'], label='train')
      10. plt.plot(history.history['val_loss'], label='test')
      11. plt.legend()
      12. plt.show()

      評估模型

      1. # 對測試集進(jìn)行預(yù)測
      2. yhat = model.predict(test_X)
      3. test_X = test_X.reshape((test_X.shape[0], n_hours*n_features))
      4. # 對預(yù)測數(shù)據(jù)進(jìn)行逆標(biāo)準(zhǔn)化
      5. inv_yhat = np.concatenate((yhat, test_X[:, -7:]), axis=1)
      6. inv_yhat = scaler.inverse_transform(inv_yhat)
      7. inv_yhat = inv_yhat[:,0]
      8. # 對測試集標(biāo)簽進(jìn)行逆標(biāo)準(zhǔn)化
      9. test_y = test_y.reshape((len(test_y), 1))
      10. inv_y = np.concatenate((test_y, test_X[:, -7:]), axis=1)
      11. inv_y = scaler.inverse_transform(inv_y)
      12. inv_y = inv_y[:,0]
      13. # 計(jì)算均方根誤差
      14. rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
      15. print('Test RMSE: %.3f' % rmse)

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多