RNN时间序列预测空气质量

关于RNN可以参考这篇文章博文地址

背景

时间序列是一个比较场景的问题,

获取数据

从UIC下载学习库下载地址下载其中的csv文件

图片.png

其各个数据特征如下
RNN时间序列预测空气质量_第1张图片
图片.png

处理数据

先导入需要用到的模块

这里用到了keras的API关于keras的使用可以看官方教程点击前往

from tensorflow import keras
from tensorflow.keras import layers
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

导入数据

data = pd.read_csv('D:\machine\project/testbeijinpm2.5/PRSA_data_2010.1.1-2014.12.31.csv')

查看下列信息看是否导入成功

data.columns
图片.png

查看数据情况可以用data.head在jupyter会显示前5行

data.head()
RNN时间序列预测空气质量_第2张图片
图片.png

pm2.5就是我们需要的label通过下面操作查看是否有空的数据

data['pm2.5'].isna().sum()

可以看到有2067行数据包含空的pm2.5

图片.png

对于这些空的数据,如果采取删除的动作,那样会导致数据不连续,可能对于训练的结果产生影响,这里采用的处理方式是讲空值处理成它最近的点的值,这样可以保证数据的连续性和前后关联性,有不至于有太大误差
运行如下操作处理

data=data.iloc[24:].fillna(method='ffill')

可以观察到时间的年月日小时分布在不同列
它们应该分布在同一列属于同一个特征
这里导入python的时间模块进行处理

import datetime

将数据 中的year,month,day,hour整合成一条数据赋值给data['time']

#时间组合
data['time']=data.apply(lambda  x: datetime.datetime(year=x['year'],
                                        month=x['month'],
                                        day=x['day'],
                                        hour=x['hour']),
           axis=1
           )

删除原本的year,month,day,no列

data.drop(columns=['year','month','day','hour','No'],inplace=True) 

查看下数据的情况


RNN时间序列预测空气质量_第3张图片
图片.png

设置成按照时间索引

#设置成按时间索引
data=data.set_index('time')

从数据中可以看到cbwd不是一些数值标量,这需要对它进行转换,先查看cbwd有哪些内容

#找到cbwd有哪些内容
data.cbwd.unique()
图片.png

将这几个标识编码

#把风向编码化
data=data.join(pd.get_dummies(data.cbwd))

编码化完成后删除cbwd列

del data['cbwd']

查看下表格,可以看到4个标识已经编码化了

data.tail()
RNN时间序列预测空气质量_第4张图片
图片.png

可以下面代码查看最后1000次pm2.5变化情况

data['pm2.5'][-1000:].plot()
RNN时间序列预测空气质量_第5张图片
图片.png

最后1000次温度变化情况

data['TEMP'][-1000:].plot()
RNN时间序列预测空气质量_第6张图片
图片.png

可以通过查看列数查看特征数量

#特征数量
len(data.columns)
图片.png

时间序列预测是观测过去多久的值,来预测未来多久的值,因此这里定义两个变量seq_length代表过去5×24小时的数据,来预测未来24小时的数据。

seq_length = 5*24
delay = 24

然后我们就可以采用数据,以seq_length和delay来采样

#采样的数据
data_ = []
for t in range(len(data) - seq_length - delay):
    data_.append(data.iloc[t:t + seq_length + delay ])

查看下采样后的数据形状

data_[0].shape

可以看到144个样例,11个特征


图片.png

将采样的数据转换成np的array

data_ = np.array([df.values for df in data_])
data_.shape
图片.png

洗牌数据

np.random.shuffle(data_)

特征切片

#特征切片
x = data_[:, :5*24, :]
# label
y = data_[:,-1, 0]

查看下x,y的数据形状

x.shape
y.shape
RNN时间序列预测空气质量_第7张图片
图片.png

划分80%数据用于训练集 20%用于测试集合

split_b = data_.shape[0]*0.8
split_b = int(split_b)
train_x = x[ :split_b]
train_y = y[ :split_b]
test_x = x[split_b: ]
test_y = y[split_b: ]

数据归一化,让不同特征规范统一范围,有效利用神经网络的训练避免引起误差。

#计算均值
#数据归一化,
mean = test_x.mean(axis = 0)
std = train_x.std(axis = 0)
train_x = (train_x - mean)/std
test_x = (test_x - mean) / std

搭建神经网络

全链接神经网络方式

batch_size = 128 #每次训练128个数据
model = keras.Sequential()
model.add(layers.Flatten(input_shape=(train_x.shape[1:])))
model.add(layers.Dense(32,activation='relu'))
model.add(layers.Dense(1))
model.compile(
    optimizer='adam',  #优化算法 
    loss = 'mse',   #均方差 
    metrics= ['mae'] #平均绝对误差
)

history = model.fit(train_x, train_y,
                   batch_size =batch_size,
                   epochs = 50,
                   validation_data=(test_x,test_y)
                   )
RNN时间序列预测空气质量_第8张图片
图片.png
#画图看情况
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(history.epoch,history.history['mean_absolute_error'],c='r') #训练数据
plt.plot(history.epoch,history.history['val_mean_absolute_error'],c='g') #测试数据
RNN时间序列预测空气质量_第9张图片
图片.png

LSTM方式

在训练过程中可以看到速度明显要比全连接的方式要好慢上许多,而训练的效果也比全链接网络的要要很多。

train_x.shape  #第一维度大小,第二维度观测次数,第三维度每次观测的特征

这只有一层的LSTM

model = keras.Sequential()
model.add(layers.LSTM(32,input_shape=(120,11)))
model.add(layers.Dense(1))

编译选择模型的优化方式

model.compile(
    optimizer='adam',  #优化算法 
    loss = 'mse',   #均方差 
    metrics= ['mae'] #平均绝对误差
)
RNN时间序列预测空气质量_第10张图片
图片.png
history = model.fit(train_x, train_y,
                   batch_size =batch_size,
                   epochs = 200,
                   validation_data=(test_x,test_y)
                   )
plt.plot(history.epoch,history.history.get('mean_absolute_error'),'y',label='Training loss')
plt.plot(history.epoch,history.history.get('val_mean_absolute_error'),'b',label= 'Test loss')
plt.legend()

LSTM层优化

添加多层优化拟合能力,需要添加
return_sequences,最后一层不需要
可以观察到训练速度更加缓慢,但训练效果却是跨越式的进展。

model = keras.Sequential()
model.add(layers.LSTM(32,input_shape=(120,11),return_sequences=True))
model.add(layers.LSTM(32,return_sequences=True))
model.add(layers.LSTM(32,return_sequences=True))
model.add(layers.LSTM(32))
model.add(layers.Dense(1))

#在训练过程中降低学习速率,加快训练速度同时增加训练的效果
#连续的3个val_LOSS没有降低则降低学习速率0.3,最小的学习速率为0.000001
lr_reduce = keras.callbacks.ReduceLROnPlateau('val_loss',patience=3,factor=0.3,min_lr=0.00001)

model.compile(
    optimizer='adam',  #优化算法 
    loss = 'mse',   #均方差 
    metrics= ['mae'] #平均绝对误差
)

history = model.fit(train_x, train_y,
                   batch_size =batch_size,
                   epochs = 200,
                    callbacks = [lr_reduce],
                   validation_data=(test_x,test_y)
                   )

plt.plot(history.epoch,history.history.get('mean_absolute_error'),'y',label='Training loss')
plt.plot(history.epoch,history.history.get('val_mean_absolute_error'),'b',label= 'Test loss')
plt.legend()

可以很明显的看到效果的提升


RNN时间序列预测空气质量_第11张图片
图片.png

RNN时间序列预测空气质量_第12张图片
图片.png

你可能感兴趣的:(RNN时间序列预测空气质量)