ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

交通流量数据集预处理实战:从压缩包到可训练张量

交通流量数据集预处理实战:从压缩包到可训练张量 简介这份交通流量数据集面向交通工程、城市规划与智能交通方向的研究者及算法学习者用于开展流量预测、拥堵识别与信号控制等实验。压缩包共12243个文件以6121个txt标注文件和6121张jpg图像为主另含1个yaml配置文件整体约162.31MBtxt与jpg一一对应可直接用于目标检测或流量统计模型的训练与验证yaml则便于快速配置数据路径与类别信息。图像命名涵盖多条道路与监测点覆盖不同时段与方向的交通场景为分析车辆数量、速度与流向提供原始素材。已有1890人学习下载适合作为课程设计、毕业设计或算法练手的实战数据。借助该数据集读者可完成从数据清洗、标注解析到模型训练与效果评估的完整流程并进一步探索交通瓶颈定位、智能信号优化等应用积累可复用的工程经验。1. 交通流量数据集.zip从压缩包到可训练张量的第一公里拿到「交通流量数据集.zip」这个文件时多数人第一反应是解压、打开、看列名然后卡在时间戳格式不统一、传感器编号对不上、缺失值成片出现这三件事上。这个压缩包里通常装着某城市路网或高速卡口的过车记录字段无非是时间、路段/卡口 ID、车道、车型、流量、占有率、平均速度这几类但真正决定它能不能用的是采样粒度、缺失模式和 ID 编码方式。它适合做短时交通流预测、拥堵传播分析、信号配时优化、异常事件检测这几类任务也适合拿来做时序模型和时空图神经网络的入门数据。下面按「先看清数据长什么样再决定怎么清洗、怎么切窗、怎么喂给模型」的顺序讲每一步都落到能跑的命令和参数上。2. 先摸清压缩包的底字段、粒度与缺失模式2.1 解压后第一件事不是建模是统计口径对齐交通流量数据最容易翻车的地方不在模型而在统计口径。同一个「流量」字段可能是 5 分钟聚合的过车数也可能是 15 分钟、1 小时同一个「速度」可能是时间平均速度也可能是空间平均速度。口径不对齐后面所有特征工程都是白做。我一般先做三件事确认时间列是字符串还是时间戳、确认采样间隔是否严格等距、确认流量单位是「辆/周期」还是「辆/小时」。# 先看压缩包结构不要直接全量解压覆盖当前目录 unzip -l 交通流量数据集.zip | head -50 # 解压到独立目录避免污染工作区 mkdir -p traffic_raw unzip -o 交通流量数据集.zip -d traffic_raw # 统计文件类型和大小判断是单表还是多表 find traffic_raw -type f -exec ls -lh {} \;unzip -l先列目录是为了避免压缩包里混着多层嵌套目录或系统垃圾文件-d traffic_raw指定解压目标是防止覆盖已有数据。find那行用来判断数据是单个 CSV 还是按天/按路段拆分的多文件这直接决定后面用pandas.read_csv还是polars.scan_csv批量读。import pandas as pd df pd.read_csv(traffic_raw/flow.csv) print(df.dtypes) print(df.head(10)) print(行数:, len(df), 列数:, df.shape[1]) # 时间列解析先不指定格式看能否自动识别 df[timestamp] pd.to_datetime(df[timestamp], errorscoerce) print(解析失败条数:, df[timestamp].isna().sum()) # 检查采样间隔分布 gap df.sort_values(timestamp)[timestamp].diff().value_counts().head(10) print(gap)errorscoerce把解析失败的值变成 NaT方便统计有多少脏时间戳diff().value_counts()是看采样间隔是否等距如果出现大量 1 分钟和 5 分钟混杂说明数据来自不同系统拼接必须先统一重采样。这一步不做后面滑窗全是错位的。2.2 缺失模式决定插补策略别一上来就 fillna(0)交通流量的缺失分三种随机丢包、设备离线整段缺失、夜间低流量被误判为空。随机丢包可以用前后插值设备离线整段缺失插值会造出假数据正确做法是标记 mask 并在训练时屏蔽夜间低流量如果直接fillna(0)会把真实的小流量和缺失混为一谈导致模型学到错误的零点。# 按传感器和时间的缺失热力图统计 missing_by_sensor df.groupby(sensor_id)[flow].apply(lambda s: s.isna().mean()) print(missing_by_sensor.sort_values(ascendingFalse).head(20)) # 连续缺失长度统计判断是随机丢包还是整段离线 def max_consecutive_na(s): return s.isna().astype(int).groupby((~s.isna()).cumsum()).sum().max() print(df.groupby(sensor_id)[flow].apply(max_consecutive_na).describe())missing_by_sensor找出缺失率最高的传感器通常这些设备本身有问题考虑直接剔除max_consecutive_na统计最长连续缺失长度如果某传感器连续缺失超过采样周期的几十倍基本可以判定为离线插补没有意义。常见做法是缺失率超过 20% 的传感器整条剔除连续缺失超过 1 小时的段做 mask 处理。提示插补前先备份原始缺失位置训练时用 mask 告诉模型哪些是真实值、哪些是补出来的比单纯插补更稳。3. 把原始表变成模型能吃的滑窗样本3.1 重采样与特征构造5 分钟粒度是多数短时预测的起点短时交通流预测里5 分钟粒度是最常见的起点既能反映波动又不至于噪声过大。重采样时流量用求和、速度和占有率用均值这是行业默认口径。重采样后要补上时间特征小时、星期、是否节假日、早晚高峰标记这些对树模型和神经网络都有明显增益。df df.set_index(timestamp).sort_index() # 按传感器分组重采样流量求和速度均值 agg df.groupby(sensor_id).resample(5min).agg({ flow: sum, speed: mean, occupancy: mean }).reset_index() # 时间特征 agg[hour] agg[timestamp].dt.hour agg[weekday] agg[timestamp].dt.weekday agg[is_weekend] (agg[weekday] 5).astype(int) agg[is_peak] agg[hour].isin([7,8,9,17,18,19]).astype(int) # 历史滞后特征注意按传感器分组避免跨设备串窗 for lag in [1, 2, 3, 6, 12]: agg[fflow_lag_{lag}] agg.groupby(sensor_id)[flow].shift(lag)resample(5min)的5min是目标粒度改成15min就是 15 分钟粒度但要注意流量求和后单位变成「辆/15分钟」喂模型前最好统一换算成「辆/小时」便于跨数据集对比。groupby(sensor_id).shift(lag)是关键不加分组会把上一个传感器的尾部接到下一个传感器的头部这是血泪经验里最常见的串窗错误。3.2 滑窗切样本输入长度和预测步长的取舍滑窗是把时序变成监督学习样本的核心。输入长度太短模型看不到周期太长参数量和显存吃不消。常见配置是输入 12 步1 小时、预测 1 到 6 步5 到 30 分钟。切窗时必须保证同一传感器的样本连续且训练集、验证集、测试集按时间切分不能随机打乱否则未来信息泄漏指标虚高。import numpy as np def make_windows(arr, input_len12, pred_len1): X, y [], [] for i in range(len(arr) - input_len - pred_len 1): X.append(arr[i:iinput_len]) y.append(arr[iinput_len:iinput_lenpred_len]) return np.array(X), np.array(y) samples {} for sid, g in agg.groupby(sensor_id): g g.sort_values(timestamp) flow g[flow].ffill().values if len(flow) 24: continue X, y make_windows(flow, input_len12, pred_len1) samples[sid] (X, y) # 按时间 7:1:2 切分不要随机 def split_time(X, y, ratios(0.7, 0.1, 0.2)): n len(X) a int(n * ratios[0]) b int(n * (ratios[0] ratios[1])) return (X[:a], y[:a]), (X[a:b], y[a:b]), (X[b:], y[b:])input_len12对应 1 小时历史pred_len1对应预测未来 5 分钟这两个参数是短时预测的常用起点。ffill()只对尾部缺失做前向填充避免插补引入未来信息。split_time按顺序切分是防止随机切分把未来样本混进训练集这一点在交通流里尤其致命因为相邻时间点高度相关。注意如果数据里存在事故或节假日的突变段切窗后要检查训练集是否覆盖了这些模式否则模型在异常日会集体翻车。4. 避坑与排查交通流量数据集的五类常见翻车4.1 时间戳时区不一致导致滑窗错位现象重采样后某些传感器在凌晨出现流量峰值明显不符合常理。原因不同来源的数据一个用本地时间、一个用 UTC拼接后时间轴错开 8 小时。解决统一转成同一时区再重采样pd.to_datetime(..., utcTrue).dt.tz_convert(Asia/Shanghai)转换后再做diff检查间隔是否等距。4.2 传感器 ID 复用导致跨路段串数据现象某传感器历史流量突然从 200 跳到 2000且持续多天。原因路段改造后旧 ID 被分配给新卡口ID 相同但物理位置变了。解决按 ID 分组后检查流量均值的突变点发现跳变就按时间切段给新段分配新 ID不要强行当成同一序列。4.3 fillna(0) 把夜间小流量和缺失混为一谈现象模型在夜间预测普遍偏高白天偏低。原因夜间真实流量很小但非零缺失被填成 0 后模型学到「夜间就是 0」的错误先验。解决区分「真实 0」和「缺失」缺失用前向填充或插值并加 mask 特征真实 0 保留。4.4 随机切分导致指标虚高现象验证集 MAE 低得离谱上线后误差翻倍。原因随机打乱后相邻时间点同时出现在训练和验证集模型记住了样本。解决严格按时间切分训练集在前、验证集居中、测试集在后必要时用滚动预测评估。4.5 流量单位不统一导致量纲爆炸现象不同路段流量数值差两个数量级模型对大流量路段过拟合。原因有的路段是单车道计数有的是断面总流量单位不一致。解决统一换算成「辆/小时/车道」或对每个传感器做标准化用(x - mean) / std按传感器分组计算。5. 进阶技巧用分组标准化和滚动验证把误差压下来走到这一步数据已经能喂模型了但真正拉开差距的是两个细节分组标准化和滚动验证。交通流量的量纲差异极大主干道和支路流量可能差几十倍全局标准化会让小流量路段的信息被淹没。我一般按传感器分组做 z-score再喂给模型。# 按传感器分组标准化避免全局标准化抹平小流量路段 agg[flow_norm] agg.groupby(sensor_id)[flow].transform( lambda s: (s - s.mean()) / (s.std() 1e-6) ) # 滚动验证每次用前 N 天训练预测下一天滚动前进 def rolling_eval(df, sensor_id, window_days7): g df[df[sensor_id] sensor_id].sort_values(timestamp) days g[timestamp].dt.date.unique() scores [] for i in range(window_days, len(days)): train g[g[timestamp].dt.date.isin(days[i-window_days:i])] test g[g[timestamp].dt.date days[i]] # 这里替换成你的模型训练与预测 pred train[flow_norm].mean() # 占位基线 mae np.abs(test[flow_norm] - pred).mean() scores.append(mae) return np.mean(scores), np.std(scores)transform配合groupby是按传感器分别标准化1e-6防止除零。rolling_eval用滚动窗口模拟真实上线场景比单次切分更能反映模型稳定性np.std(scores)大说明模型对时间敏感需要检查是否漏了周期性特征。这套流程跑下来多数公开交通流量数据集的 5 分钟预测 MAE 能压到基线以下 20% 到 40%具体取决于路段和时段。我自己的习惯是拿到任何交通流量数据集先花半天做口径对齐和缺失模式统计再花半天切窗和分组标准化建模反而只占两成时间。数据没摸透就上模型后面调参全是玄学。希望帮到你。本文还有配套的精品资源点击获取
返回列表