ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

时间序列预测入门:从销售预测到趋势、季节与基线模型

时间序列预测入门:从销售预测到趋势、季节与基线模型

时间序列预测这几年几乎成了数据分析、机器学习入门绕不开的话题。不管你是做电商运营、门店管理,还是刚转行学数据科学,最后都会碰到同一类需求:根据过去的数据,估算下个月、下一周的销量、流量或者库存需求。而“时间序列预测”这个术语,听起来挺唬人,实际它要回答的问题特别朴素——过去规律地发生的事,接下来会不会继续以某种规律发生?

这篇内容适合完全零基础的朋友,也适合那些已经会跑一些模型但没想明白原理的新手。我尽量不说教科书黑话,就用股票价格、门店销售这种最常见的例子,把“什么是时间序列”以及“怎么开始做一个能用的预测”讲清楚。

1. 什么是时间序列:一切预测的原点

1.1 有顺序的数据才有“故事”

先做一个小实验。我给你两组数字:

第一组:23, 45, 12, 67, 34, 89, 56, 78
第二组:12, 15, 13, 14, 16, 15, 17, 18

表面上看,都是七八个数字,没什么特别。但如果我告诉你,第二组是某家奶茶店连续八个月的销售额(单位千元),你会立刻发现:整体在往上走,从12到18,中间还有小幅波动。

这种“知道时间顺序之后,数字就产生了额外含义”的数据,就是时间序列。它的核心定义只有一条:每一个数据点都对应一个确定的时间刻度,并且先后顺序不能随意打乱。普通表格里行的顺序可以随便排,但时间序列一旦打乱,趋势、周期、相关性就全没了,等于毁掉数据。

时间序列的第一个特征是有序性。第二个特征是相邻数据之间经常有相关性——今天卖得多,明天往往也卖得多;这个月库存紧张,下个月进货计划也跟着紧张。这种“自己影响自己”的性质,叫作自相关性,是预测能成立的根本原因之一。

提示:判断一组数据是不是时间序列,先问两个问题——有没有时间戳?打乱顺序后还有没有分析价值?只要有一个答案是“是”,你就该按时间序列来处理。

1.2 时间序列和普通数据的根本区别

做常规机器学习时,我们默认样本之间是相互独立的。比如预测某个用户会不会续费,用户A和用户B之间没有天然的顺序关系;同一个人每个月的数据,也不会因为“这个是上个月、那个是这个月”就必须按顺序处理。

但时间序列完全反过来:样本之间的顺序本身就是信息。上周的销量会影响本周,淡季会规律地出现在每年同一个月,节假日前会突然放量。这些模式藏在先后关系里,普通表格模型很难直接学到。

另一个重要区别是时间间隔。一个序列是“每天一条记录”还是“每小时一条记录”,决定了你能预测的最小粒度,也决定了模型的复杂度。日粒度可以用相对简单的统计模型,小时粒度往往要考虑日内周期性,分钟粒度如果还要做实时,基本就进入工程系统范畴了。入门阶段不用考虑太细,你只需要搞清楚:手头数据的采样间隔是固定的吗?有没有缺了某几天没记录?这些都会直接影响后续建模。

用一个比喻来收束:普通数据分析是在看“一群人的合影”,每个人是一个样本;时间序列分析是在看“一个人的成长纪录片”,每一帧都连着前一帧,单独抽出来就没法理解剧情。

2. 股票价格与销售预测:两个经典场景的差异

2.1 股票预测为什么是入门者的坑

标题里把“股票价格”放在前面,很直观,但我要先泼一盆冷水:股票价格是最不适合新手拿来入门时间序列的数据之一。

原因是它的信噪比太低了。所谓信号,就是数据里那部分可预测的、有规律的成分;噪声,就是随机扰动。股票价格受政策传闻、市场情绪、突发事件影响极大,可预测的规律成分非常微弱,大部分波动近乎随机。拿这种数据练手,你会发现模型在训练集上表现得还行,一到真金白银的预测就露馅,因为其准确率和掷骰子差不了多少。

不是说股票类时间序列完全不能做,而是它需要非常强的金融知识和大量特征工程,还要接受预测误差巨大的现实。这不是一个新手应该用来建立信心的场景。

2.2 销售预测为什么是最好的入门教材

和股票相反,销售数据是最适合入门的时间序列。

第一,销售数据有明确且稳定的业务节奏。门店周一到周五人少、周末人多,电商平台有促销日,奶茶店夏天是旺季、冬天相对冷清。这种季节性和周期性虽然会有波动,但总体规律清晰,初学者很容易在图上“看”出来。

第二,预测误差的接受度较高。库存备多备少虽然也有成本,但你不会因为预测错了几个数字就倾家荡产。你可以放心试错,看看不同方法差多少。

第三,销售数据有清晰的因果可解释性。价格调整、促销活动、天气变化,都会直接影响销量。你可以慢慢加入这些外部因素,理解“为什么预测得准或者不准”,而不是像股票那样纯靠运气。

一句话总结:股票价格适合用来理解“最难的时间序列长什么样”,销售预测适合用来学习“怎么把时间序列做出来并且做对”。新手阶段,请优先找销售、客流、用电量、天气温度这类规律性较强的数据入门。

2.3 从场景需求反向理解模型选型

不同场景对预测的需求差异很大,这也是选模型前必须想清楚的事。

如果你是给连锁超市做订货,核心需求是“下个月各门店分别进多少货”,这属于点预测,精度要求也不苛刻,允许有合理误差区间,传统的统计方法就够了。但如果你是给电力调度中心做用电负荷预测,误差大了可能影响电网运行策略,那就需要分位数预测、概率预测,甚至要部署实时推理系统。

再看时间尺度。销售预测通常做周、月级别,数据粒度也是日或周,样本量往往几百条起步,这种规模用复杂深度学习模型纯粹是杀鸡用牛刀。股价预测短期的有分钟级、小时级,长期的有季度级,但无论哪种尺度,难点都在于可预测性弱,而不是数据量不够。

我现在看到太多人一上来就学Prophet、LSTM、Transformer,问我哪个模型更准。我一般反问:你数据有多少?预测目的是什么?有没有周期性?这三个问题答不上来,用什么模型都是白搭。确定场景需求,永远排在确定算法之前。

3. 拆开时间序列的“骨架”:趋势、季节与噪声

3.1 趋势成分

时间序列可以分解成几个叠加的部分,这是入门必须建立的心智模型。第一个成分是趋势(Trend),代表长期移动方向。

比如一个刚开业的烘焙店,前六个月的销售额从3万慢慢涨到6万,这就是上升趋势;一家线下书店的销售额连续三年下滑,这是下降趋势;还有一个公司的订单量在某个区间来回震荡但看不出明显升降,那就是没有趋势(或者趋势很平缓)。

识别趋势有个很土但有效的方法:直接画折线图,看整体走向;或者算移动平均,把短期波动抹平后看曲线的斜率。不要一开始就用复杂的分解算法,肉眼看图虽然主观,但能帮你建立第一直觉。等你需要做定量报告,再考虑用线性回归或Hodrick-Prescott滤波这类方法提取趋势项。

3.2 季节性成分

第二个成分是季节性(Seasonality),指在固定时间间隔内重复出现的波动。这个“间隔”可以是年、月、周甚至一天内的时段。

举个例子。某家连锁火锅店的数据,每年12月到次年2月生意最好,6到8月明显清淡,这个以年为单位的重复波动就是年度季节性。一家写字楼楼下的便利店,工作日午餐时段销售额出现尖峰,周末反而平淡,这是以周甚至小时為单位的季节性。

这里有个容易混淆的点:季节性不等于“某段时间恰好高”。它必须是在多个周期内稳定重复出现的模式,至少要有两到三个完整周期的数据才能判断。你手上只有14个月的销售数据,说“每年5月是高峰”,其实只看到了一个5月,可信度是存疑的。

注意:季节性周期长度取决于你的业务节奏。没有固定周期,硬套12个月或7天的季节参数,一样会得到假信号。判断周期最靠谱的方法是业务经验加肉眼观察,而不是直接交给算法。

3.3 噪声与平稳性

第三个成分是噪声(Noise),也就是去掉趋势和季节之后剩下的随机波动。它无法用规律来预测,但你可以通过观察噪声的大小判断数据的“可控程度”。

如果一个序列的噪声很大,即使趋势和季节都拆出来,预测误差依然会很大。相反,像电风扇的月度耗电量这种数据,噪声很小,预测自然准得多。噪声的大小通常用标准差或残差的波动幅度来衡量。

顺着噪声自然会引出“平稳性”这个概念。平稳性简单说就是:统计性质不随时间改变。均值大致稳定,方差大致稳定,没有明显的趋势和周期,这样的序列叫平稳序列。为什么要强调这个?因为不少经典的统计模型——比如ARIMA模型——要求输入数据平稳,如果不平稳,就需要先通过差分等方法把趋势剔除,再做建模。

你现在只需要知道:建模之前,先确认数据平稳与否;不平稳的数据,很多算法会把它那部分可预测的“确定性信息”当成噪声丢掉,或者产生虚假的回归关系。入门阶段理解到这里足够,差分、单位根检验这些细节等真正用模型时再细学。

4. 新手入门实操:从零搭建一个销售预测基线

4.1 数据准备

光说概念没用,我们动手做一个最小可行的预测流程。为了清一色地避坑,我用一个模拟场景:某线下零售门店过去24个月的饮料月销售额,单位是万元。数据本身是我虚构的,但形态和真实门店数据高度相似。

这份数据的特点很典型:整体有缓慢上升趋势,夏季(6-8月)销量偏高,冬季偏低,还带一点随机波动。

第一步是数据清洗。时间序列的清洗跟普通表清洗不一样,你最需要关心的是时间索引是否正确连续。检查一下:有没有缺失日期?有没有重复记录?有没有明显的异常值(比如某个月销量骤降为0,大概率是系统故障而非真实经营)?

对有缺失的月份,入门阶段我建议先用前后均值补一下,或者用上一个周期的同期值补。比如6月缺失,可以用去年6月的数值填充。这个处理不完美,但比直接丢掉强——时间序列中断后,后续所有周期计算都会错位。

4.2 先做基线预测:朴素法、移动平均、指数平滑

新手最常犯的错是一上来就想用机器学习模型。正确的打开方式是先做基线(Baseline)。基线方法很简单,却能告诉你“问题到底有多难”。

观察这24个月的销售额序列,呈现出明显的季节循环,因此我们要用与季节匹配的基线模型。第一个基线是朴素季节预测:预测本月销量,直接取去年同月销量。比如你预测第19个月,就用第7个月的实际销量。

第二个基线是移动平均,适合没有明显季节性但需要平滑噪声的数据。比如三月移动平均,就是用前三个月实际销量的均值作为本月预测:

import pandas as pd sales = [23, 25, 22, 26, 28, 30, 27, 29, 33, 31, 32, 35, 34, 36, 33, 35, 38, 40, 37, 39, 43, 41, 42, 45] df = pd.DataFrame({'month': range(1, 25), 'sales': sales}) df['ma3'] = df['sales'].shift(1).rolling(3).mean().shift(-1)

这里用了shift(1)表示只用过去数据,防止未来数据泄露,同时再用shift(-1)让预测值对齐到预测目标位置。移动平均的问题在于它天生滞后,序列上升期它总是追不上下期真值,下降期又高估,只能作为粗糙基准。

第三个经典基线是简单指数平滑:给近期数据更大的权重,给远期数据更小的权重。核心参数是平滑系数alpha,选得越大,模型越敏感,越容易跟着短期波动乱跑;选得越小,曲线越平滑,但对新变化反应越慢。调试时把它当作一个0到1之间的旋钮就好。

4.3 评估指标:MAE、RMSE、怎么选

有了多种预测结果,怎么判断谁好谁坏?最直观的指标是平均绝对误差(MAE),公式很简单:把所有预测值和真实值的绝对差相加,再除以样本数。它解释起来方便,直接说“平均每个月的预测偏差不到2万元”就够了。

另一个常见指标是均方根误差(RMSE)。和MAE的区别在于它先求平方再开根号,会让大误差得到更重的惩罚。如果你的业务场景里,预测偏差5万比偏差1万严重得多,那RMSE比MAE更合适。

我建议入门阶段都算出来,同时看。如果RMSE明显大于MAE,说明存在少数月误差特别大,你要去查那些月份发生了什么——很可能就是促销月或者异常事件月。

评估预测时还有个大坑:你必须用“预测期”的数据来评估,而不是“拟合期”的数据。也就是说,模型训练时用前18个月,评估时用后6个月,这叫留出验证。如果你让模型边学边预测同一个时间段,结果会虚高得离谱,因为它已经“见过答案”了。

4.4 后续提升思路

基线建立后,你再决定要不要用更复杂的模型。提升方向有两条,一条是强化时间结构本身的建模,比如用简单指数平滑的加季节版Holt-Winters方法;另一条是加入外部特征,比如促销标记、温度、节假日天数、门店营业天数。

我见过不少团队的实践经验:当一个销售数据集同时存在趋势、季节和节假日效应时,用好Holt-Winters这类经典统计模型,效果已经能超过很多“半吊子”训练出来的神经网络。经常是先把统计模型做到最佳,再考虑要不要上机器学习。

记住,时间序列问题的提升空间在特征和业务理解上,而不在算法参数。同样是销售预测,加入未来有没有促销活动这个信息,提升幅度可能比换一个高级模型大得多。

5. 常见问题与排查技巧实录

5.1 数据泄露:看似不明显的未来信息

新手做时间序列预测,最容易踩的坑根本不是模型选错,而是数据泄露。什么叫数据泄露?就是你的模型在预测的时候,偷偷用到了未来才能知道的信息。

最典型的例子:用全年销售数据做特征,然后用同一年的后几个月做测试。特征里包含了下半年的数据,模型当然“预测”得很准,但实际部署时根本不可能提前知道未来。这类问题在加入滚动统计特征(比如过去7天均值、过去30天总和)时更隐蔽——如果不小心用shift(0)而忘了用shift(1),当天的数据就会同时出现在特征和标签里,模型直接“开卷考试”。

我的排查经验是:构造特征后,仔细检查“这个特征在当前预测时刻,是否真的已经发生”。不确定的时候,画出特征时序图,人工核对边界,别过度相信代码逻辑。

5.2 预测步长与滚动预测的认知

另一个高频问题是把单步预测误当成多步预测。你在构建训练样本时,如果用过去3个月预测第4个月,这是单步预测。但实际业务要的是“下个月、下下个月、下下下个月各自的销量”,这叫多步预测,难度完全不同。

多步预测有个常见误区:用“预测值”迭代地预测下一步,结果误差会像滚雪球一样累积。比如预测第5个月时用第4个月的预测值做输入,第6个月又用第5个月的预测值……几轮下来,预测结果可能严重偏离真实值。

入门阶段的替代方案有两种:一是直接训练多输出模型,同时预测未来多个月的销量,避免误差累积;二是用递归方式滚动预测时,清楚知道误差会随着步长增加而扩大,并对业务方说明这件事。

5.3 短期序列如何避免过度解读

如果你只有12个月的数据,还有明显的夏季高峰,那么你其实只观测到了一个完整年度的周期,无法确认这个“季节性”是否稳定。如果只有6个月数据,连季节性都谈不上,只能做趋势加噪声的分析。

遇到这类数据,我建议采用更简单的模型:月度数据量不足时,可以转为周粒度聚合;序列太短就减少预测目标,比如从预测12个月降到预测3个月。不要试图用复杂模型挖掘数据中不存在的模式,那是过度拟合。

5.4 关于异常值处理的补充

销售数据里的异常值有两种:一种来自于业务真实事件,比如某天门店开业庆典,销量翻了三倍;另一种来自于数据记录错误,比如系统漏单导致当日销量为0。前者是真实业务信息,处理策略是保留下并标记出来,后续做特征时纳入“是否活动日”;后者是脏数据,应该修正或者剔除。

很多教程会教你用3倍标准差识别异常值,然后一律替换成均值。这个做法看起来很标准,但在时间序列里非常危险——一个真实促销日会被当成异常值清洗掉,你丢失的恰恰是最重要的业务信号。我的习惯是:异常值出现时先核实日期,问业务方当天发生了什么,再决定处理方式。先理解,再动手。

动手前请先想清楚这三件事

讲到这里,关于时间序列入门该有的基础框架已经铺完了。我知道很多朋友看完仍然会急着找代码跑模型,但我真心建议你先停下来,回答自己三个问题:数据是按照固定频率采样的吗?序列里有明显趋势或季节吗?预测结果是被谁、用来做什么决策的?

把这三个问题想清楚,再回头选择模型,你会发现所谓的“深度学习还是统计模型之争”在很多实际场景里根本不重要。我个人的体感是:时间序列入门真正难的不是算法,而是能不能理解数据背后的业务节奏,并且诚实地面对预测的不确定性。你先从销售预测这类规律性强的数据开始,把基线、评估、特征监控的流程跑通,后面再碰复杂的场景,心里就踏实得多。

至于开头提到的股票价格,我的建议是放一放。等你能把销售数据做到“预测误差可解释、业务能接受”的程度,再回头挑战高噪声数据也不迟。预测这条路没有捷径,但有一条真正高效的路——先从最有规律的数据开始,把基本功打扎实,之后遇到任何时间序列,你都知道第一步该做什么。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进