三种模型同台竞技:AR、灰色模型与KNN在交通流量预测中的对比
2026/9/15 16:21:28 网站建设 项目流程

简介:针对交通流量预测问题,这份Matlab仿真资源整合了AR自回归、GM(1,1)灰色预测、KNN近邻三种经典模型,适合本硕博及科研人员用于算法对比、课程设计与论文复现。包体共19个文件,包含8个.m源码脚本、9张结果图示、1份Excel交通数据及1个操作录像avi,整体约9MB,结构紧凑。Runme主脚本分别对应三种模型,配合数据文件和结果图可快速观察各算法预测效果。目前已有611人学习下载。通过源码阅读与录像演示,能帮助读者掌握三种模型的建模思路、Matlab实现步骤及结果可视化方法,尤其适合缺少工程经验的学生对照练习,提升交通流预测方向的编程实践能力。资源中代码注释清晰,运行主脚本即可复现全部仿真结果,便于二次修改与扩展。

1. 三种模型挤进同一个流量预测工程,才有对比价值

交通流量序列从来不是单一结构的时间序列:短时间片里被上下游信号灯周期拖拽,呈现强自相关;放到一小时尺度又出现早晚高峰的非平稳形态;换到一周再看,相似日重复结构远比随机成分显著。这个工程把 AR、GM(1,1)、KNN 三个模型放进同一份 Data.xlsx 和同一批结果图里,本质是让三种建模视角在同一份数据上互相检验:AR 抓短时惯性,灰色模型处理弱波动小样本,KNN 则在找历史相似窗口。压缩包里三个 Runme 主脚本对应三条独立实验线,适合本硕博教研复用;运行前提是 MATLAB 2021a 及以上,从工程根目录打开并运行主脚本,而不是子函数。

2. 自回归模型:把历史流量直接当解释变量

2.1 AR 的假设与交通流量的契合点

AR(p) 模型把当前时刻流量写成前 p 个时刻流量的线性组合,再加上噪声项。对路段检测器数据来说,t 时刻的流量和 t-1、t-2 时刻高度相关,车辆在断面上的连续性不会瞬间消失;用最小二乘估计出的每个滞后项权重,恰好反映这种惯性有多强、能持续几个时间片。相比后面几章要讲的灰色模型和 KNN,AR 几乎是零配置成本:不需要累积生成序列,不需要定义距离度量,只要序列本身满足弱平稳,回归结果就有意义。

实际使用中阶数 p 的选择比系数本身更影响效果。p 太小,模型只抓到一两个周期的惯性,预测在拐点处明显滞后;p 太大,噪声也被当成规律学进去,预测曲线开始抖动。常见做法是先对序列做自相关函数(ACF)和偏自相关函数(PACF)分析,看偏自相关在多少阶截尾,再在测试段上做几次小范围调参。对你拿到的这套工程,AR_6-7.jpg 和 AR_17-18.jpg 两张结果图就是不同时段切片下阶数效果的直观对照。

2.2 Runme1_AR.m 的主脚本调用逻辑

Runme1_AR.m 负责读取 Data.xlsx、调用 Model_AR.m 并输出预测图。Model_AR.m 内部的核心计算思路可以等价写成下面这段代码:

% AR 预测核心流程:滞后矩阵 + 最小二乘 function [coef, pred] = ar_fit(flow, p) % flow: 原始流量序列 % p: 自回归阶数 % 构造滞后矩阵,每行是前 p 个时刻的流量 X = []; y = []; for t = p+1 : length(flow) X(end+1, :) = flow(t-p : t-1); % 特征:过去 p 个值 y(end+1, 1) = flow(t); % 目标:当前值 end % 最小二乘解:coef 就是 AR 系数向量 coef = (X'*X) \ (X'*y); % 对整段序列做滚动预测 pred = zeros(length(flow), 1); for t = p+1 : length(flow) pred(t) = coef' * flow(t-p : t-1)'; end

这里特意用矩阵形式的coef = (X'*X) \ (X'*y)而不是直接调ar()函数,目的是让你看清回归动作本身:特征就是滞后流量,目标就是当前值,AR 本质上是一个带时间结构的线性回归。参数 p 建议在 3 到 10 之间试;如果你改数据源,要注意把flow保持为列向量,否则矩阵乘法维度会报错。

MATLAB 里还有两条等效路线:ar(y, p)走最大似然估计,会额外给出白噪声方差,适合做预测区间;aryule(flow, p)走 Levinson-Durbin 递推,速度快但不够直观。三者在高信噪比下系数几乎一致,教学场景用最小二乘版更好讲。工程中 Runme1_AR.m 会自行调用封装好的 Model_AR.m,你只需要改脚本顶部的p值和绘图区间即可复现。

2.3 结果图 AR_6-7.jpg 与 AR_17-18.jpg 怎么读

看图时第一眼关注两件事:预测曲线是否比真值慢半拍,以及曲线在拐点处是否被拉平。6-7 和 17-18 是时间切片,分别对应早高峰爬升段和傍晚流量回落段,这两个时段的序列统计特性差别很大,正好能暴露 AR 模型的边界。

图像典型现象常见检查项
AR_6-7.jpg预测尾随真值、峰值偏低阶数 p 是否过小
AR_17-18.jpg傍晚波动大,预测偏平滑数据是否混入明显非平稳段

提醒一点:AR 预测的是条件均值,对突变尖峰天然无解。若图上某个尖峰完全没被拟合,不是代码 bug,是模型假设决定的,不必强行调参。

3. GM(1,1) 灰色模型:用累加生成把波动压平

3.1 灰色建模为什么在小样本流量上成立

GM(1,1)(Grey Model,一阶微分方程、单变量)的核心动作是把原始序列做一次累加生成,即 x1(k) = sum(x0(1:k))。累加之后,原本杂乱波动的流量序列会呈现近似指数形态,再用指数函数去拟合这条曲线,最后累减还原回原始尺度。这个思路专门解决「样本点太少、统计方法没法估计分布」的场景:AR 需要足够的滞后项样本来拟合系数,KNN 需要足够大的历史窗口库来寻找邻居,而 GM(1,1) 拿到 4 个点以上就能出结果,所以它常被用作对照组模型。

适用边界同样需要说清:GM(1,1) 假设序列背后有一条平滑指数趋势。流量数据在一天内呈驼峰状,直接套模型会得到单调拟合曲线,所以工程里通常只取一段相对平滑的短窗口来演示灰色模型的长处。这恰恰是三种模型放一起的价值:没有哪个模型在所有时段都占优,关键看数据形态和建模假设是否匹配。

3.2 GM11.m 的最小二乘计算链

Runme2_GM11.m 调用 GM11.m 完成建模与预测,核心步骤可以等价还原成下面这段代码:

% GM(1,1) 建模核心:累加、均值生成、最小二乘、累减还原 function [pred, a, b] = gm11_fit(x0, n_pred) % x0: 原始观测序列(列向量) % n_pred: 向后预测的步数 n = length(x0); x1 = cumsum(x0); % 1-AGO 累加生成 z1 = 0.5 * (x1(2:end) + x1(1:end-1)); % 紧邻均值生成序列 B = [-z1, ones(n-1, 1)]; Y = x0(2:end); u = (B'*B) \ (B'*Y); % 最小二乘估计 a = u(1); % 发展系数 b = u(2); % 灰色作用量 pred_x1 = zeros(n + n_pred, 1); pred_x1(1) = x0(1); for k = 1 : n + n_pred - 1 pred_x1(k+1) = (x0(1) - b/a) * exp(-a*k) + b/a; end pred = subtract_restore(pred_x1, x0); % 累减还原成预测序列

代码里三个容易被忽略的地方。第一,z1是相邻累加值的平均,而不是原始值的平均,这个背景值序列直接影响参数 a 和 b 的估计精度;第二,发展系数 a 反映序列增长趋势,|a| 小于 0.3 时灰色预测通常可靠,超过这个范围预测曲线会明显失真;第三,预测步数越多,exp(-a*k)的指数效应越强,表现在交通序列上就是预测值快速收敛到某个水平线。如果原始流量数值在数百到数千量级,累加后 x1 会到数万,B'*B的条件数可能偏大,换新数据源时建议先把序列做一次标准化再建模。

工程运行时你不需要手动调用 GM11.m,直接跑 Runme2_GM11.m 就会生成 GM(1,1).jpg。图里通常包含原始序列、拟合序列和未来几步预测三组曲线,对比时重点看拟合段与原始段的贴近程度,而不是盯住未来段的绝对误差。

3.3 灰色模型在交通流量场景的典型失效

场景GM(1,1) 表现处理方式
流量缓慢上升段拟合好,预测可信保留并展示
早晚高峰剧烈震荡段预测被拉平或出现不合理骤降缩短建模窗口或先平滑
样本少于 6 个点参数 a 估计不稳定至少取 10 个点做实验

新手最容易犯的错是拿一整天流量直接跑 GM(1,1),然后看到预测曲线变成一条直线,就以为代码写坏了。其实这是灰色模型在非单调数据上的正常失效:最小二乘把指数趋势拟合成一个「平均斜率」,累减还原后自然拖平。想让它表现好,就用 5 分钟或 15 分钟粒度切短窗重跑。

4. KNN 回归:不假设分布,用相似历史窗口投票

4.1 把预测问题改成近邻查找

KNN 做回归的思路和前两种完全不同:它不估计任何参数,只维护一个历史窗口库。给定当前时刻之前 w 个时间片的流量,构成一个 w 维向量;在历史库里找欧氏距离最近的 k 个向量,把它们各自对应的下一时刻流量取平均,就是预测值。w 决定用多长的历史形态匹配,k 决定用多少个相似片段投票。

这个思路能捕捉「相似日」结构:周二早高峰 8:00 前后的流量形态,往往和最接近的几个历史工作日同时段形态相似。这是 AR 和灰色模型都利用不了的信息。代价是计算开销:预测一个点要扫一遍全部历史窗口,w 越大维度越高。工程里带 KNN_t 的一组 jpg 图,就是围绕窗口长度或近邻数量做的敏感性实验,具体哪个变量要看 Runme3_KNN.m 里变量名的定义。

4.2 Model_KNN.m 的窗口构建与距离筛选

% KNN 回归核心:候选集构建 + 最近邻平均 function pred = knn_flow(flow, w, k, test_idx) % flow: 流量序列 % w: 特征窗口长度 % k: 近邻数量 % test_idx: 待预测样本的位置索引 cand = []; label = []; for t = w+1 : length(flow) cand(end+1, :) = flow(t-w : t-1); % 每一个历史形态 label(end+1, 1) = flow(t); % 形态之后的一步真值 end query = flow(test_idx-w : test_idx-1); d = sqrt(sum((cand - query).^2, 2)); % 欧氏距离 [~, idx] = mink(d, k); % 最近 k 个样本索引 pred = mean(label(idx)); % 平均作为预测结果

mink(d, k)是 MATLAB 内置函数,比先 sort 再截取少用一半临时内存,候选样本数千级别时差距很明显。参数上的经验值:w 不要超过 24,因为 5 分钟粒度下 24 个点就是两小时,再长会出现维数灾难;k 可以从 sqrt(候选样本数) 附近开始试,比如历史窗口有 300 条,先取 15 到 20,再按交叉验证误差微调。流量数据各维度量纲一致,不需要额外做标准化;如果你自己做了归一化,比较向量也要同步缩放。

工程里若预测点很多,这段循环会偏慢。想提速可以换成knnsearch配合 k-d 树,或者在候选库里先按星期几过滤掉异类天再匹配,效果通常更贴合交通流特性。

4.3 KNN_t 系列图片里的欠拟合与过拟合

文件参数含义(按命名推断)观察重点
KNN_t=6近邻数或窗口为 6曲线贴着局部噪声走
KNN_t=12中间取值预测形态最接近真值
KNN_t=18偏大的邻域或窗口曲线变平滑,尖峰被抹掉
KNN_t=23 / 30更大参数偏差增大,滞后明显

这组图从左到右其实就是参数敏感性实验:参数太小时预测方差大,过大时预测退化成平均形态。你可以在 Runme3_KNN.m 里改 k 值重新出图,验证趋势,顺便确认 t 到底绑定的是 k 还是 w。

5. 数据预读、运行顺序与三种预测的横向校验

5.1 拿到的压缩包如何快速跑通

解压到纯英文路径,例如D:\traffic_forecast,用 MATLAB 打开工程根目录,按 Runme1_AR.m、Runme2_GM11.m、Runme3_KNN.m 的顺序执行。不要直接在命令行里运行 Model_ 开头的函数文件,它们通常依赖主脚本预先准备的工作区变量,比如 flow、time_axis,独立运行会报「未定义函数或变量」。解压包里的操作录像 0022.avi 演示的就是这套环境准备流程,跟着点一遍即可。

如果报错涉及表变量名不存在,打开 Data.xlsx 确认流量列实际名称,再回脚本里把readtable的列名参数改一致;常见列名是 Flow、flow、VOL。确认 MATLAB 左侧当前文件夹窗口显示的是工程所在路径,再点运行。

5.2 用三个迹象判断仿真是否正确

现象原因对策
GM 预测曲线成水平直线数据段非单调,指数拟合退化成常数缩短窗口重跑
AR 预测值随步数发散、越走越高序列非平稳导致系数病态先做一阶差分再预测
KNN 预测与真值几乎完全重合测试点本身还在候选集里预测前排除含该时刻的候选窗口

你担心的「仿真发散」问题要分模型定位:AR 发散是系数矩阵病态,GM 发散是指数参数过大,KNN 一般不发散而只是失效。按表格先定位再改参,比盲目换模型效率高。

5.3 统一用 MAPE 和 RMSE 对比三种模型

mape = mean(abs((pred - actual) ./ actual)) * 100; rmse = sqrt(mean((pred - actual).^2));

单独看结果图只能判断形态,量化对比就同时算这两个指标。把三个模型的 pred 分别保存在工作区,对同一段 actual 跑这两行,填进一张小表即可。一个值得记住的细节:实际流量接近 0 的时刻,MAPE 会被单个点拉出几十倍的虚高值,对比前先把这些时刻过滤掉,否则指标失真。

5.4 横向对比的采样口径

三个脚本内部可能用了不同的数据切分方式,直接对比误差不够严谨。做实验时可以在各脚本最前面统一执行rng(1);固定随机数种子,并让每个模型都输出同一时段的预测结果,这样才能保留横向对比的可信度。建议把三个模型的误差表存成comparison.xlsx,方便反复比较不同参数组合、不同窗口设置下的误差分布。这样,对同一份交通流量数据的三种预测方法就有了可复现、可量化的统一口径。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询