時間序列數據生成器(TimeseriesGenerator)

在使用RNN及其變體時,大多數是為了解決時間問題,即數據是有時序性質的。而且,RNN要求輸入的數據是3D張量,即(samples, time_steps, features),中間的這個time_steps就體現了時間。為了將數據轉換成(m, n, k)這種格式,可以手動進行操作,比如前面的一篇文章 http://www.itdecent.cn/p/6b874e49b906。當然,也可以考慮使用今天的主角:TimeseriesGenerator

介紹

TimeseriesGenerator是Keras為方便用戶處理時序數據而制作的一個生成器,使用起來也很簡單。

class TimeseriesGenerator(data, targets, length, sampling_rate=1, stride=1, start_index=0, end_index=None, shuffle=False, reverse=False, batch_size=128)

generator = TimeseriesGenerator(data, targets, time_steps)

在這里,常用的參數主要有:
data:要轉換的原始的時間序列數據
targets:目標值
length:以多大步長來轉換數據
定義好一個生成器并將數據導入之后,可以通過以下方式進行查看轉換后的數據:

for i in range(len(generator)):
    x, y = generator[i]
    print('%s => %s' % (x, y))

應用

在平常的案例中,主要有兩類數據。
第一類是數據x與要預測的值y是同一種性質的值,比如溫度。而另一類中,輸出y與輸入x是不同類的,比如[下雨, 薄衣, 出汗] -> [感冒]。

案例1:預測余弦值

這一類數據很多都是單變量,即特征數只有1,比如溫度、價格等。

import numpy as np
import matplotlib.pyplot as plt
from keras.preprocessing.sequence import TimeseriesGenerator
from keras.models import Sequential
from keras.layers import Dense, LSTM

# 生成數據
x_len = 1075
x = np.linspace(0, np.pi * 10.75, x_len, endpoint=False)
y = np.cos(x).reshape(-1, 1)
print("顯示生成的余弦數據:")
plt.scatter(x, y)
plt.show()

window = 75  # 時序滑窗大小,就是time_steps
batch_size = 256
tg = TimeseriesGenerator(y, y, length=window, batch_size=batch_size)

# 構建LSTM模型
model = Sequential()
model.add(LSTM(
    units=50, input_shape=(window, 1), return_sequences=True # True返回輸出序列的全部
))
model.add(LSTM(
    units=100, return_sequences=False # False返回輸出序列的最后一個
))
model.add(Dense(1)) # 輸出層
model.compile(optimizer='adam', loss='mse')  # 均方誤差(Mean Square Error)
model.fit_generator(generator=tg, epochs=30, verbose=2)

# 預測
pred_len = 200  # 預測序列長度
for i in range(4):
    x_pred = x[i * batch_size + window: i * batch_size + window + pred_len]
    y_pred = []  # 存放擬合序列
    X_pred = tg[i][0][0]
    for i in range(pred_len):
        Y_pred = model.predict(X_pred.reshape(-1, window, 1))  # 預測
        y_pred.append(Y_pred[0])
        X_pred = np.concatenate((X_pred, Y_pred))[1:]  # 窗口滑動
    plt.scatter(x_pred[0], y_pred[0], c='r', s=9)  # 預測起始點
    plt.plot(x_pred, y_pred, 'r')  # 預測序列
plt.plot(x, y, 'y', linewidth=5, alpha=0.3)  # 原序列
plt.show()

案例2:預測兩數之和

此類案例,數據x與預測值y之間存在某種聯系, 但不是同類性質的數據。

from numpy import array
from numpy import hstack
from numpy import insert
from keras.preprocessing.sequence import TimeseriesGenerator
# 給定數據
in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95, 105])
out_seq = array([25, 45, 65, 85, 105, 125, 145, 165, 185, 205])
in_seq1 = in_seq1.reshape((len(in_seq1), 1))
in_seq2 = in_seq2.reshape((len(in_seq2), 1))
out_seq = out_seq.reshape((len(out_seq), 1))
# 按行的方向進行堆疊
dataset = hstack((in_seq1, in_seq2))
# 插入一個值作為初始值
out_seq = insert(out_seq, 0, 0)
# 定義生成器
n_input = 1
generator = TimeseriesGenerator(dataset, out_seq, length=n_input, batch_size=1)
# print each sample
for i in range(len(generator)):
    x, y = generator[i]
    print('%s => %s' % (x, y))

需要注意的是,在這里多了一個out_seq = insert(out_seq, 0, 0)。這主要是因為,若沒有0,0,則數據會默認將25作為第一個值,然而 預測是從第二個值開始的,這樣自然就稱為了 [10, 15] -> [45]。因此,加入一個[0]將25頂上去。

最后,數據處理真的挺不好玩的,哎,希望能多學一些,提前多踩一些。加油~

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 《Lose Yourself》 Look' if you had one shot' one opportunit...
    飛魚xi閱讀 1,059評論 0 1
  • 第四章 公司里的三人幫 今天像往常一樣,我在艱難的工作著,不要覺得我這句艱難,沒什么分量,這種艱難對于我來說是空前...
    陌上扶桑閱讀 427評論 0 0
  • 身高160cm,骨架小小的我穿衣一不留神就會成為學生,怎樣穿得有女人味一些又得體大方應該是每個小不點女生想...
    那些花骨朵兒閱讀 288評論 0 0

友情鏈接更多精彩內容