交通流预测爬坑记(二):最简单的LSTM预测交通流,使用tensorflow2实现

本文介绍了如何使用tensorflow2.0构建一个简单的LSTM模型预测交通流。作者强调tensorflow2.0的易用性,并分享了处理时间序列数据的难点,如按时间步长(time_step=5)划分数据。文中提供了数据来源,提到了数据预处理步骤,包括删除无关列和数据归一化。最后,概述了模型构建、训练、预测和评估的基本流程。
摘要由CSDN通过智能技术生成

说到时间序列预测,我想一定首先想到RNN,然后想到LSTM,LSTM原理就不说了,网上有很多相关文章。

下面使用tensorflow2.0来实现预测

不得不说tensorflow2.0 太香了,太简单了,真的是有手就行

在tensorflow中只需要调用已经tensorflow的LSTM模块就行了,比如下面的代码

from tensorflow.keras.layers import Dense,LSTM,Dropout

model = tf.keras.Sequential([
    LSTM(80, return_sequences=True),
    Dropout(0.2),
    LSTM(80),
    Dropout(0.2),
    Dense(1)
])
model.compile(optimizer='adam',
             loss='mse',)

这样就创建了一个2层LSTM,每层80个神经元的;同时添加了Droopout函数防止过拟合;使用adam激活函数;使用mse作为损失误差的神经网络。真的炒鸡简单。
主要问题是数据的处理,要做时间序列预测,原理应该是使用前n个时间去预测下一个时间,也就是所模型训练的数据应该是下面这个图这样的数据在这里插入图片描述
所以处理数据才是困难的地方。

下面我使用的数据是在上一个文章中提到的英国站点数据。其他的数据也是大同小异。

百度网盘: https://pan.baidu.com/s/19vKN2eZZPbOg36YEWts4aQ
密码 4uh7

在导入数据时,不知道为什么如果有标红的这一列,就会提示错误,所以我把这个数据直接删了,这列数据对预测也没有影响
在这里插入图片描述
然后通过下面代码就可以得到一个包含,日期、流量的的数据

f = pd.read_csv('..\Desktop\AE86.csv')
# 从新设置列标
def set_columns():
    columns = []
    for i in f.loc[2]:
        columns.append(i.strip())
    return columns
f.columns = set_columns()
f.drop([0,1,2], inplace = True)

# data 包含要操作的列
data = pd.DataFrame()
# 想留下哪一行数据,就在这里添加到data中
data['datetime'] = f['Local Date']+' '+f['Local Time']
data['total_flow'] = f['Total Carriageway Flow']
# data['speed'] = f['Speed Value']  速度本文没用到
data['datetime'] = pd.to_datetime(data['datetime'])

data['month'] = data['datetime'].apply(lambda date: date.month)
data['day'] = data['datetime'].apply(lambda date: date.day)
data['hour'] = data['datetime'].apply(lambda date:date.hour)
data['minute'] = data['datetime'].apply(lambda date: date.minute)

# 数据转格式
data['total_flow'] = np.array(data['total_flow']).astype(np.float64)

处理后的数据如下
在这里插入图片描述
之后就是划分训练集和测试集,归一化

# 一月第25天第一个时间的索引值
d25 = data.query('day==25').index[0]
# 训练集  2211个数据,2018年一月前三周
train_set = data.iloc[:d25,1:2]
# 检测集  669个数据,2018年最后一周
test_set = data.iloc[d25:,1:2]

# 归一化
sc = MinMaxScaler(feature_range=(0, 1))
train_set_sc = sc.fit_transform(train_set)
test_set_sc = sc.transform(test_set)
下面就是创建LSTM的输入数据,以time_step=5为预测间隔,即使用前5个时间段,预测下一个时间段
time_step = 5
# 按照time_step划分时间步长
x_train = []
y_train = []
x_test = []
y_test = []
for i in range(time_step, len(train_set_sc)):  
    x_train.append(train_set_sc[i - time_step:i])
    y_train.append(train_set_sc[i:i + 1])
for i in range(time_step, len(test_set_sc)):  
    x_test.append(test_set_sc[i - time_step:i])
    y_test.append(test_set_sc[i:i + 1])
x_test, y_test = np.array(x_test), np.array(y_test)

# 随机化,这部分可以不要
np.random.seed(7)
np.random.shuffle(x_train)
np.random.seed(7)
np.random.shuffle(y_train)
tf.random.set_seed(7)

# 转为array格式
x_train, y_train = np.array(x_train), np.array(y_train)
x_test, y_test = np.array(x_test), np.array(y_test)
x_train = np.reshape(x_train, (x_train.shape[0], time_step, 1))
x_test = np.reshape(x_test, (x_test.shape[0], time_step, 1))
下面就是构建模型,预测,误差分析,可视化之类的了

总体代码如下

import tensorflow as tf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.layers import Dense,LSTM,Dropout,Flatten
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
import math
from matplotlib.font_manager import FontProperties  # 画图时可以使用中文
f = pd.read_csv('..\Desktop\AE86.csv')
# 从新设置列标
def set_columns():
    columns = []
    for i in f.loc[2]:
        columns.append(i.strip())
    return columns
f.columns = set_columns()
f.drop([0,1,2], inplace = True)

# data 包含要操作的列
data = pd.DataFrame()
data['datetime'] = f['Local Date']+' '+f['Local Time']
data['total_flow'] = f['Total Carriageway Flow']
# data['speed'] = f['Speed Value']
data['datetime'] = pd.to_datetime(data['datetime'])

data['month'] = data['datetime'].apply(lambda date: date.month)
data['day'] = data['datetime'].apply(lambda date: date.day)
data['hour'] = data['datetime'].apply(lambda date:date.hour)
data['minute'] = data['datetime'].apply(lambda date: date.minute)

# 数据转格式
data['total_flow'] = np.array(data['total_flow']).astype(np.float64)
# 一月第25天第一个时间的索引值
d25 = data.query('day==25').index[0]
# 训练集  2211个数据,2018年一月前三周
train_set = data.iloc[:d25,1:2]
# 检测集  669个数据,2018年最后一周
test_set = data.iloc[d25:,1:2]
# 归一化
sc = MinMaxScaler(feature_range=(0, 1))
train_set_sc = sc.fit_transform(train_set)
test_set_sc = sc.transform(test_set)

# 按照time_step划分时间步长
time_step = 5
x_train = []
y_train = []
x_test = []
y_test = []
for i in range(time_step, len(train_set_sc)):  
    x_train.append(train_set_sc[i - time_step:i])
    y_train.append(train_set_sc[i:i + 1])
for i in range(time_step, len(test_set_sc)):  
    x_test.append(test_set_sc[i - time_step:i])
    y_test.append(test_set_sc[i:i + 1])
x_test, y_test = np.array(x_test), np.array(y_test)

# 随机化,这部分可以不要
np.random.seed(7)
np.random.shuffle(x_train)
np.random.seed(7)
np.random.shuffle(y_train)
tf.random.set_seed(7)

# 转为array格式
x_train, y_train = np.array(x_train), np.array(y_train)
x_test, y_test = np.array(x_test), np.array(y_test)
x_train = np.reshape(x_train, (x_train.shape[0], time_step, 1))
x_test = np.reshape(x_test, (x_test.shape[0], time_step, 1))

# LSTM模型
model = tf.keras.Sequential([
    LSTM(80, return_sequences=True),
    Dropout(0.2),
    LSTM(80),
    Dropout(0.2),
    Dense(1)
])
model.compile(optimizer='adam',
             loss='mse',)


# 训练模型, 其中epochs,batch_size 可以自己更改
history = model.fit(x_train, y_train,
               epochs=5,
               validation_data=(x_test, y_test))
# 模型预测
pre_flow = model.predict(x_test)
# 反归一化
pre_flow = sc.inverse_transform(pre_flow)
real_flow = sc.inverse_transform(y_test.reshape(y_test.shape[0], 1))

# 计算误差
mse = mean_squared_error(pre_flow, real_flow)
rmse = math.sqrt(mean_squared_error(pre_flow, real_flow))
mae = mean_absolute_error(pre_flow, real_flow)
print('均方误差---', mse)
print('均方根误差---', rmse)
print('平均绝对误差--', mae)

# 画出预测结果图
font_set = FontProperties(fname=r"C:\Windows\Fonts\simsun.ttc", size=15)    # 中文字体使用宋体,15号
plt.figure(figsize=(15,10))
plt.plot(real_flow, label='Real_Flow', color='r', )
plt.plot(pre_flow, label='Pre_Flow')
plt.xlabel('测试序列', fontproperties=font_set)
plt.ylabel('交通流量/辆', fontproperties=font_set)
plt.legend() 
# 预测储存图片
# plt.savefig('...\Desktop\123.jpg')
上面代码是最简单的,只是用流量,同时单一节点进行流量预测。

也可以使用速度,占有率等信息,加入到模型中对流量进行预测。真要认真做起来是比较难的,但是如果只是应付应付,提供一个思虑:

可以把另外几种特征也按照time_step=5,进行划分,直接传入到模型中,只不过在模型的最后一层加一个Flatten层(将所有数据拉直成一维),这样就可以大大方方的说”本文考虑了,流量、速度、车道占有率等多种因数,相对于以前文章具有重大改进“

  • 25
    点赞
  • 169
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值