RNN时间序列预测空气质量

作者: 泛酸的桂花酒 | 来源:发表于2019-05-06 17:42 被阅读1次

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

背景

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

获取数据

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

图片.png
其各个数据特征如下
图片.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()
图片.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) 

查看下数据的情况


图片.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()
图片.png

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

data['pm2.5'][-1000:].plot()
图片.png

最后1000次温度变化情况

data['TEMP'][-1000:].plot()
图片.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
图片.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)
                   )
图片.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') #测试数据
图片.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'] #平均绝对误差
)
图片.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()

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


图片.png
图片.png

相关文章

  • RNN时间序列预测空气质量

    关于RNN可以参考这篇文章博文地址 背景 时间序列是一个比较场景的问题, 获取数据 从UIC下载学习库下载地址下载...

  • 时间序列预测——DA-RNN模型

    时间序列预测——DA-RNN模型 作者:梅昊铭 1. 背景介绍 传统的用于时间序列预测的非线性自回归模型(NRAX...

  • RNN

    RNN RNN 是一种利用神经网络对序列模型的通用模型 利用历史信息结合当前输入进行预测 适合解决时间序列输入输出...

  • 学习笔记TF021:预测编码、字符级语言建模、ArXiv摘要

    预测编码(predictive coding),向RNN输入大量序列,训练预测序列下一帧能力。语言建模(langu...

  • 基于EMD分解与LSTM的空气质量预测

    作为RNN的一种变体,LSTM广泛用于时间序列的预测。本文结合EMD(empirical mode decompo...

  • 23.RNN模型: 时间序列预测

    问题描述基于历史的20个通道,预测3个通道未来的值。 流程1.时间序列数据预处理:利用pandas.dataFra...

  • CRNN算法详解

    1. CRNN算法结构 文字识别是对序列的预测方法,所以采用了对序列预测的RNN网络。通过CNN将图片的特征提取出...

  • PyTorch RNN Regression

     循环神经网络RNN及时预测时间序列. 更多可以查看官网 :* PyTorch 官网 载入数据 假设想要用 sin...

  • 时间序列预测法及Spark-TimeSerial实现

    时间序列预测法及Spark-Timeserial 时间序列预测法 时间序列预测法(Time Series Fore...

  • 11.21 interview

    如何评价facebook开源的prophet时间序列预测工具? 时间序列分析 时间序列预测之--ARIMA模型 通...

网友评论

    本文标题:RNN时间序列预测空气质量

    本文链接:https://www.haomeiwen.com/subject/vrploqtx.html