跳至主要内容

SARIMA:季节性时间序列预测完整指南

了解 SARIMA 如何扩展 ARIMA 以处理季节性,理解其七个参数,并在 Python 中从数据收集到预测构建可用模型。
· 15分钟 阅读

使用 AI 探索

每年 12 月,零售商都会为节日季备货。每到夏季,电网都要为空调用电高峰做准备。这些模式年复一年地重复出现。如果您在构建时间序列预测时忽略了它们,就会白白损失精度。

季节性自回归积分滑动平均模型(简称 SARIMA)在广泛使用的 ARIMA 框架之上扩展,能够在捕捉常规趋势的同时建模重复出现的季节性模式。本文将介绍什么是 SARIMA、其各组件如何工作、何时应优先于 ARIMA 选择 SARIMA,以及如何在 Python 中按步骤构建一个模型。

什么是 SARIMA?

SARIMA 是一种时间序列预测模型,可同时处理数据中的非季节性与季节性模式。它直接建立在 ARIMA 之上,因此如果您已经用过 ARIMA,会发现大多数机制都很熟悉。关键区别在于,SARIMA 额外引入了一组专门用于建模固定间隔重复行为的参数,例如月度、季度或每周周期。

形式上,SARIMA 写作 SARIMA(p, d, q)(P, D, Q)[S]。第一组参数 (p, d, q) 处理非季节性结构,与标准 ARIMA 相同。第二组 (P, D, Q)[S] 则用于季节性模式,其中 S 表示季节周期长度。对于具有年度季节性的月度数据,S = 12;季度数据则 S = 4。

SARIMA 的关键组成部分

SARIMA 的七个参数一开始可能会让人觉得很多。将它们分为两组会更容易理解:熟悉的 ARIMA 三元组 (p, d, q) 以及与之在季节尺度上相对应的 (P, D, Q, S)。每个季节性参数所起的作用与其非季节性“孪生”完全相同,只是应用在季节性间隔而非相邻时间步上。

自回归(AR)部分

AR 组件使用该序列的过去取值来预测未来。参数 p 指定包含多少个滞后值。如果 p = 2,模型会用前两个时间步作为当前值的预测因子。

在季节性一侧,P 做的是同样的事,但作用在季节性滞后上。如果 P = 1 且 S = 12,模型会查看 12 期前(上一年的同一月份)的取值作为预测因子。这能直接捕捉同比模式。

差分(I)部分

参数 d 控制为消除趋势并使序列平稳化而进行差分的次数。差分即用每个观测减去其前一观测,可去除线性趋势。如果 d = 1,即取一阶差分;若 d = 2,则对已差分的序列再做一次差分。

季节性差分的原理相同,但作用在季节性滞后上。参数 D 指定应用季节性差分的次数。当 D = 1 且 S = 12 时,您将每个观测减去其 12 期前的值。当序列同时存在总体上升趋势和重复性季节性时,常见做法是同时使用 d = 1 与 D = 1。

移动平均(MA)部分

与关注过去取值的 AR 组件不同,MA 组件建模当前观测与过去预测残差之间的关系。参数 q 设定包含多少个滞后误差项。如果 q = 1,模型会用上一步的预测误差来校正当前预测。

季节性对应参数 Q 将同一逻辑应用于季节性滞后。若 Q = 1 且 S = 12,模型会引入 12 期前的预测误差。当季节性冲击(如异常炎热的夏季推高能源需求)往往会延续到下一年的同一时期时,这一点尤为重要。

季节性组件(S)

参数 S 定义季节周期长度,并将三项季节性参数(P、D、Q)关联起来。S 的取值非常关键:如果您的数据是月度且呈现年度模式,S = 12;周度数据的年度周期则 S 约为 52。

季节性有时会有点棘手。一年并非精确等于 52 周,而更接近 52.18。对大多数实际用途而言,取整为 S = 52 足够。但某些数据集具有多个季节周期:如日度用电常同时呈现每周周期(S = 7)与年度周期(S = 365)。标准 SARIMA 仅能处理一个季节周期,若存在多重季节性,则需要使用更高级的方法,如 TBATS 或 Facebook Prophet。

当 S 并不明显时,时间序列分解会有帮助。将序列分解为趋势、季节性与残差组件,可直观看出占主导地位的重复周期。您也可以查看自相关图,是否在规则滞后处出现尖峰。

ARIMA 与 SARIMA:有何区别?

您或许已经在想:实际中什么时候该用 SARIMA 而不是更简单的 ARIMA?

简短的答案是:当数据不存在有意义的季节性模式时用 ARIMA;当存在时用 SARIMA。

ARIMA 建模三件事:序列自身的自相关(AR)、达到平稳所需的差分次数(I),以及过去预测误差对当前值的滞留影响(MA)。它能很好地处理趋势、循环与不规则噪声。但它做不到的是建模以固定季节频率重复的模式。这些会以无法解释的方差形式“漏掉”。

SARIMA 正是为此而生。当您的数据中出现清晰的季节性峰谷时,拟合普通 ARIMA 会将这些模式“挤进”残差,从而导致更差的预测,且残差并非白噪声。SARIMA 则可直接捕捉这些模式。

一个实用法则:绘制数据,观察是否存在固定间隔的重复模式。如果看到了,比如节日销售高峰、冬季能源激增、季度财报规律,请选用 SARIMA。如果序列不规则或主要由趋势驱动且无固定周期,ARIMA 更简单且足够用。

我们的Python 中的 ARIMA 模型课程同时涵盖两种框架,并提供上手机会,帮助您建立何时应用各自模型的直觉。

如何在 Python 中构建 SARIMA 模型

构建 SARIMA 遵循一个清晰的流程:收集数据、检查平稳性、识别参数、拟合模型、进行诊断并开展预测。以下使用 Python 的 statsmodels 库说明各步骤在实践中的做法。

数据收集

要建模季节性,需要足够长的历史数据,至少能观察到两次该模式,最好是多个周期。典型示例包括月度零售销售、气温记录、能源消耗数据和客运量统计。可公开获取的来源包括美国联邦储备经济数据库(FRED)、美国人口普查局或 Kaggle,都是不错的起点。

该流程的标准教学数据集是航空旅客数量:1949 至 1960 年的月度数据,具有清晰的上升趋势和强烈的年度季节性。可通过 statsmodels 的 get_rdataset() 从 Rdatasets 集合获取。建议先用此数据集熟悉流程,再应用到您自己的数据上。

数据预处理

在拟合任何 SARIMA 之前,需要一个平稳序列,即其均值与方差不会随时间变化。增强型 Dickey-Fuller(ADF)检验可进行形式化检查:p 值低于 0.05 表明序列平稳。

若不平稳,可通过差分修正。对趋势使用常规差分(d = 1),对季节性非平稳使用季节性差分(D = 1,滞后 S),必要时两者皆用。在此步骤前先处理缺失值。对时间序列而言,前向填充或插值是常见做法,因为直接删除行会破坏时间结构。

模型识别

在获得平稳序列后,可使用自相关函数(ACF)与偏自相关函数(PACF)图来识别模型参数。重点关注:

  • ACF 显示序列与其滞后的相关性。q 滞后后的急剧截断提示 MA 阶数。季节性滞后处的尖峰(如月度数据的 12、24、36)提示 Q。
  • PACF 显示在去除中间滞后影响后的偏相关。p 滞后后的急剧截断提示 AR 阶数。季节性尖峰提示 P。

实际操作中,这些图会给出候选取值,您可以用信息准则比较少量模型(诊断部分会详述)。如果更倾向于自动化搜索,pmdarima 包的 auto_arima() 会对参数组合进行网格搜索并选择拟合最佳的模型。

参数估计

确定候选参数后,statsmodels 会使用极大似然估计(MLE)进行估计,即寻找使在该模型下观测数据最可能出现的系数值。相比普通 ARIMA,SARIMA 的估计计算量更大,因为优化器需同时拟合非季节性与季节性组件。

拟合过程偶尔会收敛到局部最优而非全局最优,因此当结果看起来不对劲时,值得尝试不同的初始值或参数组合。

模型拟合

以下是在 Python 中使用航空旅客数据集拟合 SARIMA 模型的方法:

import pandas as pd
import statsmodels.api as sm

# Load the classic airline dataset
airline_data = sm.datasets.get_rdataset("AirPassengers", "datasets").data
airline_data.index = pd.date_range(start="1949-01", periods=len(airline_data), freq="MS")
passengers = airline_data["value"]

# Fit SARIMA(1,1,1)(1,1,1)[12]
sarima_model = sm.tsa.statespace.SARIMAX(
    passengers,
    order=(1, 1, 1),
    seasonal_order=(1, 1, 1, 12),
    enforce_stationarity=False,
    enforce_invertibility=False
)

sarima_result = sarima_model.fit(disp=False)
print(sarima_result.summary())	

order 参数用于非季节部分,取 (p, d, q);seasonal_order 取 (P, D, Q, S)。将 enforce_stationarity=False 与 enforce_invertibility=False 设为 False,可为优化器提供更大的自由度,往往有助于在真实世界数据上收敛。

模型统计与诊断

拟合完成后,使用 sarima_result.plot_diagnostics() 运行内置诊断图。您需要关注四点:

  • 标准化残差: 应该呈白噪声,无明显模式。
  • 残差直方图: 应大致接近正态分布。
  • 正态 Q-Q 图: 点应接近对角线。
  • 相关图(残差的 ACF): 不应有显著尖峰,否则说明存在未解释的自相关。

特别关注相关图中的季节性滞后。若在 12、24 等滞后处出现尖峰,说明季节性部分尚未充分捕捉。使用 AIC(赤池信息准则)与 BIC(贝叶斯信息准则)比较不同设定:值越低代表拟合越好,且 BIC 对复杂度的惩罚更重。

预测

在模型通过验证后,生成预测就很直接了。将数据划分为训练集和测试集,以获得对预测精度更客观的评估:

# Train on first 11 years, test on final year
train = passengers[:"1959"]
test = passengers["1960":]

# Refit on training data and forecast
sarima_train = sm.tsa.statespace.SARIMAX(
    train,
    order=(1, 1, 1),
    seasonal_order=(1, 1, 1, 12),
    enforce_stationarity=False,   # add this
    enforce_invertibility=False   # add this
).fit(disp=False)

forecast = sarima_train.get_forecast(steps=12)
forecast_mean = forecast.predicted_mean
conf_int = forecast.conf_int()

get_forecast() 方法会返回点预测以及置信区间,随着预测步数的增加,区间会逐渐变宽。这并非缺陷,而是模型对不确定性的如实表达。请在留出的测试集上使用 RMSE(均方根误差)或 MAPE(平均绝对百分比误差)评估准确性。

SARIMA 的实际应用

现实世界中的许多信号都具有季节性,因此 SARIMA 在任何时间序列工具箱中都应占据一席之地。以下是跨行业的一些示例:

  • 零售: 预测月度销售量用于库存规划,尤其是在节假日等需求高峰期,这些高峰可预测,但其幅度会逐年变化。
  • 能源消耗: 预测电力与天然气需求,其既有日度季节性也有年度季节性,由气温与活动模式驱动。
  • 金融: 建模与会计年度同步的季度盈利或成交量模式。
  • 天气预报: 预测气温、降水等呈现强年度周期的气候变量。

在这些场景中,重复结构就是信号,而 SARIMA 正是为捕捉它而设计的。

SARIMA 的局限性

了解工具在哪些方面表现出色只是问题的一半。SARIMA 是季节性时间序列的可靠基线,但了解其局限,才能区分善用模型与盲目用模型的人。

它一次只处理一个季节周期。如果您的数据存在多重季节性,如日度、周度与年度模式相互叠加,SARIMA 无法同时建模全部频率。TBATS、Prophet 或 LSTM 等方法更适合处理多重季节频率。

SARIMA 也假设线性关系。它建模过去取值、过去误差与未来观测之间的线性关系。非线性动力学(在金融时间序列或混沌系统中较常见)需要其他工具。与 ARIMA 一样,SARIMA 仅依赖序列自身的历史。如果您的预测受外部驱动因素影响(如促销、天气事件、经济指标),请考虑 SARIMAX,它在 SARIMA 框架上引入外生变量。

最后,参数选择确实可能很难。需要调的参数有七个,搜索空间很大,且在长序列上拟合可能很慢。pmdarima 的 auto_arima() 有助于自动化这一过程。但理解参数的实际含义没有捷径可走,这也是我们在写任何代码前先讲组件的原因。

结语

我一直认为,SARIMA 在入门级预测课程中被低估了。它常被教作“加了季节性的 ARIMA”,这让人觉得只是小幅扩展。事实并非如此。季节性参数不是附加的装饰;它们在做实打实的结构性建模,捕捉的是 ARIMA 根本触及不到的那一层数据行为。

让 SARIMA 在实践中“通透”的关键在于意识到非季节性与季节性组件并非各自为政的并行模型,而是相互作用。AR 与 MA 项与其季节性“孪生项”协同工作,分别处理不同时标上的自相关。一旦理解了这一点,阅读 ACF 与 PACF 图就不再像在“找图形”,而更像是在真正理解您的数据。

如果您处理的是月度、季度或任何规则周期的数据,SARIMA 是正确的起点。这不是因为它总是最终答案,而是因为它迫使您清晰地思考序列的结构。在此基础上,SARIMAX 可引入外部预测因子,而 TBATS 或 Prophet 则能处理更复杂的多季节性情况。我们的时间序列预测教程以及Python 中的 ARIMA 模型课程,都是不错的下一步。

Vinod Chugani

作者

Vinod Chugani

Vinod Chugani 的职业生涯始于东京,曾任摩根大通最年轻的对冲基金销售台负责人,随后在雷曼兄弟创下个人销售纪录,之后又打造了覆盖 30 个国家的电子分销业务,营收突破 1 亿新元,随后转向数据领域。他毕业于杜克大学经济学专业,亦为 NYC Data Science Academy 校友,并在 100 多名申请者中成为Hugo Bowne-Anderson 在 Maven 开设的 “Building AI Applications” 课程的三位奖学金获得者之一。目前,他为 DataCamp、KDnuggets、Machine Learning Mastery 和 Statology 撰稿,内容涵盖从统计学到代理式 AI 等主题,并在 NYC Data Science Academy 指导数据从业者,已完成超过 1,000 场一对一辅导。

 

SARIMA 常见问答

SARIMA 是什么的缩写?

SARIMA 是 Seasonal AutoRegressive Integrated Moving Average(季节性自回归积分滑动平均)的缩写。它在标准 ARIMA 模型基础上增加了季节性参数——(P, D, Q) 与季节周期 S——以捕捉时间序列数据中重复出现的模式,如月度或季度周期。

ARIMA 与 SARIMA 有何不同?

ARIMA 建模非季节性模式:趋势、自相关与移动平均效应。SARIMA 则增加一层参数(P、D、Q、S),用于在季节性滞后上建模相同的效应。如果您的数据在固定间隔呈现重复模式——比如每年 12 月销售更高——SARIMA 可直接捕捉,而 ARIMA 会将其留在无法解释的残差方差中。

如何选择合适的 SARIMA 参数?

首先使用增强型 Dickey-Fuller 检验检查序列是否平稳。然后查看 ACF 与 PACF 图:非季节性的 AR(p)与 MA(q)阶数取决于非季节性滞后处的截断模式;季节性阶数 P 与 Q 则来自季节性滞后处的尖峰。您也可以使用 pmdarima 包的 auto_arima() 自动搜索参数组合,并用 AIC 或 BIC 选择最优模型。

如何确定 SARIMA 模型的季节周期 S?

季节周期 S 反映模式重复的频率。具有年度季节性的月度数据,S = 12;季度数据 S = 4;周度数据 S = 52(或将 52.18 四舍五入)。若周期不明显,可进行时间序列分解,或查看 ACF 图中是否有等间距尖峰——这些尖峰揭示主要季节频率。

SARIMA 能处理多个季节周期吗?

标准 SARIMA 一次处理一个季节周期。如果数据存在多重叠加的季节性——例如日度电力需求同时具有每周与年度周期——您需要使用 TBATS、Facebook Prophet 或 LSTM 等替代方法,这些方法可同时建模多个重叠的季节结构。

哪个 Python 库最适合拟合 SARIMA 模型?

Python 的 statsmodels 库是标准选择,提供了 SARIMAX()(足够灵活,可在无外生变量时拟合 SARIMA)。若需自动选择参数,pmdarima 库的 auto_arima() 会执行网格搜索,当您不确定参数起点时,非常值得纳入工作流程。

如何评估我的 SARIMA 模型是否拟合良好?

拟合完成后,对结果对象运行 plot_diagnostics(),检查残差是否类似白噪声、无结构——尤其是在残差 ACF 中季节性滞后不应出现尖峰。使用 AIC 或 BIC(越低越好)比较不同模型设定。对于留出数据的预测精度,RMSE 与 MAPE 是最常用指标。

什么是 SARIMAX,何时应该用它而不是 SARIMA?

SARIMAX 为 SARIMA 框架加入外生变量——外部预测因子。当您拥有可度量、且会影响序列的因素时使用它:如促销投入影响零售销售、气温影响能源需求、宏观经济指标影响季度营收。若手头只有该序列本身,SARIMA 足矣;一旦有相关外部驱动,SARIMAX 就能将其直接纳入。

主题