基於Keras用LSTM進行時間序列預測(二)

Kesci: Keras 實現 LSTM——時間序列預測

    博主之前參與的一個科研項目是用 LSTM 結合 Attention 機制依據作物生長期內氣象環境因素預測作物產量。本篇博客將介紹如何用 keras 深度學習的框架搭建 LSTM 模型對時間序列做預測。所用項目和數據集來自:真實業界數據的時間序列預測挑戰

1 項目簡單介紹

1.1 背景介紹

 

本項目的目標是建立內部與外部特徵結合的多時序協同預測系統。數據集採用來自業界多組相關時間序列(約40組)與外部特徵時間序列(約5組)。課題通過進行數據探索,特徵工程,傳統時序模型探索,機器學習模型探索,深度學習模型探索(RNN,LSTM等),算法結合,結果分析等步驟來學習時序預測問題的分析方法與實戰流程。

1.2 數據集說明

 

** 訓練數據有8列:**

- 日期 - 年: int
- 日期 - 月: int
- 日期 - 日: int, 時間跨度爲2015年2月1日 - 2016年8月31日
- 當日最高氣溫 - 攝氏度(下同): float
- 當日最低氣溫: float
- 當日平均氣溫: float
- 當日平均溼度: float
- 輸出 - float
預測數據沒有輸出部分,其他與預測一樣。時間跨度爲2016年9月1日 - 2016年11月30日
訓練與預測都各自包含46組數據,每組數據代表不同數據源,組之間的溫度與溼度信息一樣而輸出不同.

2 導入庫並讀取查看數據

#查看其中一個地區的訓練數據
import pandas as pd
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, LSTM, Dropout
import matplotlib.pyplot as plt
% matplotlib inline
import glob, os
import seaborn as sns
import sys
from sklearn.preprocessing import MinMaxScaler
columns = ['YEAR','MONTH','DAY','TEMP_HIG','TEMP_COL','AVG_TEMP','AVG_WET','DATA_COL']
data = pd.read_csv('../input/industry/industry_timeseries/timeseries_train_data/1.csv', 
                      names=columns)
data.head()

# 查看數據採集區1的數據
plt.figure(figsize=(24,8))
for i in range(8):
    plt.subplot(8, 1, i+1)
    plt.plot(data.values[:, i])
    plt.title(columns[i], y=0.5, loc='right')
plt.show() 

3 數據預處理

3.1 時間序列數據轉化爲監督問題數據

def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    n_vars = 1 if type(data) is list else data.shape[1]
    df = pd.DataFrame(data)
    cols, names = list(), list()
    # input sequence (t-n, ... t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    # forecast sequence (t, t+1, ... t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
        else:
            names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    # put it all together
    agg = pd.concat(cols, axis=1)
    agg.columns = names
    # drop rows with NaN values
    if dropnan:
        agg.dropna(inplace=True)
    return agg

關於上段代碼的理解可以參考:How to Convert a Time Series to a Supervised Learning Problem in Python

 

# 將數據歸一化到0-1之間,無量綱化
scaler = MinMaxScaler(feature_range=(0,1))
scaled_data = scaler.fit_transform(example[['DATA_COL','TEMP_HIG','TEMP_COL','AVG_TEMP','AVG_WET']].values)
# 將時序數據轉換爲監督問題數據
reframed = series_to_supervised(scaled_data, 1, 1)
#刪除無用的label數據
reframed.drop(reframed.columns[[6,7,8,9]], axis=1, inplace=True)
print(redf.info())
redf.head()

3.2 數據集劃分及規整

# 數據集劃分,選取前400天的數據作爲訓練集,中間150天作爲驗證集,其餘的作爲測試集
train_days = 400
valid_days = 150
values = redf.values
train = values[:train_days, :]
valid = values[train_days:train_days+valid_days, :]
test = values[train_days+valid_days:, :]
train_X, train_y = train[:, :-1], train[:, -1]
valid_X, valid_y = valid[:, :-1], valid[:, -1]
test_X, test_y = test[:, :-1], test[:, -1]

# 將數據集重構爲符合LSTM要求的數據格式,即 [樣本,時間步,特徵]
train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
valid_X = valid_X.reshape((valid_X.shape[0], 1, valid_X.shape[1]))
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
print(train_X.shape, train_y.shape, valid_X.shape, valid_y.shape, test_X.shape, test_y.shape)
(400, 1, 5) (400,) (150, 1, 5) (150,) (27, 1, 5) (27,)

4 建立模型並訓練

model1 = Sequential()
model1.add(LSTM(50, activation='relu',input_shape=(train_X.shape[1], train_X.shape[2]), return_sequences=True))
model1.add(Dense(1, activation='linear'))
model1.compile(loss='mean_squared_error', optimizer='adam') 
# fit network
LSTM = model.fit(train_X, train_y, epochs=100, batch_size=32, validation_data=(valid_X, valid_y), verbose=2, shuffle=False)
# plot history
plt.plot(LSTM.LSTM['loss'], label='train')
plt.plot(LSTM.LSTM['val_loss'], label='valid')
plt.legend()
plt.show()

5 模型預測並可視化

plt.figure(figsize=(24,8))
train_predict = model.predict(train_X)
valid_predict = model.predict(valid_X)
test_predict = model.predict(test_X)
plt.plot(values[:, -1], c='b')
plt.plot([x for x in train_predict], c='g')
plt.plot([None for _ in train_predict] + [x for x in valid_predict], c='y')
plt.plot([None for _ in train_predict] + [None for _ in valid_predict] + [x for x in test_predict], c='r')
plt.show()

藍色曲線爲真實輸出

綠色曲線爲訓練數據的預測輸出

黃色曲線爲驗證數據集的預測輸出

紅色曲線爲測試數據的預測輸出(能看出來模型預測效果還是比較好的)

6 小結

    本次只採用了一個地區的數據用來訓練模型,在後續的工作中可以增加多任務學習內容。

 

文章來源: https://www.cnblogs.com/mtcnn/p/9411597.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章