python交通流预测算法_使用KNN方法进行的短时交通流预测和结果分析

我在上一篇文章中简单地讨论了一些关于KNN的细节,这几天花了点时间用python实现了KNN方法在短时交通流预测的应用,我把主要代码和一些注解记录在下文中。

数据来源和预处理:

这次的数据来自Kaggle(Traffic Flow),这个数据集中的数据根据不同的路口编号为文件命名,文件中每五分钟记录一组数据,一个完整的文件的时间跨度约在60天左右。

经过简单观察后发现,这些数据多存在数据缺失的问题,因而取拥有最长的不含0值的时间序列的train26804.csv作为试验展开的数据集。这次的预测模型的建立和结果分析都将基于train26803.csv的第5760行至第14687行进行,其历时正30天。

KNN模型的建立方案

在上一篇文章中提到KNN的几个重要因素中就含有时间延迟τ、历史值向量维数m和近邻个数K,由于本次数据已经给出了一个确定的时间延迟5min,因此这次KNN模型的建立将分三步进行。

首先是找到合适的历史值向量维数m和近邻个数K。本人查阅过的部分论文中均表示,对于m值和K值的选取,长期以来并未有一个统一的标准,但是多数研究者关于m和K的计算结果都处在5~25的区间内,所以我准备结合下面会提到的预测值计算公式和误差计算,遍历所有区间内的m和K的组合,在一个随意选取的时间段内计算各个组合的总误差值,取总误差最小的组合为模型所用。

第二步是计算预测值,预测值将根据与当前历史值向量的距离进行加权平均得到,计算公式:

。根据短时交通流的周期性特征,这次试验中匹配最近邻向量的操作中,将只在当前时间点最近的7天内寻找最近邻向量。距离计算采取欧拉距离计算。

最后,将通过相对方差对预测结果进行评价,计算公式:

求模型参数m和K

首先是建立数据库,这个数据库表现为列表的列表。母列表包含了原数据的各个不同版本的副本,各个不同版本的副本的区别在于追加了多少维度的历史值向量。上一段提到这次试验的匹配最近邻环节将只在最近7天的数据内寻找,所以为观察值最佳历史值向量只发生在第288行也就是第七天之后。

import pandas as pd

import numpy as py

data=pd.read_csv('train26803.csv')

data=data.iloc[5760:14688]

temp=data.values

matrix=[]

for i in temp:

matrix.append(list(i))

re=[]

for m in range(25):

if m != 0:

matrix=[]

for i in temp:

matrix.append(list(i))

for i in range(len(matrix)):

if i >= 288:

for j in range(m):

if j != 0:

matrix[i].append(matrix[i-j][1])

# print(matrix)

re.append(matrix)

print('done')

接着是根据数据库的形式确定距离计算和预测值计算的函数,第三个函数(takeElem)将在寻找最近邻操作中使用到:

def dis(x,y):

t=0

for i in range(len(x)):

if i >= 2:

t+=pow((x[i]-y[i]),2)

return pow(t,1/2)

def pred(ds,i):

if i < 288:

print('error')

return 0

res=[]

# res.append(ds[i])

for j in range(2016):

temp=[]

temp.append(dis(ds[i],ds[i-j-1]))

temp.append(ds[i-j-1][1])

res.append(temp)

return res

def takeFirst(elem):

return elem[0]

然后就是遍历m和K的各个组合,计算各个组合的误差总和,并在其中找到误差最小的组合:

allRes={}

for x in re:

if re.index(x)>2:

tempRes={}

print('m=',str(re.index(x)))

for k in range(25):

if k>2:

print('k=',str(k))

errT=0

n=0

for i in range(2016):

realValue=float(re[0][4068+i][-1])

distances=pred(x,i+4068)

distances.sort(key=takeFirst)

# print('real is:')

# print(re[0][4068+i][-1])

# print('predict in ',str(i+4068))

distancesa=distances[:k]

button = 0

res=0

for i in distancesa:

if i[0]==0:

i[0]=0.00000001

button += 1/(i[0])

for i in distancesa:

res += (1/i[0])*i[1]/button

res=round(res,2)

# print((res-realValue)/realValue)

n+=1

errT+=pow(((res-realValue)/realValue),2)

# print(errT/n)

tempRes[str(k)]=pow((errT/n),2)

allRes[str(re.index(x))]=tempRes

print('done')

##m和k的遍历结果已存入jsonFile.json 待调出处理

minm='3'

mink='3'

for m in allRes:

for k in allRes[m]:

if allRes[m][k]

minm=m

mink=k

print('done')

print("the most suitable m is :",minm)

print("the most suitable k is :",mink)

上述的这一段代码将运行很长的时间,我的小笔记本在这一步需要花四个小时左右进行计算。经过这一步的计算,我们可以得到,针对这个数据集的最优m值为18,最优K值为14。

将上述代码稍加改造就可以直接用来进行预测工作:

allRes={}

for x in re:

if re.index(x)==18:

tempRes={}

print('m=',str(re.index(x)))

for k in range(25):

if k==14:

print('k=',str(k))

errT=0

n=0

tt=[]

for i in range(4068):

realValue=float(re[0][4068+i][-1])

totalT=[]

totalT.append(re[0][4068+i][0])

# print(i)

distances=pred(x,i+4068)

distances.sort(key=takeFirst)

distancesa=distances[:k]

button = 0

res=0

for i in distancesa:

if i[0]==0:

i[0]=0.00000001

button += 1/(i[0])

for i in distancesa:

res += (1/i[0])*i[1]/button

res=round(res,2)

n+=1

errT=((res-realValue)/realValue)

totalT.append(realValue)

totalT.append(res)

totalT.append(round((res-realValue),2))

totalT.append(errT)

tt.append(totalT)

allRes[str(re.index(x))]=tt

print('done')

晚上上述工作之后,所有的预测结果将存在allRes中。

结果展示与误差分析

经过统计后发现,这个统计结果的相对误差和只有0.00133,绝对误差总和只有0.315,这说明,即便这个模型的建立方式相当粗糙,其得到的预测结果还是相对可靠的。

为了直观起见,我对预测值和观察值进行了可视化处理,代码和效果展示如下:

import matplotlib.pyplot as plt

for i in range(15):

sx=[]

sy1=[]

sy2=[]

n=1

for i in tt[i*288:(i+1)*288]:

sx.append(n)

sy1.append(float(i[1]))

sy2.append(float(i[2]))

n+=1

plt.plot(sx,sy1,"x-",label="res")

plt.plot(sx,sy2,"+-",label="real")

"""open the grid"""

plt.grid(True)

plt.legend(bbox_to_anchor=(1.0, 1), loc=1, borderaxespad=0.)

plt.show()

你可能感兴趣的:(python交通流预测算法)