logo资料库

国科大数据挖掘大作业2018交通拥堵预测.docx

第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
资料共7页,全文预览结束
三、算法及解决方案 1. 导入数据 将四天的训练集数据放在一个表中,表的格式为 csv 文件,使用 pandas 包中的 read_csv 方 法将 csv 文件读入,并标记每一列的属性。 import pandas as pd train=pd.read_csv("F:\\mydocument\\py\\all2.csv",header=None,sep=',',names=["date","time"," direction","type","linkID","length","travelTime","volumn","speed","occupancy","congestionLevel ","null"],encoding='GB2312') 读入后的数据如图 3.1 所示: 图 3.1 训练集原始数据 2. 数据预处理 (1)将传感器的型号进行编码,该问题中一共有 855 个传感器,将传感器的型号用 0 到 854 表示,使用 sklearn 包中的 LabelEncoder import pandas as pd from sklearn.preprocessing import LabelEncoder from sklearn.pipeline import Pipeline class MultiColumnLabelEncoder: def __init__(self,columns = None): self.columns = columns # array of column names to encode def fit(self,X,y=None): return self # not relevant here def transform(self,X): output = X.copy() if self.columns is not None: for col in self.columns: output[col] = LabelEncoder().fit_transform(output[col]) else: for colname,col in output.iteritems(): output[colname] = LabelEncoder().fit_transform(col) return output def fit_transform(self,X,y=None): return self.fit(X,y).transform train = train.fillna('') train[['linkID']]=train[['linkID']].apply(LabelEncoder().fit_transform) 传感器编码后的结果如图 3.2 所示:
图 3.2 传感器型号编码后的数据 从图 3.2 中,可以看到 linkID 这一列由原来的 WI-MNT_XML_V001-5006 编码成了相对应 的数值。 ( 2 ) 将 拥 堵 程 度 : NON_CONGESTION 、 LIGHT_CONGESTION 、 MEDIUM_CONGESTION 、 HEAVY_CONGESTION、UNKNOWN_CONGESTION_LEVEL 分别映射成 0、1、2、3、4,使用 map 方法,便于将数据放入模型中。 size_mapping = { 'NON_CONGESTION':0, 'LIGHT_CONGESTION':1, 'MEDIUM_CONGESTION':2, 'HEAVY_CONGESTION':3, 'UNKNOWN_CONGESTION_LEVEL':4} train['congestionLevel'] = train['congestionLevel'].map(size_mapping) 拥堵程度映射后的结果如图 3.3 所示: 图 3.3 拥堵程度映射后的数据 从图 3.3 中可以看出:congestionLevel 这一列已由原来的 NON_CONGESTION 映射成了相 应的数值。 (3)删掉日常生活中不符合常理的数据,删去车辆行程时间为负值的数据、车速为负值的 数据、道路的占有率为负值的数据以及拥堵状况未知的数据,由于题目所提供的数据量较多, 删掉这些数据不会影响训练出的模型的准确度。 print(train.shape) train=train[~(train['travelTime']<=0)] train=train[~(train['speed']<0)] train=train[~(train['occupancy']<0)] train=train[~(train['occupancy']==4)]
print(train.shape) Train 数据清洗后,如图 3.4 所示: 从图 3.4 的运行结果中可以看到:数据已由原来的 984958 条删减到了 605935 条数据。 图 3.4 清洗后的数据 (4)特征选择 针对每一个传感器而言,由于传感器的位置是不变的,所以数据中方位(direction)、 道路类型(type)、道路长度(length)都是固定不变的,所以可以将其删去,这些特征不 影响模型的准确度;由于车速(speed)、道路的占有率(occupancy)和道路的拥堵程度 (congestionLevel null)直接相关,拥堵程度高相应的车速会慢、道路占有率会高。所以, 针对该问题,我们只选取时间和拥堵程度作为特征,进行模型的训练。 特征选择后的结果如图 3.5 所示: 图 3.5 特征选择后的数据 (5)时间处理 该问题是时间序列问题,需要把原始数据中的日期和时间这两列转化成模型支持的 datetime 类型,具体处理了方式如下: train['date'] = train['date'].map(lambda x:'date'+x if len(x)==3 else x) train['time'] = train['time'].map(lambda x:'date'*(4-len(x))+x if len(x)<4 else x) train['date_time'] = train['date'] + train['time'] def format_date(s):
month = int(s[:2]) day = int(s[2:4]) h = int(s[4:6]) m = int(s[6:]) return datetime.datetime(2018, month, day, h , m) train['date_time'] = train['date_time'].map(format_date) 处理后得到的数据如图 3.6 所示: (6)将数据可视化:以其中的一个传感器为例,画出训练集中交通拥堵程度随时间变化的 图,如图 3.7 和图 3.8 所示,这样能更直观的看出一天中交通拥堵程度变化的规律。 图 3.6 时间处理后的数据 图 3.7 交通拥堵程度变化图
图 3.8 交通拥堵程度变化图 3. 建立 LSTM 模型 (1)考虑到真实的训练环境,把每批次训练样本数(batch_size)、时间步(time_step)、 训练集的数量(train_begin,train_end)设定为参数,使得训练更加高效。为神经网络模型设 定初始值,定义输入层维度为 1,输出层维度为 1,隐藏层的层数为 60,模型的学习率为 0.0006,时间步定义为 20,每次训练 60 个样例。 time_step=20 rnn_unit=10 batch_size=60 input_size=1 output_size=1 lr=0.0006 train_x,train_y=[],[] for i in range(len(normalize_data)-time_step-1): #时间步 #隐藏层的个数 #每一批次训练多少个样例 #输入层维度 #输出层维度 #学习率 #训练集 x=normalize_data[i:i+time_step] y=normalize_data[i+1:i+time_step+1] train_x.append(x.tolist()) train_y.append(y.tolist()) (2)定义神经网络变量的输入层、输出层的权重和偏倚: weights={ 'in':tf.Variable(tf.random_normal([input_size,rnn_unit])), 'out':tf.Variable(tf.random_normal([rnn_unit,1])) }
biases={ 'in':tf.Variable(tf.constant(0.1,shape=[rnn_unit,])), 'out':tf.Variable(tf.constant(0.1,shape=[1,])) } (3)定义神经网络变量:传入的参数为输入网络批次数目,传入模型中的数据需要转成 2 维进行计算,计算后的结果作为隐藏层的输入,隐藏层中的数据需要转成 3 维,作为 lstm cell 的输入,output_rnn 是记录 lstm 每个输出节点的结果,final_states 是最后一个 cell 的结果, output 作为输出层的输入。 def lstm(batch): w_in=weights['in'] b_in=biases['in'] input=tf.reshape(X,[-1,input_size]) input_rnn=tf.matmul(input,w_in)+b_in input_rnn=tf.reshape(input_rnn,[-1,time_step,rnn_unit]) cell=tf.nn.rnn_cell.BasicLSTMCell(rnn_unit) init_state=cell.zero_state(batch,dtype=tf.float32) output_rnn,final_states=tf.nn.dynamic_rnn(cell,input_rnn,initial_state=init_state,dtype=tf.fl oat32) output=tf.reshape(output_rnn,[-1,rnn_unit]) w_out=weights['out'] b_out=biases['out'] pred=tf.matmul(output,w_out)+b_out return pred,final_states (7)训练模型:训练过程中,模型重复训练 10000 次,训练好后将模型保存为 travel.model def train_lstm(): global batch_size pred,_=lstm(batch_size) #损失函数 loss=tf.reduce_mean(tf.square(tf.reshape(pred,[-1])-tf.reshape(Y, [-1]))) train_op=tf.train.AdamOptimizer(lr).minimize(loss) saver=tf.train.Saver(tf.global_variables()) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) #重复训练 10000 次 for i in range(10000): step=0 start=0 end=start+batch_size while(end
if step%10==0: print(i,step,loss_) print("保存模型:",saver.save(sess,'travel.model')) step+=1 (8)预测模型:预测时只需输入[1,time_step,input_size]的测试数据 def prediction(): pred,_=lstm(1) saver=tf.train.Saver(tf.global_variables()) with tf.Session() as sess: #参数恢复 module_file = tf.train.latest_checkpoint(base_path+'module2/') saver.restore(sess, module_file) #取训练集最后一行为测试样本。shape=[1,time_step,input_size] prev_seq=train_x[-1] predict=[] #得到之后 100 个预测结果 for i in range(100): 试样本 next_seq=sess.run(pred,feed_dict={X:[prev_seq]}) predict.append(next_seq[-1]) #每次得到最后一个时间步的预测结果,与之前的数据加在一起,形成新的测 prev_seq=np.vstack((prev_seq[1:],next_seq[-1])) #以折线图表示结果 plt.figure() plt.plot(list(range(len(normalize_data))), normalize_data, color='b') plt.plot(list(range(len(normalize_data), len(normalize_data) + len(predict))), predict, color='r') 4.使用 plt.show()
分享到:
收藏