在深度学习火之前,学术界更多是采用机器学习的方法,而其中支持向量机就是最热门一个方法,这篇文档基于支持向量回归和LSTM两种模型进行短时交通流预测。
本文所采用的数据是2016年10月长沙市芙蓉路/人民路北向南方向的交通流数据,数据采用5min内通过数据采集点的车辆数的统计值,10月15日和16日共576个数据点,其中15日为星期六,16日为星期天,两天都为周末,所以两天在时间上应该有同样的分布。
本文以10月15日288个数据点作为训练样本集,10月16日的288个作为测试集。参考前人的研究,文中将当前t时间的流量和前4个时间段共5个点的流量作为输入值,以t+1时刻的流量为输出,所以网络输入和输出的属性个数分别为5,1(个数可根据实际情况定)。于是训练集输入为283*5,输出为283*1,283为样本个数;测试集是一样。
LSTM做预测的时候,输入数据通常都是要归一化处理的,原因:1、避免不同数量级的特征对网络鲁棒性的影响;2、支持向量机好像是建立在数据集是正态分布的前提下的,所以,如果数据集不满足正态分布,对结果有很大影响。本文中采用了两种方案进行数据预处理。
1)Min-Max scaling
大多数机器学习算法中,会选择Standardization来进行特征缩放,但是,Min-Max Scaling也并非会被弃置一地。在数字图像处理中,像素强度通常就会被量化到[0,1]区间,在一般的神经网络算法中,也会要求特征被量化[0,1]区间。公式如下:
2)Standardization
量化后的特征将服从标准正态分布,因为很多算法的假设都是建立在数据集是正态分布的基础上的,如支持向量机,其具体公式如下:
其中,u和delta分别为对应特征的均值和标准差。这样数据的均值为0,标准差为1。
本文采用ε-支持向量回归,采用rbf核函数,C为0.8,gamma为0.2,epsilon为0.1。
LSTM模型输入特征数为5,输出特征数为7,网络层数为2,所以整个网络为5-7-7,然后在LSTM模型后加一个全连接层,全连接的输入为7,输出为1。
因为训练的样本数比较少,所以设计的LSTM的模型也比较简单。
本文采用均方根误差(Root Mean Square Error)是观测值与真值偏差的平方和与观测次数m比值的平方根,是用来衡量观测值同真值之间的偏差。计算公式为:
1)支持向量机
(a) 真实值与预测值
(b) 误差
3)LSTM-layer=2
(c) 真实值与预测值
(d) 误差
3)LSTM-layer=6
(e) 真实值与预测值
(f) 误差
红色为真实值,黑色为预测值,绿色为误差。
上图中(c)、(d)为LSTM中层数为2层的结果,(e)、(f)为层数为6层的结果。可以发现LSTM整体更平滑,把握一种整体趋势,而且随着参数和网络层数的增加,网络的输出越平滑。(不知道增加训练样本集的数据量是不是会不一样)。对,不同的网络模型计算的评价指标如下表所示。
方法/数据集
均方根误差
SVR/Min-Max-scaling
23.46
SVR/Standardization
21.53
LSTM-layer=2/Standardization
21.01
LSTM-layer=6/Standardization
24.19
参考文献:
[1] 基于深度学习的短时交通流预测研究_王祥雪
[2] 基于支持向量机回归的短时交通流预测模型_傅贵
部分程序:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Author : Yibao2hao """ 可代写程序,有问题可加qq:778961303. """ # 导入相关模块 import numpy as np import pandas as pd from sklearn.svm import SVR import matplotlib.pyplot as plt from pylab import mpl import pickle from sklearn import metrics mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体/matplotlib显示汉字 ##----------------------------------------------------------- # 训练数据 with open('standardtrain.pkl', 'rb') as f: # Python 3: open(..., 'rb') trainx, trainy = pickle.load(f) ##----------------------------------------------------------- # 测试数据 with open('standardtest.pkl', 'rb') as f1: # Python 3: open(..., 'rb') testx, testy, scale = pickle.load(f1) # ############################################################################# # Fit regression model svr_rbf = SVR(kernel='rbf', C=0.8, gamma=0.2) svr_lin = SVR(kernel='linear', C=1e3) svr_poly = SVR(kernel='poly', C=1e3, degree=2) svr_rbf.fit(trainx, trainy) y_rbf = svr_rbf.predict(testx) # Look at the results lw = 2 x1 = np.arange(testy.size) plt.plot(x1, testy, 'r.-',lw=lw, label='训练值') plt.plot(x1, y_rbf, 'k.-', lw=lw, label='测试值') plt.xlabel('data') plt.ylabel('target') plt.title('Support Vector Regression') plt.legend() plt.show() # ############################################################################# # 显示拟合的误差 fig = plt.figure() error_rbf = testy - y_rbf error_rbf = np.squeeze(error_rbf) plt.plot(x1, error_rbf, 'g.-', lw=lw, label='RBF model error') plt.xlabel('data') plt.ylabel('error') plt.title('The fitting error of each model') plt.legend() plt.show() 交通流预测 LSTM SVR 支持向量机 机器学习 # 输出模型的RMSE误差 print(np.sqrt(metrics.mean_squared_error(testy, y_rbf)))