基于长短期记忆网络LSTM的交通流量预测模型,是一种常用的交通流量预测模型。它主要是通过对历史交通流量数据进行学习,然后预测未来某个时间段内的交通流量情况。LSTM模型相较于传统的预测模型,具有更好的处理序列数据的能力。

最近,我们基于长短期记忆网络LSTM对某个县城的交通流量进行了预测,现将实现过程复现如下:

一、样本数据字段特征:卡口地址、时间、天气、节假日、过车数量(部分数据省略)。

卡口地址 时间 天气 节假日 过车数量
城关加油站门前 2021-01-01 16:00:00 非节假日 11
西大街党校门前 2021-01-01 18:00:00 非节假日 9
皇甫街灵都大厦门前 2021-01-01 21:00:00 非节假日 20
皇甫街灵都大厦门前 2021-01-01 23:00:00 非节假日 16
东大街幼儿园门前 2021-01-02 08:00:00 节假日 16
东大街幼儿园门前 2021-01-02 09:00:00 节假日 12
城关加油站门前 2021-01-02 09:00:00 节假日 8

说明:此次发布到csdn上的项目,所使用的数据为模拟数据,请根据实际情况进行修改。

二、构建长短期记忆网络LSTM模型。

import pandas as pd  
from sklearn.preprocessing import LabelEncoder, MinMaxScaler  
from sklearn.model_selection import train_test_split  
from keras.models import Sequential  
from keras.layers import Dense, LSTM  
import numpy as np  
  
# 读取数据  
data = pd.read_excel(r'卡口模拟数据.xlsx', engine='openpyxl')  
  
# 数据预处理  
data['时间'] = pd.to_datetime(data['时间'])  
data['小时'] = data['时间'].dt.hour  
data['分钟'] = data['时间'].dt.minute  # 添加分钟信息  
data.drop('时间', axis=1, inplace=True)  
  
# 编码分类变量  
encoders = {}  
inverse_mappers = {}  # 存储反向映射关系  
for col in ['卡口地址','天气', '是否节假日']:  
    encoder = LabelEncoder().fit(data[col])  
    encoders[col] = encoder  
    data[col] = encoder.transform(data[col])  
    # 创建反向映射  
    inverse_mappers[col] = {index: category for index, category in enumerate(encoder.classes_)}  
  
# 归一化数据(除了目标变量)  
scaler = MinMaxScaler()  
scaled_features = scaler.fit_transform(data.drop('过车数量', axis=1))  
  
# 创建时间序列数据集  
def create_time_series(data, look_back=1):  
    X, Y = [], []  
    for i in range(len(data) - look_back):  
        X.append(scaled_features[i:(i + look_back), :])  
        Y.append(data['过车数量'][i + look_back])  
    return np.array(X), np.array(Y)  
  
look_back = 1  # 可以根据需要调整时间步长  
X, y = create_time_series(data, look_back=look_back)  
  
# 划分训练集和测试集(连续划分)  
train_size = int(len(X) * 0.7)  
X_train, y_train = X[:train_size], y[:train_size]  
X_test, y_test = X[train_size:], y[train_size:]  
  
# 重新整形数据以适应LSTM  
X_train = np.reshape(X_train, (X_train.shape[0], look_back, scaled_features.shape[1]))  
X_test = np.reshape(X_test, (X_test.shape[0], look_back, scaled_features.shape[1]))  
  
# 构建LSTM模型  
model = Sequential()  
model.add(LSTM(50, activation='relu', input_shape=(look_back, scaled_features.shape[1])))  
model.add(Dense(1))  
model.compile(optimizer='adam', loss='mse')  
  
# 训练模型  
model.fit(X_train, y_train, epochs=100, batch_size=32, shuffle=False)  
  
# 模型评估  
eval_pre = model.predict(X_test)  
mse = np.mean((eval_pre.flatten() - y_test) ** 2)  
print(f'MSE: {mse}')  
  
# 读取待预测数据并进行预处理  
new_data = pd.read_excel(r'待预测车流.xlsx', engine='openpyxl')  
new_data['时间'] = pd.to_datetime(new_data['时间'])  
new_data['小时'] = new_data['时间'].dt.hour  
new_data['分钟'] = new_data['时间'].dt.minute  # 添加分钟信息  

# 保存时间列以便后续使用  
time_column = new_data['时间']  

# 从新数据中删除'时间'列,以便与训练数据保持一致  
new_data.drop('时间', axis=1, inplace=True)  
  
# 对新数据进行相同的编码处理  
for col in ['卡口地址', '天气', '是否节假日']:  
    new_data[col] = encoders[col].transform(new_data[col])  
  
# 使用训练时的scaler对象对新数据进行相同的归一化处理  
scaled_new_features = scaler.transform(new_data)  
  
# 创建与训练时相同形状的输入数据  
X_new = []  
for i in range(len(scaled_new_features) - look_back):  
    X_new.append(scaled_new_features[i:(i + look_back), :])  
X_new = np.array(X_new)  
X_new = np.reshape(X_new, (X_new.shape[0], look_back, scaled_new_features.shape[1]))  
  
# 使用训练好的模型进行预测  
predictions = model.predict(X_new)  
predictions = [int(i) if i > 0 else 0 for i in predictions.flatten()]  
  
# 创建结果DataFrame,并转换回原始数据格式  
result_length = len(predictions)  
result = pd.DataFrame({
    '时间': time_column.values[-result_length:],  # 使用之前保存的时间列     
    '编码后的卡口地址': new_data['卡口地址'].values[-result_length:], 
    '编码后的天气': new_data['天气'].values[-result_length:],  
    '编码后的是否节假日': new_data['是否节假日'].values[-result_length:],  
    '车流量预测': predictions  
}) 
  
# 将编码值转换回原始数据  
result['卡口地址'] = result['编码后的卡口地址'].map(inverse_mappers['卡口地址'])  
result['天气'] = result['编码后的天气'].map(inverse_mappers['天气'])  
result['是否节假日'] = result['编码后的是否节假日'].map(inverse_mappers['是否节假日'])  
  
# 删除编码后的列  
result.drop(['编码后的卡口地址', '编码后的天气', '编码后的是否节假日'], axis=1, inplace=True)  
  
# 调整列顺序
result = result[['时间', '卡口地址', '天气', '是否节假日', '车流量预测']]

# 保存为excel文件  
result.to_excel('交通流量预测.xlsx', index=False)

三、模型结果呈现如下(部分数据省略):

时间 卡口地址 天气 是否节假日 车流量预测
2022-01-01 08:00:00 东大街幼儿园门前 非节假日 3
2022-01-01 09:00:00 东大街幼儿园门前 非节假日 14
2022-01-01 08:00:00 皇甫街灵都大厦门前 非节假日 6
2022-01-01 09:00:00 皇甫街灵都大厦门前 非节假日 18
2022-01-01 08:00:00 西大街党校门前 非节假日 5

 

 

 

 

 

 

 

 

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐