owned this note
owned this note
Published
Linked with GitHub
# 時間序列預測
# 1.問題描述
使用任意一種RNN(SimpleRNN,GRU,LSTM),根據提供的1000筆時間序列數據,預測出1001~1500筆數據。
提供的數據集:
A3_train.txt,其中有1000行,每一行為一個float類型的數值,該txt文件部分內容如下:
![數據集樣例](https://i.imgur.com/2mhTHYe.png)
# 2.數據預處理
## ①讀取文件,將文件的1000條數據轉化為形狀是(1000,)的array
```python=
# 读取文件,将1000条数据构造成一个形状为(1000,)的array
import os
import numpy as np
from matplotlib import pyplot as plt
data_dir = r"C:\Users\NOTEBOOK\DeepLearningNote\train_data.txt"
f = open(data_dir)
content = f.read()
f.close()
samples = [float(i) for i in content.split("\n")]
samples = np.array(samples)
plt.plot(range(len(samples)),samples)
```
將1000條數據展示出來
![1000條數據以坐標的形式展示出來](https://i.imgur.com/ueANnNz.png)
## ②定義一個用來產生train_data和train_labels的函數
該函數可以產生(900,100)狀的array,作為train_data,產生(900,)狀的array,作為train_labels
```python=
#定义split_sequence函数,返回值X含有n_steps个之前的值,y是下一时刻的值
def split_sequence(sequence, n_steps):
X, y = list(), list()
for i in range(len(sequence)):
end_ix = i + n_steps
if end_ix > len(sequence)-1:
break
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
X.append(seq_x)
y.append(seq_y)
return np.array(X), np.array(y)
```
## ③通過split_sequence函數,得到所有的data和labels,並將train_data變形為LSTM可處理的形式
```python=
data,labels = split_sequence(samples,100)
data = data.reshape((len(data),100,1))
```
# 3.建立模型
模型由三層LSTM層和一個Dense層組成
```python=
#建立模型
from keras.models import Sequential
from keras.layers import GRU,LSTM,Dropout,Dense
model = Sequential()
model.add(LSTM(20,activation="relu",input_shape=(100,1),return_sequences=True))
model.add(LSTM(30,activation="relu",return_sequences=True))
model.add(LSTM(30,activation="relu"))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')
model.summary()
```
# 4.訓練模型
將1000筆數據中的20%作為驗證數據
```python=
history = model.fit(data,labels,epochs=20,batch_size=20,validation_split=0.2)
```
由於初始的權重是隨機的,最好的一次訓練過程如下
![](https://i.imgur.com/iZg8S4J.png)
打印其訓練過程的loss和val_loss
```python=
loss = history.history['loss']
val_loss = history.history['val_loss']
plt.plot(range(20),loss,"bo",label="loss")
plt.plot(range(20),val_loss,"b",label='val_loss')
plt.legend()
plt.show()
```
![](https://i.imgur.com/tR9MJAI.png)
# 5.預測
## ①定義預測函數
此函數用來得到1001~1500這500筆預測結果
此函數首先利用901~1000這100筆數據得到第1001筆預測結果,然後將1001筆預測結果存入到results中,將902~1001這100筆數據加入原始數據中,下一輪預測將以此為輸入,得到第1002筆預測結果,依次進行下去,直到運行500次,也就是得到第1500筆預測結果
```python=
#定义方法,可以预测从1001到1500的结果
def predict1001_1500(samples):
results = []
for i in range(500):
# print(samples[-1].shape)
result = model.predict(samples[-1].reshape(1,100,1))
results.append(result)
sample = np.append(samples[-1][1:],result)
sample = sample.reshape((1,100,1))
# print(sample.shape)
samples = np.concatenate((samples,sample),axis=0)
return results
```
## ②得到1001~1500這500筆預測結果
```python=
results = predict1001_1500(data)
```
將這1500筆預測結果打印出來
```python=
plt.plot(range(1000),samples)
plt.plot(range(1000,1500),np.array(results).reshape(500,))
```
![](https://i.imgur.com/fpIyNcr.png)
單獨打印500筆預測結果
```python=
plt.plot(range(500),np.array(results).reshape(500,))
```
![](https://i.imgur.com/R9gRZDD.png)