ST-CNN实战:用Python实现交通流量预测(附完整代码)

ST-CNN实战:从零构建交通流量预测系统

最近在做一个智慧城市相关的项目,核心需求是根据历史数据预测未来几个小时的交通流量。试过传统的时序模型,也折腾过一些基础的神经网络,效果总是不尽如人意,直到把目光投向了时空卷积神经网络(ST-CNN)。这东西听起来挺唬人,但说白了,就是能同时“看懂”时间和空间上的变化规律。交通数据天生就带有这两种属性:一个路口(空间点)的流量会随时间变化,而相邻路口(空间关系)的流量又会相互影响。ST-CNN恰好是为处理这类数据而生的。这篇文章,我就把自己从数据清洗、模型搭建到训练调参的完整实战过程拆开揉碎了讲给你听,目标是让你看完后,能直接上手复现一个可用的预测系统。整个过程会用到Python、PyTorch以及一些常见的数据处理库,适合已经对深度学习和Python有基本了解,想找一个具体项目练手的开发者。

1. 理解数据:交通流量预测的基石

任何机器学习项目的第一步,也是最关键的一步,就是理解你的数据。对于交通流量预测,我们通常能拿到的是来自各个传感器或摄像头的时序记录。我这次使用的是一份模拟的网格化城市区域流量数据,它包含了多个监测点(节点)在连续时间段内的流量读数。

原始数据往往是一张巨大的表格,行是时间戳,列是各个监测点的流量值。但ST-CNN模型需要的输入格式是三维张量,其形状通常为 (样本数, 时间步长, 节点数, 特征数)。这里的“特征数”在最简单的情况下就是流量这一个值,但你也可以加入速度、占有率等其他维度。

注意:真实数据常常存在缺失值、异常值(比如传感器故障导致流量暴增)以及时间戳不连续的问题。在投入模型前,必须花大力气进行清洗和规整。

数据预处理的核心流程,我总结为以下几步:

  1. 缺失值处理:对于少量缺失,可以用前后时刻的均值或插值法填充;对于大段缺失,可能需要考虑剔除该节点或该时间段的数据。
  2. 异常值检测与处理:使用统计方法(如3σ原则)或基于邻近点的方法识别异常值,并用合理值替换。
  3. 数据归一化:这是加速模型收敛的关键。通常对每个节点单独进行Z-Score标准化,即减去均值除以标准差。切记要保存训练集的均值和标准差,用于对测试集进行相同的变换。
  4. 构建时空序列样本:这是将表格数据转化为模型可读格式的过程。我们需要用一个滑动窗口在时间轴上滑动,每个窗口内的数据作为一个样本,窗口后的一个(或几个)时间点的数据作为该样本的标签(预测目标)。

为了方便理解,我们来看一个数据转换的代码片段。假设我们有一个形状为 (总时间步, 节点数) 的原始数据矩阵 data

import numpy as np

def create_sequences(data, seq_length, pred_length):
    """
    将时序数据转换为监督学习格式的样本。
    参数:
        data: 形状为 (total_timesteps, num_nodes) 的 numpy 数组。
        seq_length: 输入序列的历史时间步长。
        pred_length: 需要预测的未来时间步长。
    返回:
        xs: 样本特征,形状为 (num_samples, seq_length, num_nodes, 1)。
        ys: 样本标签,形状为 (num_samples, pred_length, num_nodes, 1)。
    """
    num_samples = data.shape[0] - seq_length - pred_length + 1
    num_nodes = data.shape[1]
    xs, ys = [], []
    
    for i in range(num_samples):
        # 输入:从 i 到 i+seq_length 的历史数据
        x = data[i:i+seq_length, :]
        # 输出:紧接着的 pred_length 个未来数据
        y = data[i+seq_length:i+seq_length+pred_length, :]
        
        xs.append(x)
        ys.append(y)
    
    # 增加一个特征维度,并转换为 numpy 数组
    xs = np.array(xs)[..., np.newaxis]  # 形状: (N, seq_length, num_nodes, 1)
    ys = np.array(ys)[..., np.newaxis]  # 形状: (N, pred_length, num_nodes, 1)
    
    return xs, ys

处理完数据后,我们还需要定义节点之间的空间关系,即图的邻接矩阵。对于规则网格,可以使用基于距离的高斯核函数来构建加权邻接矩阵;对于不规则的道路网络,则可能需要根据实际连接关系来定义。一个简单的基于距离的邻接矩阵构建方法如下:

def build_adjacency_matrix(node_coords, thre
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值