小王在巷口开了一家奶茶店,每天打烊后都会在账本上记下今天卖了多少杯。一个月下来,他盯着曲线发呆:周末总是冲高、周二回落、最近仿佛整体在涨,下周还有情人节。他需要的不是“感觉”,而是一个能告诉他“明天备多少料、下周备多少货”的方法。这就是时序模型——专门用“按时间顺序记录的过去”来预测“接下来的走势”的一系列工具。 AI 不会凭空猜未来。它像小王一样,先把账本上的历史拆开揉碎,找出长期趋势、周期波动和意外噪声,再用不同“脾气”的模型去外推。有的模型像只会看昨天账目的老账房先生,有的像经验丰富的店长知道节假日会爆单,还有的像一个能同时把全部账本摊开找关联的分析师。只有知道了它们的擅长与局限,才能真正在业务里选对工具、用对策略。
掌握时序模型是进入需求预测、库存管理等 AI 业务场景的必修课。它能让你面对真实业务数据时,不是机械地套模型,而是像经验丰富的店长一样判断该用哪种预测方法,并解释预测结果的业务含义。
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
时序模型预测对比——ARIMA vs Prophet vs Transformer 实际值:历史销售数据 ARIMA: 线性自回归+滑动平均 Prophet: 趋势+季节+节假日分解 Transformer: 自注意力长距离依赖 y(t) = AR(p) + I(d) + MA(q) | Prophet: g(t)+s(t)+h(t)+e
时序数据基础
小王每天打烊后记下的“今日杯数”,按日期排成一列,就是一条时间序列。表面看只是数字,实际上藏着三重信号:整体是淡季还是旺季(趋势)、每周或每年有没有固定波动(季节)、以及台风天那种不可复制的意外(噪声)。如果小王只盯着某一天的数字,就会把偶然当成必然。
在技术世界里,时间序列就是按时间先后采集的观测值:销量、温度、股价都算。预测之前要先回答三个问题:数据有没有长期抬头或向下?有没有周期性起伏?是不是稳定?这里的“稳定”(平稳性)很像店员的状态——如果店员每天情绪波动范围基本一致,工作表现就可预期;如果情绪越来越暴躁或越来越没规律,就难预测。时间序列也一样,均值和方差如果随时间漂移,就不平稳。
数学上,平稳性用“相隔 k 期的两个观测是否还保持稳定联系”来衡量,这个联系叫自协方差。如果不管站在哪个时间点看,相隔相同步长的相关系数都差不多,模型才敢用历史外推未来。
小王的直觉就是这样:如果“今天卖得好,明天大概率也不错”这个规律在过去 100 天都成立,老账房先生就敢据此预测。时序预测的第一步,就是先把这种“规律是否稳定”量化出来。
- 符号 γ(k)希腊字母 γ 表示“相隔 k 期的自协方差”,描述两期数据之间的连带关系强度。
- Cov 协方差Cov 是协方差运算,正数表示两项同向波动,负数表示反向波动,接近 0 表示无明显线性关系。
- y_t 与 y_{t+k}前者是第 t 时刻的观测,后者是往后数 k 个时间单位的观测,二者处在同一条时间轴上。
ARIMA 原理
老账房先生记了几十年流水,他的预测方法很朴素:明天的销量 ≈ 今天的销量 + 今天比昨天的变化 + 一点运气。如果变化本身也有规律,他就把“变化的变化”继续套进去。这种“用昨天的数推今天的数”的思路,就是 ARIMA 的核心。
ARIMA 的三个字母像三块积木。AR 代表“自回归”,把过去的观测值拿来做线性组合;I 代表“差分”,专门把越来越不稳的序列“铲平”;MA 代表“移动平均”,把过去的预测误差也纳入公式。合并起来,ARIMA(p,d,q) 中的 p、d、q 分别对应 AR 阶数、差分次数、MA 阶数。业务中如果数据没有强节假日、量不大、趋势相对线性,ARIMA 常常是稳健的首选,实践中还会用 AIC 这类指标在复杂度和拟合优度之间做权衡。
为了讲得不吓人,我们看最常用的 ARIMA(1,1,1)。先做一次差分得到 Δy_t,然后用上一期的 Δy 和上一期的预测误差来解释当期的变化。
老账房先生的账本说不清情人节会爆单,但能告诉他“最近涨势有没有延续”。ARIMA 的优势是透明、计算快、小样本也够用;代价是它对季节、节假日这类外部冲击比较迟钝,所以还要看后面的 Prophet 和 Transformer。
- Δy_t 一阶差分把相邻两期做差,相当于把“水平”变成“变化”,很多不稳定序列会因此变稳。
- φ₁Δy_{t-1} 自回归项φ₁ 是权重,表示上一期变化对本期变化的影响;如果影响显著,说明存在惯性。
- ε_t + θ₁ε_{t-1} 误差调整ε_t 是本期随机误差,θ₁ε_{t-1} 表示把上一期没预测准的部分也作为参考,让模型自己纠偏。
Prophet 原理
店长比账房先生更进一步:他不仅看每天的流水,还知道周五下班后人多、暑假学生多、情人节要提前备料。Prophet 就是这样一个“懂业务日历”的模型,它把时间序列拆成长期趋势、周期季节和节假日三部分,再相加得到预测值。
Prophet 是 Meta 开源的商业预测工具,特别适合零售、电商这种有明确季节和节假日的场景。它对缺失值和异常值处理得比较宽容,业务人员也能看懂每个部分在说什么。公式很直白:未来销量 = 大趋势 + 季节规律 + 节假日效应 + 随机噪声。
对小王来说,Prophet 就像一个提前看了日历的店长:它能告诉小王“情人节当天销量会跳到日常的 2 倍”,而且还能给出不确定性区间,让备货计划留出安全垫。
- y(t) 预测量模型在时间 t 给出的销量或需求预测值,是所有成分叠加后的结果。
- g(t) 趋势项描述长期向上或向下的走向,比如门店所在的商圈越来越旺。
- s(t) 季节项描述周、月、年等固定周期的波动,比如周末比工作日多卖三成。
- h(t) 节假日项专门处理节日、大促等一次性的可预期冲击,是 Prophet 最实用的设计之一。
Transformer 建模
如果说 Prophet 是经验丰富的店长,Transformer 更像一个把十年账本同时摊开在桌上的数据分析师。它不按时间先后逐页读,而是让每一个时间点都和所有其他时间点做对比,直接找出“哪天和哪天最像”。这种“全局关联”能力,使它非常适合数据量大、影响因素复杂、长期依赖明显的场景。
Transformer 最初用在机器翻译,后来被引入时间序列预测。它先给每个时间点加上位置编码,让模型知道先后顺序;再用自注意力机制计算两两时间点之间的相关性;最后通过编码器和解码器输出未来几步的预测。自注意力的核心公式如下。
对小王的团队来说,只有当历史数据积累到足够多、天气和促销等变量也要一起参与时,Transformer 才会明显跑赢前面的传统方法。数据不足时硬上深度学习,就像请了数据分析师却只给三天账本,发挥不出优势。
- Q、K、V 三个角色Q 代表当前时间点的查询需求,K 代表其他时间点的检索标签,V 代表真正要提取的内容。可以把它理解成去图书馆找书:Q 是书名关键词,K 是书目索引,V 是书里的正文。
- QKᵀ 相关度矩阵把查询与索引做内积,得到“此刻与彼刻有多相关”的原始分数矩阵。
- softmax 归一化把所有相关分数转成非负且总和为 1 的权重,让模型只强调最相关的少数时间点。
- √d_k 缩放d_k 是每个向量的维度,除以它的平方根是为了防止分数过大,让梯度更稳定。
季节性分解
小王想进一步弄清楚:这杯销量里,到底多少是“铺子本身该有的”,多少是“季节给的”,多少是“纯属运气”?季节性分解就是干这件事的。它把一条原始序列拆成可以解释的部件,就像把一杯奶茶拆成底料、奶盖和珍珠。
季节分解有两种常见配方。加法模型认为“底子 + 季节波动 + 噪声”只是简单相加,适合季节波动幅度不随业务量变化的情况;乘法模型认为“季节是给底子乘一个系数”,比如旺季卖得好,波动的绝对值也随之放大,这在零售中更常见。实际工具中常用 STL 分解,它能灵活提取趋势和季节成分,并帮助我们识别周期。
看完分解,小王会恍然大悟:原来某天销量暴跌不是经营出了问题,而是那天本来就只有日常的八成,再叠加一场大雨。分解让预测不再是黑盒,也让企业能更准确地把“策略效果”和“季节运气”分开。
- y_t 原始观测第 t 天实际记录的销量或业务指标。
- T_t 趋势项去掉波动后留下的长期水平,反映业务的基本盘。
- S_t 季节系数围绕 1 波动的乘数,大于 1 表示旺季,小于 1 表示淡季。
- R_t 随机噪声无法由趋势和季节解释的偶然因素,比如突然下雨或设备故障。
外部变量引入
小王逐渐发现,只看自己账本还不够。天气预报说明天降温,线上平台要搞“第二杯半价”,隔壁还在修路——这些都不在过去的销量历史里,却会实实在在影响明天。于是他把这些因素也写进模型,这就是外部变量引入。
外部变量也叫外生变量,常见的有节假日、促销活动、天气温度、广告投放、客流人数等。ARIMA 把这类变量加进去就变成 ARIMAX;Prophet 本身支持节假日回归量;Transformer 则能把多个协变量拼进输入特征。关键是:预测未来时,外部变量本身也得是提前可预知的,比如促销日历可以排好,但“未来一周的真实天气”只能靠预报。
小王把“是否促销、天气温度、节假日”做成三列特征后,模型准确率明显提升。外部变量让预测从“只靠惯性”变成“结合现实”,这是零售预测项目里效果提升最快的杠杆之一。
- β₀ 截距项没有任何外部变量影响时的基础销量水平。
- β_i x_{it} 变量贡献第 i 个外部变量的取值乘以权重,权重越大说明它越能左右销量。
- η_t 误差项被遗漏的随机因素,模型不可能解释一切。
多步与选型
小王虽然很想知道明天的销量,但真要准备一周的原料,他需要的是未来 7 天的预测。这就是多步预测。递归预测是一步一步往后推:先预测第 1 天,把预测值当作已知数再预测第 2 天,缺点是误差会像滚雪球一样越滚越大。直接预测则是为每一天分别训练一个模型,虽然更费功夫,但能避免误差累积。Transformer 这类模型还可以一次输出未来多个时间点,叫多输出预测。
选模型时没有“万能药”。小样本、线性趋势、没有复杂节假日的场景,ARIMA 便宜又可靠;有明显季节和节假日、还需要解释业务含义的场景,Prophet 更合适;数据量大、特征多、需要捕捉长期依赖的场景,Transformer 才有优势。为了让选择不靠感觉,业界通常用 MAPE 这类指标做性能基准。
小王最后给自己定了一套规矩:先做季节分解看懂数据,再按业务目标选模型,最后用 MAPE 对比几个候选方案。时序预测不是比哪个模型更高深,而是比哪个方法在当下场景最划算。
- A_t 与 F_tA_t 是第 t 天的实际销量,F_t 是模型给出的预测值。
- 相对误差项用差值除以实际值,减少不同门店规模对误差比较的影响。
- 平均与百分比对所有天求和后取平均,再乘以 100%,得到容易向业务汇报的百分比误差。
AI 应用场景
零售门店补货预测
阶段:需求预测与库存优化
解决的问题:传统人工备货依赖店长经验,遇到季节和节假日容易缺货或积压。AI 用门店历史销量结合节假日特征,预测未来 7 天销量,把“凭感觉”变成“按数据”。
具体案例:一家连锁便利店对每家门店独立训练 Prophet 模型,输入过去三年的销量、周末标记和节假日表,输出未来一周每日销量预测及区间,自动生成订货建议。
电商大促销量预测
阶段:促销规划与营销投放
解决的问题:大促期间销量受折扣力度、广告流量、加购人数等多重外部因素影响,简单移动平均完全失效。AI 把这些外生变量与历史销量一起喂给模型,才能捕捉瞬时爆发。
具体案例:某美妆电商在双十一前,将促销折扣率、广告点击量、预售加购数作为外部变量,用 Transformer 预测大促首小时销量,并动态调整各渠道广告预算。
连锁餐饮节假日排班
阶段:人力计划与运营调度
解决的问题:春节、情人节等节点的客流波动大,排班多了浪费人力,排班少了影响体验。通过季节分解把客流拆成“日常底子 + 节日加成”,再结合门店特征做预测。
具体案例:某连锁餐饮品牌用 STL 分解加回归模型,预测所有门店未来两周的时段客流,自动生成排班建议和原料采购清单。
Python 演示
class SeasonalForecast: def __init__(self, periods=12): self.periods = periods self.trend_slope = 0.0 self.trend_intercept = 0.0 self.obs_count = 0 self.seasonal = [] self.season_sums = [0.0] * periods self.season_counts = [0] * periods def fit(self, values): self.obs_count = len(values) n = self.obs_count t = list(range(n)) mean_t = sum(t) / n mean_y = sum(values) / n s_ty = sum((t[i] - mean_t) * (values[i] - mean_y) for i in range(n)) s_tt = sum((t[i] - mean_t) ** 2 for i in range(n)) self.trend_slope = s_ty / s_tt if s_tt != 0 else 0.0 self.trend_intercept = mean_y - self.trend_slope * mean_t for i, v in enumerate(values): trend = self.trend_intercept + self.trend_slope * t[i] diff = v - trend p = i % self.periods self.season_sums[p] += diff self.season_counts[p] += 1 self.seasonal = [ self.season_sums[p] / self.season_counts[p] if self.season_counts[p] else 0.0 for p in range(self.periods) ] def predict(self, steps): result = [] for h in range(1, steps + 1): idx = self.obs_count + h - 1 trend = self.trend_intercept + self.trend_slope * idx season = self.seasonal[idx % self.periods] result.append(trend + season) return result if __name__ == "__main__": sales = [120, 132, 118, 140, 155, 160, 170, 165, 150, 145, 160, 180] model = SeasonalForecast(periods=12) model.fit(sales) preds = model.predict(3) print("未来3个月预测销量:", [round(p, 1) for p in preds])
class SeasonalForecast:定义了一个可复用的季节预测模型类,适合小白理解整体流程。self.trend_slope = 0.0保存线性趋势的斜率,fit 之后会被历史数据更新。self.season_sums = [0.0] * periods按周期位置累计季节偏差,这是季节成分的“统计台账”。s_ty = sum((t[i] - mean_t) * ...计算时间与销量的协方差,用于求趋势线的斜率。diff = v - trend去掉趋势后的残差,里面主要剩下季节和随机成分。self.seasonal = [...]把每个月累计的偏差取平均,得到每个周期位置的季节因子。idx = self.obs_count + h - 1预测未来第 h 步时,要用历史之后的时间序号计算趋势。result.append(trend + season)预测值等于未来趋势加上对应季节因子,这就是加法分解的预测。
常见误区
误区我以为不管用什么模型,第一步都必须把销量数据差分到平稳,否则模型不能用。
正解只有 ARIMA 这类基于自相关统计的模型才严格要求平稳性。Prophet 自己会拟合趋势和季节,Transformer 也能直接学习复杂模式。对它们做差分反而可能丢掉有用的长期信息。正确做法是先定模型,再按模型要求做数据处理。
为何常见:因为许多教材从 ARIMA 讲起,差分和单位根检验给人留下了“必经步骤”的强烈印象。
误区我习惯用回归里的 R² 看预测准不准,数值越接近 1 就说明模型越好。
正解时序预测更看重误差随时间的表现,常用 MAPE、RMSE、MAE。R² 在时序里容易虚高,因为趋势本身就能解释大部分变动;而且它无法暴露“预测总是慢半拍”的问题。业务中真正关心的是“平均偏多少”,而不是“解释了多少方差”。
为何常见:因为很多人在学机器学习时先接触回归评估指标,直接迁移到了时间序列。
误区我总觉得深度学习一定碾压传统统计方法,所以所有预测都用 Transformer。
正解模型效果取决于数据量、特征质量和业务场景。小样本、线性趋势、无强节假日的场景,ARIMA 又快又稳;强季节和节假日场景,Prophet 可解释性更好;只有数据量大、特征丰富、长期依赖明显时,Transformer 才能体现出优势。盲目上大模型只会增加成本且难以调试。
为何常见:媒体和开源项目推高了深度学习的“光环”,让人忽略了统计模型在小场景中的实用性。
误区我为了让程序简单,预测第 2 天时把第 1 天的预测值当真实值继续算,以为结果不会有问题。
正解这种递归策略会让误差像滚雪球一样累积,多步之后预测可能严重偏离。更稳妥的做法是直接为每步训练模型,或用多输出模型一次生成整段预测。真实项目里还应评估不同步长的误差衰减速度。
为何常见:递归写法最简单,且人们在入门时容易忽略误差传播的数学直觉。
面试题
Q1. 下列哪一项最符合时间序列的定义?
- A.按时间顺序记录的观测值集合← 正确答案
- B.按地理位置排列的采样数据
- C.无顺序关系的随机样本集合
- D.只包含一个变量的数据集
答案:A。时间序列的核心是“按时间排序”,比如每天的销量、每小时的气温。地理位置排列是空间数据,随机样本不是序列,单变量也不一定是时间序列。
Q2. 判断序列平稳时,最主要看什么?
- A.均值和方差是否随时间保持稳定← 正确答案
- B.数据是否一定呈上升趋势
- C.是否只有一个季节周期
- D.预测误差是否为常数
答案:A。平稳性要求统计性质不随时间漂移,最典型的就是均值和方差稳定。持续上升或方差变大都是非平稳信号。季节周期并不破坏平稳性,只要波动模式稳定即可。
Q3. ARIMA 中的字母 I 表示什么?
- A.通过差分处理非平稳序列← 正确答案
- B.将数据取对数变换
- C.使用自回归项拟合
- D.增加移动平均窗口
答案:A。ARIMA 中 A 是自回归,I 是差分,MA 是移动平均。差分的作用正是把非平稳序列变得平稳,让模型可以用历史规律外推。
Q4. ARIMA(1,1,1) 中第三个数字代表什么?
- A.移动平均的阶数← 正确答案
- B.自回归的阶数
- C.差分的次数
- D.季节周期的长度
答案:A。ARIMA(p,d,q) 的三个数字分别对应自回归阶数、差分次数、移动平均阶数。因此第三个数字 1 表示 MA(1),即过去一期的预测误差会被纳入模型。
Q5. Prophet 模型通常把时间序列拆分为哪些部分?
- A.趋势项 g(t)← 正确答案
- B.季节项 s(t)← 正确答案
- C.节假日项 h(t)← 正确答案
- D.差分项 d(t)
答案:ABC。Prophet 的核心公式是 y(t)=g(t)+s(t)+h(t)+ε,趋势项、季节项、节假日项是它的三个组件。差分是 ARIMA 里的操作,不属于 Prophet 的分解结构。
Q6. 自注意力公式中的 softmax 有什么作用?
- A.把注意力分数转成权重之和为 1 的概率← 正确答案
- B.增加模型的参数量
- C.把输入压缩成低维向量
- D.把时间序列变成平稳序列
答案:A。softmax 能把任意实数分数变成非负且总和为 1 的权重,让模型“重点看哪儿”更明确。它不改变维度,也不做平稳化。
Q7. 乘法季节分解模型 y = T × S × R 中,S 表示什么?
- A.季节因子,随季节周期性变化← 正确答案
- B.随机误差项,代表不可控波动
- C.长期趋势项,代表整体走向
- D.外部变量项,代表促销影响
答案:A。在乘法模型里,S 是季节因子,围绕 1 波动:旺季大于 1,淡季小于 1。随机误差是 R,长期走向是 T,外部变量并不是该式的一部分。
Q8. 以下哪些可以作为时序预测的外部变量?
- A.节假日与促销活动计划← 正确答案
- B.天气与温度等环境数据← 正确答案
- C.未来一周的实际销量
- D.商品价格与广告投放量← 正确答案
答案:ABD。外部变量必须是与预测目标相关且能提前或同步获取的信息,如节假日、天气、价格、广告。未来一周的实际销量属于预测目标本身,不能作为输入,否则就是数据泄漏。
Q9. 多步预测中“递归策略”最大的问题是什么?
- A.预测误差会不断累积放大← 正确答案
- B.无法利用任何历史数据
- C.只能预测一个时间点
- D.要求数据严格平稳
答案:A。递归策略把上一步的预测值当作下一步的输入,一旦预测有偏差,误差会连续传递、逐步放大。直接预测和多输出预测就是为了缓解这一问题。
Q10. 关于 Transformer 的位置编码,正确的说法有哪些?
- A.为模型注入每个时刻的顺序信息← 正确答案
- B.和自注意力机制共同工作← 正确答案
- C.只能使用固定的正弦编码
- D.可学习的位置编码也很常用← 正确答案
答案:ABD。自注意力本身不区分先后顺序,位置编码负责补充顺序信息,二者互补。固定正弦编码和可学习位置编码都是常见方案,因此“只能使用正弦编码”的说法过于绝对。