渔港的老船长阿海,从来不回答“明天能打多少鱼”这种简单问题。他会先翻一翻昨天的渔获日志,再看看云层、潮汐和季节,然后慢慢说一句:“带上大网,八成在 30 到 80 条之间。”这句话里有三个智慧:第一,他先读历史;第二,他借用外部线索;第三,他知道未来充满不确定性,所以给的不是一个数字,而是一个范围。DeepAR 就是把这套“渔港智慧”变成深度学习模型的现代算法。它属于自回归概率预测家族:用历史数据滚动预测,输出一个完整概率分布,再从中切出分位数和预测区间,让库存、电力、运维等场景都能提前做好“带多大网”的决策。这篇文章将用阿海的航海日志,带你从零理解 DeepAR 这颗现代时间序列预测的“智慧罗盘”。

岗位关联

对时序分析工程师而言,DeepAR 是连接“点预测”与“决策风险”的桥梁。学会它,你能在业务中给出带着置信度的答案,也让预测报告从“猜个数”升级为“给区间”。

目录
  1. 可视化演示
  2. 问题背景:只报一个数会害了整船人
  3. 自回归原理:边看边猜的接力赛
  4. 分布参数输出:画一张可能性地图
  5. 分位数预测:把分布切成决策
  6. 协变量支持:借天气和潮汐的眼睛
  7. ARIMA对比:固定公式 vs 数据驱动
  8. 训练流程:五十年日志浓缩成模型
  9. 应用落地:渔港智慧装进行业
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

动态演示DeepAR的核心机制,通过概览/流程/对比/趋势四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

DeepAR:Deep 1. DeepAR模型架构与自 2. 参数化分布输出与概率预测 核心机制可视化 DeepAR整体架构与关键组件

问题背景:只报一个数会害了整船人

阿海在渔港干了四十年。每天清晨,都有年轻船长问他:“今天能打多少鱼?”阿海从不直接报一个数,总是先翻翻日志,看看天气和潮汐时间,然后说:“八成在 30 到 80 条之间。”年轻人常常疑惑:为什么不给一个准数?阿海反问:如果只给你“50 条”,风浪大时你带小网出海,风险谁来担?

在时间序列预测里,“只报一个数”就是点预测。它给出期望值或中位数,却无法表达波动范围。做电商库存时,如果系统说“下周卖 1000 件”,实际可能是 800 件,也可能是 1500 件——单凭一个数,你既不敢大胆备货,又不敢过度压缩库存。概率预测则不同,它会告诉你“销量大概率落在 800 到 1300 件之间”,这样你就能按风险偏好做决策。DeepAR 正是为这类需求而生:它不再输出单一数值,而是输出一个完整分布,再由分布计算分位数和预测区间。

另一个关键背景是多序列共享。一个港口有几十条渔船,各自的渔获曲线千差万别,但又共享鱼汛、季节和洋流带来的共同规律。如果为每条船单独建模,数据稀疏且模型脆弱;DeepAR 把多条序列一起喂给网络,让模型在共享全局规律的同时,通过序列嵌入区分不同个体。这种“多条序列联合建模”的做法,让冷启动序列也能借力其他序列获得合理预测。

这段原理就像阿海在心中画了一张“可能性地图”:他不问“明天一定是多少”,而是问“明天大概落在哪一片海域”。分位数就是这张地图上的刻度线,把不确定性切成可管理的区间。

Qτ(z)=inf⁡{z∈R:Fz(z)≥τ}Q_\tau(z)=\inf\{z\in\mathbb{R}:F_z(z)\ge\tau\}
分位数函数是分布函数的“反向查询表”:给定比例 τ,找到对应的取值刻度。
  1. 分布函数先定义 F_z(z)=P(Z≤z),它表示随机变量 Z 不超过某个值 z 的概率,也就是“渔获不超过某条数”的累计概率。
    Fz(z)=P(Z≤z)F_z(z)=P(Z\le z)
  2. 反求分位点给定 τ,找到使分布函数刚好超过 τ 的最小 z,这个值就是第 τ 分位数。
    Qτ(z)=inf⁡{z:Fz(z)≥τ}Q_\tau(z)=\inf\{z:F_z(z)\ge\tau\}
  3. 构建预测区间取 τ=0.05 与 τ=0.95 两个分位数,便得到 90% 预测区间,业务上可理解为“九成把握鱼获落在中间”。
    [Q0.05(z), Q0.95(z)][Q_{0.05}(z),\,Q_{0.95}(z)]

自回归原理:边看边猜的接力赛

阿海预测明天的渔获,不是凭空想象。他先读今天的日志,用今天推明天;如果明天还没到,他就把“推算出的数”当作临时的假想记录,再往后推后天。这个“预测值滚进下一步再继续预测”的动作,就是自回归的本质——用自己过去的输出,去预测未来的下一步。

DeepAR 的具体做法是:用循环神经网络(RNN,常见实现为 LSTM 或 GRU)逐时间步读取历史观测和协变量,并维护一个隐藏状态 h_t。这个隐藏状态就像是阿海脑中的“综合判断”,浓缩了从开港以来到当前时刻的所有信息。每一步,模型基于 h_t 输出下一步的条件分布。这个结构可以用条件概率公式表达:

自回归也带来一个绕不开的挑战:误差传播。推理阶段,模型没有真实观测值可用,只能用自己采样的预测值作为下一步输入,前一步的偏差会被一步步放大。这就像阿海在雾天里航行,第一步方向偏了,后面每一步都可能偏得更远。因此 DeepAR 在预测时采用“采样 + 滚动”的方式,而不是简单地把均值当真相,以降低误差多米诺效应。

p(zt0:T∣z1:t0−1,x1:T)=∏t=t0Tp(zt∣z1:t−1,x1:T)p(z_{t_0:T}\mid z_{1:t_0-1},x_{1:T})=\prod_{t=t_0}^{T}p(z_t\mid z_{1:t-1},x_{1:T})
左边是“给定过去,未来整段序列的联合概率”,右边把它拆成“每个时刻条件概率的连乘”。这正是自回归的概率语言。
  1. 联合概率左边表示给定过去观测与协变量 x_{1:T} 后,未来序列 z_{t_0} 到 z_T 整体出现的概率。
    p(zt0:T∣z1:t0−1,x1:T)p(z_{t_0:T}\mid z_{1:t_0-1},x_{1:T})
  2. 链式分解右边把联合概率写成每个时刻条件概率的连乘,每一时刻只依赖它之前的信息。
    ∏t=t0Tp(zt∣z1:t−1,x1:T)\prod_{t=t_0}^{T}p(z_t\mid z_{1:t-1},x_{1:T})
  3. 自回归依赖每一项都依赖全部历史 z_{1:t-1},这意味着模型每走一步,都把“过去”背在身上,像接力赛的选手始终握着前一棒。
    p(zt∣z1:t−1,x1:T)p(z_t\mid z_{1:t-1},x_{1:T})

分布参数输出:画一张可能性地图

阿海心里那张“可能性地图”,并不是一条线,而是一座高低起伏的山:40 到 60 条是山脊,几乎每天都出现;90 条是尖峰,偶尔遇到鱼群;10 条是低谷,台风天常见。DeepAR 要做的,就是让神经网络学会画出这样一张地图——也就是输出一个参数化分布。

对于连续型目标(如电量、温度、渔获的千克数),DeepAR 常用高斯分布,输出均值 μ 和标准差 σ。对于计数型目标(如订单件数、鱼获条数),则用负二项分布,输出均值 μ 和分散度 α。模型把 RNN 的隐藏状态 h_t 通过一个输出层映射为分布参数,再用最大似然原则训练,让历史数据在预测分布下出现概率最大。高斯分布与参数映射可写成:

负二项分布则用于计数场景,其概率质量函数为:

输出分布参数的意义在于:模型不再被逼着“说一个准数”,而是诚实地表达“我知道多少、我不知道多少”。阿海之所以敢说 30 到 80,不是因为他算得准,而是因为他知道自己对海洋的把握有多少。DeepAR 用分布参数把这种“自知之明”写进了数学里。

p(zt∣θ(ht))=12πσ2exp⁡(−(zt−μ)22σ2),μ=Wμht+bμ,σ=exp⁡(Wσht+bσ)\begin{aligned}p(z_t\mid\theta(h_t))&=\frac{1}{\sqrt{2\pi\sigma^2}}\exp\left(-\frac{(z_t-\mu)^2}{2\sigma^2}\right),\\\mu&=W_\mu h_t+b_\mu,\qquad \sigma=\exp(W_\sigma h_t+b_\sigma)\end{aligned}
高斯分布由均值和方差决定;DeepAR 不是直接输出任意数字,而是输出“这张地图长什么样”的两个参数。
p(z∣μ,α)=(z+1α−1z)(αμ1+αμ)z(11+αμ)1αp(z\mid\mu,\alpha)=\binom{z+\frac{1}{\alpha}-1}{z}\left(\frac{\alpha\mu}{1+\alpha\mu}\right)^z\left(\frac{1}{1+\alpha\mu}\right)^{\frac{1}{\alpha}}
负二项多了一个分散度参数 α,能刻画“方差大于均值”的过离散计数,比如爆款商品销量。
  1. 高斯密度密度函数给出某个观测 z_t 在指定均值方差下的相对概率,是“地图上该点的高程”。
    p(zt∣θ(ht))=12πσ2exp⁡(−(zt−μ)22σ2)p(z_t\mid\theta(h_t))=\frac{1}{\sqrt{2\pi\sigma^2}}\exp\left(-\frac{(z_t-\mu)^2}{2\sigma^2}\right)
  2. 均值参数映射均值由隐藏状态的线性变换得到,W_μ 和 b_μ 是网络学习到的权重与偏置。
    μ=Wμht+bμ\mu=W_\mu h_t+b_\mu
  3. 标准差保证正先线性变换再取指数,确保 σ 永远为正,避免出现“负方差”这种无意义结果。
    σ=exp⁡(Wσht+bσ)\sigma=\exp(W_\sigma h_t+b_\sigma)
  4. 负二项计数机制组合数部分表示“把 z 次成功分配到若干批次”的路径数量,适配计数数据。
    (z+1α−1z)\binom{z+\frac{1}{\alpha}-1}{z}
  5. 分散度参数α 越大,方差相对均值越大,地图越“陡峭多变”;α 趋近 0 时退化为泊松分布。
    αμ1+αμ\frac{\alpha\mu}{1+\alpha\mu}

分位数预测:把分布切成决策

阿海说的“八成在 30 到 80 条”,其实是在切分布:他心中那座“可能性地图”里,有 10% 的概率低于 30 条,10% 的概率高于 80 条,中间 80% 是相对稳妥的区间。把连续分布切成若干段,每一段对应的边界值,就是分位数。

DeepAR 得到分布参数后,可以解析地算分位数,也可以从分布中采样再算经验分位数。以高斯分布为例,第 τ 分位数可写作均值加上标准差的若干倍:

预测区间比单点更贴合真实决策。备货时,你关心的是“至少准备多少才不至于缺货”,这对应较高分位数;控制成本时,你关心的是“最多别超多少”,这对应较低分位数的反方向。DeepAR 的分位数预测,本质上是一把可调节的“风险标尺”,让业务人员根据自己的风险偏好自由选择刻度。

Zτ=μ+σΦ−1(τ)Z_\tau=\mu+\sigma\Phi^{-1}(\tau)
Φ^{-1} 是标准正态分布的分位数函数;μ 负责平移,σ 负责缩放,把标准分位点移到预测分布上。
  1. 标准分位点Φ^{-1}(τ) 给出标准正态分布的第 τ 分位点,比如 τ=0.9 时约为 1.28。
    Φ−1(0.9)≈1.28\Phi^{-1}(0.9)\approx1.28
  2. 平移缩放加上 μ、乘上 σ,把标准分位点搬移到实际预测分布尺度上。
    Zτ=μ+σΦ−1(τ)Z_\tau=\mu+\sigma\Phi^{-1}(\tau)
  3. 构造区间同时取 τ=0.16 与 τ=0.84,得到 68% 预测区间;取 0.05 与 0.95,则得到 90% 预测区间。
    [μ+σΦ−1(0.05), μ+σΦ−1(0.95)][\mu+\sigma\Phi^{-1}(0.05),\,\mu+\sigma\Phi^{-1}(0.95)]

协变量支持:借天气和潮汐的眼睛

阿海预测渔获,绝不只是看昨天打了多少鱼。他会看云层判断风向,看潮汐表判断鱼群上岸时间,看季节判断鱼汛期。这些额外信息有一个共同特点:在预测时刻是可以提前知道的。在 DeepAR 里,这类信息被称为协变量。

协变量分为三类。第一类是时间特征,比如星期几、是否节假日、一年中的第几周,它们刻画数据的时间节律。第二类是静态特征,比如商品 ID、店铺 ID、渔船编号,它们让模型区分不同序列的个性。第三类是未来已知的外部信息,比如已经公布的促销计划、天气预报、排产安排——它们在未来已知,可以安全地参与预测。DeepAR 把协变量与历史观测一起送入 RNN,让隐藏状态不仅记住“过去发生了什么”,还知道“现在是什么环境”。其状态更新可写成:

使用协变量要注意一个红线:未来未知的动态变化不能用。比如“未来某天的即时刻价格波动”是无法预知的,把它当协变量等于让模型偷看未来,训练和推理的分布会不一致,预测区间也会失真。阿海从来不把“明天是否会遇到鱼群”这种随机事件当作已知信息,他只借那些“能提前看天”的可靠信号。

ht=RNN(ht−1,zt−1,xt)h_t=\mathrm{RNN}(h_{t-1},z_{t-1},x_t)
上一步隐藏状态、刚发生的观测、当前协变量三者共同决定新的隐藏状态;x_t 就是那副“天气与潮汐的眼睛”。
  1. 状态更新RNN 把上一步隐藏状态 h_{t-1}、上一步观测 z_{t-1} 与当前协变量 x_t 融合,得到新状态 h_t。
    ht=RNN(ht−1,zt−1,xt)h_t=\mathrm{RNN}(h_{t-1},z_{t-1},x_t)
  2. 观测输入z_{t-1} 是自回归部分,让模型知道“刚发生的事”,相当于阿海刚看到的渔获。
    zt−1z_{t-1}
  3. 协变量接入x_t 是外部信息通道;由于它来自时间、日历或已公布计划,预测时可以提前拿到,不会造成信息泄漏。
    xtx_t

ARIMA对比:固定公式 vs 数据驱动

阿海的爷爷也有一套预测方法:一本写满系数的“大海公式”。今天的渔获等于过去几天的线性组合,再加上一些历史噪声的残留。这套方法就是统计时间序列中的 ARIMA。在小范围、相对平稳的海域,它很管用;可一旦遇到洋流突变、鱼汛非线性爆发,公式就会失灵。

ARIMA 的数学形式可以写成:

DeepAR 与 ARIMA 的差异,本质上是两种世界观的差异。ARIMA 是“给定公式,估计系数”,假设关系线性、序列平稳、单序列独立建模;DeepAR 是“给定数据,学习映射”,用循环网络拟合非线性关系,多序列共享参数,还能自然接入协变量。当然,ARIMA 在样本量小、可解释性要求高的场景仍有价值。阿海并不是要扔掉爷爷的公式,而是多了一艘现代化的渔船:遇到复杂海况,用数据学出来的直觉,比固定公式更可靠。

(1−∑i=1pϕiLi)(1−L)dzt=(1+∑j=1qθjLj)εt(1-\sum_{i=1}^{p}\phi_i L^i)(1-L)^d z_t=(1+\sum_{j=1}^{q}\theta_j L^j)\varepsilon_t
L 是滞后算子,φ 与 θ 是线性系数;ARIMA 用有限个线性项描述序列动态。
  1. 自回归项φ_i L^i 表示过去第 i 天取值对当前值的线性影响,相当于爷爷只看“昨天、前天、大前天”的简单加权。
    ∑i=1pϕiLi\sum_{i=1}^{p}\phi_i L^i
  2. 差分操作(1−L)^d 对序列做 d 阶差分,目的是消除趋势,让序列变得平稳。
    (1−L)dzt(1-L)^d z_t
  3. 移动平均项θ_j ε_{t-j} 描述过去随机噪声的残余记忆,捕捉“历史冲击对未来的余波”。
    ∑j=1qθjLjεt\sum_{j=1}^{q}\theta_j L^j\varepsilon_t

训练流程:五十年日志浓缩成模型

阿海今天的判断力,来自五十年间每天记录的航海日志。DeepAR 的训练流程也是同样的逻辑:把大量历史“日志”标准化后喂给网络,用损失函数反复打磨,最后得到一个能对新海域做概率预测的模型。

训练的第一步是数据预处理:对每条序列做缩放(常用同比缩放),使不同量纲的序列可比;再按固定窗口切出训练样本。第二步是定义损失函数。DeepAR 用的是负对数似然,也就是让观测到的真实值在模型预测分布下的概率尽可能大。对于高斯分布,损失写成:

训练完成后进入预测阶段。DeepAR 不再需要真实值,而是从预测分布中采样,把采样值当作下一步输入,循环滚动,生成多条完整轨迹:

阿海用五十年日志换来的“直觉”,在计算机里变成几小时的梯度更新。训练让模型学会的,不只是“下一时刻最可能的值”,更是“下一时刻可能的范围有多大”——这正是概率预测的灵魂。

L=−∑t=t0Tlog⁡p(zt∣θ(ht))\mathcal{L}=-\sum_{t=t_0}^{T}\log p(z_t\mid\theta(h_t))
第 s 条轨迹在第 t+1 步随机抽取一个值,并把该值滚入历史;不同随机种子得到不同轨迹,最终汇总成区间。
  1. 分布采样从预测分布中随机抽取一个值 z̃,而不是直接取均值,保留不确定性。
    z~t+1(s)∼p(z∣θ(ht+1(s)))\tilde{z}_{t+1}^{(s)}\sim p(z\mid\theta(h_{t+1}^{(s)}))
  2. 滚动输入把采样值当成下一步的实际观测,与协变量一起送入 RNN,继续推进。
    ht+1(s)=RNN(ht(s),z~t(s),xt+1)h_{t+1}^{(s)}=\mathrm{RNN}(h_t^{(s)},\tilde{z}_t^{(s)},x_{t+1})
  3. 轨迹汇总重复多次采样得到多条轨迹,再取分位数,得到预测区间与中位数预测。
    {z~t+1(s),z~t+2(s),…,z~T(s)}s=1S\{\tilde{z}_{t+1}^{(s)},\tilde{z}_{t+2}^{(s)},\dots,\tilde{z}_{T}^{(s)}\}_{s=1}^{S}

应用落地:渔港智慧装进行业

阿海的经验不可能只服务一条船。当整个港口的船长都来向他请教时,他的“预测指南”就成了公共基础设施:每条船根据自己的渔网大小、冷库容量、销售渠道,从同一张概率分布图中切出适合自己的区间。DeepAR 在真实行业中的落地,也是同一个模式。

电商需求预测是最典型的场景。一个平台有成千上万个 SKU,每个 SKU 的销量序列各不相同,但都受节假日、促销和季节影响。DeepAR 用多序列共享建模,为每个 SKU 输出销量分位数;仓库据此确定安全库存,既不积压资金,也不轻易断货。能源负荷预测同样受益:电网调度员需要知道“明天下午的高峰负荷可能冲到多少”,而不只是一个平均值,DeepAR 的输出区间让调度更有余量。在运维监控中,DeepAR 对服务器指标做区间预测,当真实值跳出预测区间时就触发告警,比固定阈值更灵敏。这些场景共享同一个数学目标:在给定风险水平下,尽量收紧区间但又不漏掉真实值。覆盖概率可写成:

阿海从不为所有渔船推荐同一种渔网。他给每艘船一张概率地图,让船长们按自己的载重和风险偏好做决策。DeepAR 也一样:它不是一个“自动给答案”的黑箱,而是一台“生产概率地图”的机器,把不确定性管理能力带到每一个需要预测的业务现场。

P(L≤z≤U)≥1−α,L=Qα/2(z), U=Q1−α/2(z)P(L\le z\le U)\ge 1-\alpha,\qquad L=Q_{\alpha/2}(z),\ U=Q_{1-\alpha/2}(z)
L 和 U 是区间两端的分位数,1−α 是置信水平;α 越小,区间越宽,决策越保守。
  1. 区间边界L 取 α/2 分位数,U 取 1−α/2 分位数,两者构成预测区间。
    L=Qα/2(z),U=Q1−α/2(z)L=Q_{\alpha/2}(z),\qquad U=Q_{1-\alpha/2}(z)
  2. 覆盖概率区间包含真实值的概率至少为 1−α,保证预测的统计可靠性。
    P(L≤z≤U)≥1−αP(L\le z\le U)\ge 1-\alpha
  3. 风险调节α 由业务风险偏好决定,缺货成本高就选小 α(更宽区间),库存成本高就选大 α(更紧区间)。
    1−α1-\alpha

AI 应用场景

电商销量区间预测

阶段:预测与决策支持

解决的问题:传统点预测只给单一销量,采购人员要么不敢备货导致缺货,要么超额备货导致库存积压。DeepAR 为每个 SKU 输出销量分位数,采购员直接看“90% 预测区间”就能确定安全库存。

具体案例:某电商平台对 5 万个 SKU 用 DeepAR 联合建模,将节假日、促销日作为协变量,每周输出未来 14 天的分位数预测;大促前根据 95% 分位数提前备货,缺货率下降约 20%,同时库存周转天数未明显恶化。

能源负荷概率调度

阶段:预测与风险调度

解决的问题:电网调度需要知道负荷波动的上限,而非仅仅均值;区间过窄可能引发拉闸限电,区间过宽则浪费发电资源。DeepAR 的概率输出让调度员在“安全”和“经济”之间找到平衡。

具体案例:某区域电网使用 DeepAR 预测未来 48 小时负荷,把温度、节假日作为协变量,输出 90% 预测区间;调度员根据区间上沿安排旋转备用容量,在保证供电可靠性的前提下减少备用机组启停。

运维指标异常检测

阶段:监控与告警

解决的问题:传统固定阈值告警在业务波动大时频繁误报。DeepAR 为每个监控指标生成动态预测区间,真实值越出区间即视为异常,告警更精准。

具体案例:某互联网公司的 SRE 团队用 DeepAR 对数百个服务的 QPS、延迟、错误率做区间预测,当延迟超过 99% 分位数时自动触发告警;相比固定阈值,误报率降低约 40%,且能在流量突增早期发现问题。

Python 演示

python87 行
import numpy as np def make_series(n=200, period=20, seed=7):    rng = np.random.default_rng(seed)    t = np.arange(n)    return np.sin(2 * np.pi * t / period) + 0.1 * rng.standard_normal(n) def make_pairs(x, window=8, horizon=1):    xs, ys = [], []    for i in range(window, len(x) - horizon + 1):        xs.append(x[i - window:i])        ys.append(x[i + horizon - 1])    return np.array(xs), np.array(ys) class SimpleDeepAR:    def __init__(self, window=8, hidden=24, lr=0.05):        rng = np.random.default_rng(0)        self.window = window        self.hidden = hidden        self.lr = lr        self.w1 = rng.normal(0, 0.3, (window, hidden))        self.b1 = np.zeros(hidden)        self.w2 = rng.normal(0, 0.3, (hidden, 2))        self.b2 = np.zeros(2)     def forward(self, x):        h = np.tanh(x @ self.w1 + self.b1)        theta = h @ self.w2 + self.b2        mu = theta[:, 0]        log_sigma = np.clip(theta[:, 1], -3, 3)        sigma = np.exp(log_sigma)        return mu, sigma     def step(self, x, y):        h = np.tanh(x @ self.w1 + self.b1)        theta = h @ self.w2 + self.b2        mu = theta[:, 0]        log_sigma = np.clip(theta[:, 1], -3, 3)        sigma = np.exp(log_sigma)        d_theta = np.zeros_like(theta)        d_theta[:, 0] = (mu - y) / sigma ** 2        d_theta[:, 1] = 1 - (y - mu) ** 2 / sigma ** 2        d_theta /= len(x)        d_w2 = h.T @ d_theta        d_b2 = d_theta.sum(axis=0)        dh = d_theta @ self.w2.T        da = dh * (1 - h ** 2)        d_w1 = x.T @ da        d_b1 = da.sum(axis=0)        self.w1 -= self.lr * d_w1        self.b1 -= self.lr * d_b1        self.w2 -= self.lr * d_w2        self.b2 -= self.lr * d_b2     def train(self, xs, ys, epochs=300):        for _ in range(epochs):            self.step(xs, ys)     def forecast(self, x_last, steps=12, samples=300, seed=1):        rng = np.random.default_rng(seed)        paths = np.zeros((samples, steps))        for s in range(samples):            window = np.copy(x_last)            for t in range(steps):                mu, sigma = self.forward(window[None, :])                v = float(rng.normal(mu[0], sigma[0]))                paths[s, t] = v                window = np.roll(window, -1)                window[-1] = v        return paths def main():    ser = make_series()    xs, ys = make_pairs(ser)    tail = xs[-1]    model = SimpleDeepAR()    model.train(xs, ys)    paths = model.forecast(tail, steps=12, samples=300)    lo = np.percentile(paths, 16, axis=0)    hi = np.percentile(paths, 84, axis=0)    med = np.percentile(paths, 50, axis=0)    print("未来12步预测中位数:", np.round(med, 3))    print("68%预测区间下限:", np.round(lo, 3))    print("68%预测区间上限:", np.round(hi, 3)) if __name__ == "__main__":    main()
目的:演示 DeepAR 的核心思想——“输出分布参数 + 自回归采样预测”,用纯 NumPy 实现高斯似然训练与区间预测。
  1. xs.append(x[i - window:i])构造长度为 8 的历史窗口,这是自回归的“渔获日志切片”。
  2. self.w1 = rng.normal(0, 0.3, (window, hidden))初始化输入层权重,相当于一张随机草稿地图。
  3. sigma = np.exp(log_sigma)对 log σ 取指数,保证标准差永远为正。
  4. d_theta[:, 0] = (mu - y) / sigma ** 2高斯负对数似然对均值参数的梯度。
  5. d_theta[:, 1] = 1 - (y - mu) ** 2 / sigma ** 2对对数方差的梯度,体现“预测不准时主动扩大方差”。
  6. self.w2 -= self.lr * d_w2用梯度下降更新输出层,让地图逐步贴合真实海域。
  7. v = float(rng.normal(mu[0], sigma[0]))从预测分布中采样一个值,而不是直接取均值。
  8. window = np.roll(window, -1); window[-1] = v把采样值滚入窗口,实现自回归滚动。
  9. np.percentile(paths, 16, axis=0)对所有轨迹取 16% 分位数,得到 68% 预测区间下界。

常见误区

误区我原本以为 DeepAR 就是把 ARIMA 的线性计算换成神经网络,本质上还是在预测下一个数值点。

正解ARIMA 输出的是条件均值,预测区间需要额外假设;而 DeepAR 直接输出整个概率分布的参数,天然支持分位数和区间。类比阿海:爷爷的公式只给一个“最可能的数”,阿海则给一张“可能性地图”。DeepAR 的目标函数是负对数似然,优化的是分布,不是均值误差。

为何常见:因为很多入门资料把时间序列预测简化为“预测下一个数”,忽略了概率输出才是 DeepAR 的核心创新。

误区我以为区间预测就是先算一个均值,然后统一加 10% 或减 10%,形成一个固定宽度的条带。

正解DeepAR 的预测区间来自分布的分位数,宽度会随时间步长变化:越往远处预测,不确定性越大,区间越宽。就像渔船越驶向远海,航线的不确定性越大,阿海给出的范围越宽。

为何常见:点预测的思维惯性让人习惯“一个数加一个误差带”,忽略了概率分布本身蕴含了变化宽度。

误区我觉得只要把能收集到的特征全塞进 DeepAR,预测一定更准。

正解协变量必须是预测时“已知”的信息。如果加入未来未知的动态变量,比如“明天的随机价格波动”,训练时模型等于偷看了未来,推理时却拿不到,就会造成训练与推理分布不一致,预测区间严重失真。阿海从不用“明天会不会遇到鱼群”这种未知事件做判断。

为何常见:特征工程中“特征越丰富越好”的直觉被错误套用,忽略了时序预测对“信息时序”的特殊要求。

误区我以为 DeepAR 既然同时学习多条序列,就要求所有序列长度一致,否则无法放到一个矩阵里训练。

正解DeepAR 是逐时间步训练的,不同序列可以有不同的起始时间和长度。模型通过序列嵌入区分个体,缺失的历史段只影响局部损失,不影响整体训练。就像每艘渔船的日志厚薄不同,阿海照样能从所有日志中学到共同规律。

为何常见:从表格数据“一行一条样本”的思维出发,容易误以为网络输入必须是一个整齐的矩形。

误区我以为负对数似然降到很低,说明模型学得很好,预测区间一定可靠。

正解NLL 低只说明“历史数据在预测分布下有较高密度”,但模型可能过拟合,把方差估计得过窄,导致区间过度自信。这就像阿海只熟悉自己那片海域,换个渔场就抓瞎。真正的可靠性要用回测校验:看真实值是否以指定比例落入预测区间。

为何常见:监督学习中“训练误差低=模型好”的惯性思维,在概率预测场景需要额外警惕过拟合带来的方差低估。

面试题

Q1. DeepAR 直接输出的是什么?

单选题 · easy

  • A.一个固定预测数值
  • B.一组分布参数← 正确答案
  • C.一段分类标签
  • D.若干规则表达式

答案:B。DeepAR 输出概率分布的参数,如高斯分布的均值和方差,而不是单一数值。就像阿海给出的是整张“可能性地图”,不是某个确定的渔获数。

Q2. 分位数预测的核心价值是什么?

单选题 · easy

  • A.加速模型训练
  • B.把不确定性变成区间← 正确答案
  • C.压缩历史数据
  • D.替代全部特征工程

答案:B。分位数把概率分布切成可操作的区间,让决策者知道“大概率的范围”,这是点预测无法提供的风险信息。

Q3. “自回归”在 DeepAR 中主要体现在哪里?

单选题 · easy

  • A.用历史预测未来并滚动← 正确答案
  • B.多次重复训练同一模型
  • C.回归到坐标原点
  • D.自动选择回归函数

答案:A。DeepAR 每一步都用上一步观测或采样值作为输入,像接力赛一样把预测结果滚进未来。这与“自己预测自己”的自回归语义一致。

Q4. 下面哪些可以作为 DeepAR 的协变量?

多选题 · mid

  • A.是否法定节假日← 正确答案
  • B.未来促销计划← 正确答案
  • C.未来未知的市场报价
  • D.当前所处星期几← 正确答案

答案:ABD。协变量必须是预测时已知的信息。节假日、促销计划和星期几都能提前确定;未来未知的市场报价无法预知,作为协变量会造成训练与推理不一致。

Q5. DeepAR 输出标准差时,为什么要用指数函数?

单选题 · mid

  • A.保证方差恒为正数← 正确答案
  • B.让网络层数变少
  • C.减少训练样本量
  • D.跳过梯度计算

答案:A。指数函数能把任意实数映射到正数区间,确保标准差永远大于零。这就像阿海给出的范围永远是“从低到高”,不会出现负数渔获。

Q6. 相比 ARIMA,DeepAR 的优势包括哪些?

多选题 · mid

  • A.可以拟合非线性关系← 正确答案
  • B.多序列共享参数← 正确答案
  • C.天然支持协变量← 正确答案
  • D.完全不需要数据清洗

答案:ABC。ARIMA 是线性模型,单序列建模;DeepAR 用循环网络拟合非线性,多序列共享统计强度,并自然接入协变量。但它仍然需要数据清洗和标准化,D 错误。

Q7. 68% 预测区间通常对应哪一对分位数?

单选题 · mid

  • A.0.05 与 0.95
  • B.0.16 与 0.84← 正确答案
  • C.0.01 与 0.99
  • D.0.25 与 0.75

答案:B。正态分布中,约 68% 的概率质量落在均值左右各一个标准差内,对应 0.16 到 0.84 分位数。0.05 与 0.95 给出的是 90% 区间。

Q8. DeepAR 训练时最常使用的损失函数是什么?

单选题 · hard

  • A.均方误差
  • B.负对数似然← 正确答案
  • C.交叉熵损失
  • D.Hinge 损失

答案:B。DeepAR 最大化历史数据在预测分布下的似然,等价于最小化负对数似然。它同时约束均值与方差,让模型在“猜得准”和“不确定时说清楚”之间取得平衡。

Q9. 关于 DeepAR 预测区间,下列说法正确的是?

多选题 · hard

  • A.可以通过分位数获得← 正确答案
  • B.只能由高斯分布导出
  • C.能反映模型的不确定性← 正确答案
  • D.宽度始终保持固定

答案:AC。预测区间从分布的分位数计算;不确定性能通过区间宽度表达,且越远处越宽。DeepAR 也可用负二项等分布,B 错误;宽度固定是点预测的误区,D 错误。

Q10. “教师强制”在 DeepAR 训练中的含义是什么?

单选题 · extreme

  • A.用真实历史观测作为输入← 正确答案
  • B.用模型预测值替代观测
  • C.每个样本配一个教师模型
  • D.训练时冻结部分参数

答案:A。训练时把真实历史观测作为每一步的输入,而不是用模型自己的预测,这叫教师强制。它让训练更稳定,但推理时没有真实值,只能用采样值滚动,因此训练与推理存在分布差异。