久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    在Keras中使用LSTM模型進行多變量時間序列預測

     imelee 2019-08-25

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

    • 如何將原始數據集轉換為可用于時間序列預測的數據。

    • 如何準備數據并使LSTM適合多變量時間序列預測問題。

    • 如何進行預測并將結果重新調整回原始單位。

    空氣污染的預測

    在本文中,我們將使用空氣質量數據集。

    這個數據集來自于在美國駐中國大使館收集的北京五年的每小時的空氣質量數據。

    數據包括日期時間,PM2.5濃度,以及包括露點,溫度,氣壓,風向,風速和累積的下雪小時數的天氣信息。原始數據中的完整功能列表如下:

    • No : 行號

    • year,month,day,hour : 表示年,月,日,小時

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

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

    • TEMP : 溫度

    • PRES : 氣壓

    • cbwd :風向

    • Iws : 風速

    • ls : 累積的下雪小時數

    • lr : 累積的下小時數

    我們可以使用這些數據并構建一個預測問題,我們想通過前一個小時的天氣條件和pm2.5濃度,來預測下一個小時的pm2.5濃度。

    你們可以在這里下載空氣質量數據。

    下面我們查看一下數據

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

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

    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()

    接下來我們重新命名數據集的字段名,并刪除前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小時的數據
    4. df = df[24:]
    5. df.head()

    下面我們對除風向(wnd_dir)以外的7個變量進行可視化,我們要查看一下它們的時序圖

    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預測模型

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

    為LSTM模型準備數據

    這里將是本文的一個重點,目前的我們的數據集是一個時間序列數據集,它沒有標簽,接下來我們要做的就是將時間序列數據轉換成監督學習的數據,并且生成標簽。然后對輸入的變量進行標準化處理。 考慮到污染測量和前一時刻(t-1)的天氣條件,我們將監督學習問題設定為預測當前小時(t)的污染濃度。

    如何將時間序列數據轉換成監督學習的數據?這里我們定義了一個函數:series_to_supervised(), 它通過數據平移的方式將我們的目標變量前移一個時間單位,這樣就形成了數據的標簽,有了標簽它就變成了監督學習的數據,這樣我們就可以訓練lstm模型了。

    1. # 將序列轉換成監督式學習
    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. # 預測序列 (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. #對風向字段進行編碼
    3. encoder = LabelEncoder()
    4. values[:,4] = encoder.fit_transform(values[:,4])
    5. # 確保所有變量都是實數型
    6. values = values.astype('float32')
    7. #對數據進行標準化出來
    8. scaler = MinMaxScaler(feature_range=(0, 1))
    9. scaled = scaler.fit_transform(values)
    10. # 將時間序列數據轉換成監督學習數據
    11. reframed = series_to_supervised(scaled, 1, 1)
    12. # 刪除那些不需要預測的列
    13. reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True)
    14. reframed.head()

    從上面的輸出結果中我們看見var(t-1)至var8(t-1)為我們的前一小時的特征變量,var1(t)為當前時刻t的目標變量,var(t)是var(t-1)進行一次數據平移所產生的結果。這樣我們就可以利用t-1時刻的特征數據來預測t時刻污染濃度。

    到目前為止我們已經有了特征集和標簽,下面我們就可以為LSTM模型準備訓練集和測試集了。由于這是時間序列的數據,t時刻的污染濃度和t-1時刻的天氣條件是有密切關系的,所以在準訓練集和測試集時,我們不能對原始數據進行亂序操作。這里我們要按順序將第一年的數據作為訓練集,將后面四年的數據作為測試集。然后我們將訓練集和測試集轉化成3維數組的格式。

    1. # 將數據分割為訓練集和測試集
    2. values = reframed.values
    3. n_train_hours = 365 * 24
    4. train = values[:n_train_hours, :]
    5. test = values[n_train_hours:, :]
    6. # 分離出特征集與標簽
    7. train_X, train_y = train[:, :-1], train[:, -1]
    8. test_X, test_y = test[:, :-1], test[:, -1]
    9. # 轉換成3維數組 [樣本數, 時間步 ,特征數]
    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模型

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

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

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

    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. print(model.summary())

    訓練LSTM模型

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

    評估LSTM模型

    在模型訓練結束后,我們可以預測整個測試數據集。由于我們在訓練模型之前已經將所有的特征集和標簽進行了標準化處理即將數據值縮放到了0-1之間,因此我們的預測結果也是在0-1之間,為了對預測結果進行有效評估,我們必須將預測結果和標簽值全部轉換成沒有標準處理之前的實際值,這樣我們才能進行有效評估。

    通過將預測結果和測試集的標簽值進行逆向縮放,我們就得到了實際值,這樣我們可以計算模型的誤差分數。我們使用均方根誤差(RMSE)作為評估指標。

    1. # 對測試集進行預測
    2. yhat = model.predict(test_X)
    3. test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
    4. # 對預測值進行逆標準處理
    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. # 對測試集標簽進行逆標準化處理
    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. # 計算 RMSE
    14. rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
    15. print('Test RMSE: %.3f' % rmse)

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

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

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

    1. # 設置預測未來3小時的污染
    2. n_hours = 3
    3. n_features = 8
    4. # 將時間序列轉換成監督學習數據集
    5. reframed = series_to_supervised(scaled, n_hours, 1)

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

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

    1. # 分離訓練集和測試集
    2. values = reframed.values
    3. n_train_hours = 365 * 24
    4. train = values[:n_train_hours, :]
    5. test = values[n_train_hours:, :]
    6. # 分離特征集和標簽
    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)

    接下來我們要講訓練數據和測試數據轉換成3維數組格式,與之前的3維數組不一樣的是,此時我們三維數組的第二個維度將是3。

    1. # 轉換成3維數據格式 [樣本數, 時間步, 特征數]
    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))

    訓練模型

    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. # 訓練模型
    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. # 對測試集進行預測
    2. yhat = model.predict(test_X)
    3. test_X = test_X.reshape((test_X.shape[0], n_hours*n_features))
    4. # 對預測數據進行逆標準化
    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. # 對測試集標簽進行逆標準化
    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. # 計算均方根誤差
    14. rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
    15. print('Test RMSE: %.3f' % rmse)

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 军人妓女院BD高清片| 暖暖 在线 日本 免费 中文| 日本一区不卡高清更新二区| 国产一区二区在线影院| 波多野结衣AV一区二区全免费观看| 东方四虎av在线观看| 国产成人精品亚洲日本在线观看| 国产精品白丝喷水在线观看| 国产日产欧产美韩系列麻豆| 日韩精品一区二区亚洲AV| 野外做受三级视频| 日本边添边摸边做边爱的视频| 在线播放亚洲成人av| 无码精品人妻一区二区三区中 | 精品一卡2卡三卡4卡乱码精品视频| 少妇高清一区二区免费看| 亚洲综合精品第一页| 亚洲日本成本人观看| 国产成人精品视频不卡| 体验区试看120秒啪啪免费| 国产亚洲AV电影院之毛片| 国产 亚洲 制服 无码 中文 | 少妇粗大进出白浆嘿嘿视频| 亚洲一区二区观看播放| 国产重口老太和小伙| 女性高爱潮视频| 久久久噜噜噜久久| 国产亚洲精品AA片在线播放天| 亚洲国产成人精品无码区蜜柚| 精品国产品香蕉在线| 国产一区二区不卡自拍| 国产精品自在线拍国产电影| 综合色一色综合久久网| 久久精品无码免费不卡| 亚洲VA成无码人在线观看天堂| 人人澡人摸人人添| 国产成人精品无码播放| 看全色黄大色大片免费久久| XXXXXHD亚洲日本HD| 免费国产一区二区不卡| 亚洲AV无码专区国产乱码电影|