SARIMA算法
已有ARIMA算法,为什么还引入SARIMA算法
ARIMA和SARIMA模型的核心区别。简单来说:
普通的差分(d)处理的是“趋势”非平稳性,而季节性差分(D)处理的是“季节性”非平稳性。它们是两种完全不同性质的非平稳模式,需要分别处理。
如冰块销售额数据包含两种变化:
-
趋势 (Trend):因为你的营销做得很好,品牌越来越受欢迎,所以整体销售额每年都在稳步上升。这是一个长期的、单调向上的运动。
-
季节性 (Seasonality):因为天气原因,每年夏天销售额都会达到高峰,冬天都会降到低谷。这是一个固定的、以年为周期的重复模式。
现在,销售额数据是非平稳的,但原因有两个:
-
原因一:有趋势(均值随时间上升)。
-
原因二:有季节性(方差和协方差随时间周期性变化)。
ARIMA
当对销售额进行 一阶普通差分 (d=1) 时,你计算的是 Y_t - Y_{t-1}。
-
效果:这个操作成功地移除了趋势。它不再是一根整体向上的线了。现在数据的均值看起来是稳定的(围绕0波动)。
-
局限:但是,差分后的数据依然会每年夏天出现一个高峰,冬天出现一个低谷。它的波动模式依然随着季节有规律地变化。从统计学的严格定义来看,这种具有周期性波动的序列协方差不是恒定的(因为夏天和冬天的波动幅度不同),因此它仍然不是平稳序列。
所以,ARIMA的差分只解决了“趋势非平稳”,但没解决“季节非平稳”。
SARIMA
为了处理残留的季节性非平稳性,SARIMA引入了季节性差分 (D)。
对于月度数据(s=12),一阶季节性差分 (D=1) 计算的是 Y_t - Y_{t-12}。
-
效果:这个操作比较的不是“这个月 vs 上个月”,而是“今年夏天 vs 去年夏天”。它直接移除了以年为单位的固定季节性模式。做完季节性差分后,数据不仅没有趋势,连固定的夏高冬低模式也被移除了,序列变得更加平稳。
最终,一个完整的SARIMA模型通常是两者结合:(1 - L)^d (1 - L^s)^D Y_t = ...
(其中L是滞后算子)
它先通过 (1 - L)^d 做普通差分去趋势,再通过 (1 - L^s)^D 做季节性差分去季节性。
为什么不能只用普通差分 (d) 来解决季节性?
你可能会想,如果做很多次普通差分(比如d=12),是不是也能把季节性差分掉?
理论上可以,但实践中非常不推荐,原因如下:
-
效率低下且不精确:普通差分(d=12)的公式是 (1 - L)^{12},这是一个复杂的多项式,它会引入从滞后1到滞后11的许多不必要的项,而不仅仅是我们关心的滞后12项。这会使模型变得非常复杂和混乱。而季节性差分 (1 - L^{12})是一个精准的外科手术,只针对滞后12期进行操作。
-
可解释性差:季节性差分有明确的业务含义——“与去年同期的变化量”。而12阶普通差分没有这样清晰的解释。
-
可能引入额外的相关性:高阶的普通差分可能会意外地使数据过度差分,或引入新的、难以解释的自相关结构,让模型的AR和MA部分更难识别和估计。
SARIMA模型
SARIMA模型,全称为季节性自回归积分滑动平均模型(Seasonal Autoregressive Integrated Moving Average Model),是时间序列分析中的一种重要模型,用于处理具有明显季节性特征的数据。它在ARIMA模型的基础上,增加了季节性因素的考量,使得模型能够更好地捕捉和预测季节性变化的时间序列数据。
季节性(Seasonal): 这一部分考虑了数据随时间变化可能出现的周期性模式,比如说每年的某个季节销量上升或下降这样的季节性规律。
自回归(Autoregressive, AR): 这表示模型会用前一段时间内的数据来预测未来的值。想象一下,如果你在观察股市,你可能会发现今天的股价与过去几天的股价有关。
积分(Integrated, I): 这部分涉及到将时间序列转换为稳定的形式,使得序列的统计特性(如均值)不随时间改变。这通常通过差分完成,也就是计算连续观测之间的变化量。
滑动平均(Moving Average, MA): 这表示模型利用时间序列过去误差的平均值来做预测。这可以看作是一种平滑技术,有助于消除预测中的随机波动。
模型结构
SARIMA模型通过引入季节性参数来扩展ARIMA模型,其形式通常表示为SARIMA(p,d,q)(P,D,Q)s,其中:
-
p:非季节性自回归项的阶数。
-
d:非季节性差分次数。
-
q:非季节性移动平均项的阶数。
-
P:季节性自回归项的阶数。
-
D:季节性差分次数。
-
Q:季节性移动平均项的阶数。
-
s:季节周期的长度。
在实际应用中,SARIMA模型可以用于各种季节性数据的预测,如月度销售数据、季度经济指标、年度气象数据等。通过对历史数据的季节性模式进行学习,SARIMA模型能够预测未来某一时期内的数据走势。
当用statsmodels等库拟合一个SARIMA(model, order=(p, d, q), seasonal_order=(P, D, Q, s))模型时,软件内部会:
-
自动对
Y_t进行D次季节性差分和d次非季节性差分,得到Z_t。 -
将
Z_t同时喂给非季节性ARMA和季节性ARMA这两个组件。 -
通过最大似然估计等算法,同时估计出所有参数:
-
非季节性AR参数:
φ₁, φ₂, ..., φ_p -
非季节性MA参数:
θ₁, θ₂, ..., θ_q -
季节性AR参数:
Φ₁, Φ₂, ..., Φ_P -
季节性MA参数:
Θ₁, Θ₂, ..., Θ_Q
-
4. 非季节性和季节性ARMA组件是并联在一起,对同一个经过差分处理的平稳序列 `Z_t 进行拟合的,分别捕捉和解释该序列中不同时间尺度(短期 vs. 长期周期)的自相关模式
statsmodels 中 SARIMAX 算法的各个参数:
模型阶数参数 (核心参数)
非季节性部分 (p, d, q)
-
order(tuple, 格式为 (p, d, q)): 定义模型的主(非季节性)部分。-
p(AR - 自回归阶数): 表示当前值用过去多少期的值来进行回归。例如p=1表示 Y_t 与 Y_{t-1} 相关。 -
d(I - 积分阶数): 为了使序列变得平稳而进行的差分次数。d=1表示对原始数据做一阶差分。 -
q(MA - 移动平均阶数): 表示当前误差项用过去多少期的误差项来进行回归。例如q=1表示当前误差与上一期的误差相关。
-
季节性部分 (P, D, Q, s)
-
seasonal_order(tuple, 格式为 (P, D, Q, s)): 定义模型的季节性部分。-
P(季节性自回归阶数): 类似于p,但是是针对季节周期的滞后项。例如s=12(月度数据),P=1表示 Y_t 与 Y_{t-12} 相关。 -
D(季节性差分阶数): 类似于d,是为了消除季节性不平稳而进行的季节性差分次数。例如D=1和s=12表示进行 (Y_t - Y_{t-12})一阶季节性差分。 -
Q(季节性移动平均阶数): 类似于q,是针对季节性周期的误差滞后项。 -
s(季节周期长度): 这是最关键的一个参数,定义了数据的季节性周期。-
月度数据且有年度季节性:
s=12 -
季度数据:
s=4 -
每周数据(每天一个观测值)且有周度季节性:
s=7 -
每小时数据且有日度季节性:
s=24
-
-
示例: 一个常见的用于月度数据的模型是 SARIMAX(order=(1,1,1), seasonal_order=(1,1,1,12))。
模型设定参数
这些参数用于引入额外的信息或改变模型的默认形式。
-
exog(array_like, 可选): 外生变量。这是一个包含一个或多个时间序列的数组,这些序列被假设为对因变量endog有影响,但不受其影响(即它们是“给定的”或“预定的”)。例如,在预测销售额时,广告支出、节假日指标等可以作为外生变量。 -
trend(str {'n', 'c', 't', 'ct'}, 默认为 'c'): 控制模型中的确定性趋势。-
'n'或'nc': 无常数项,无趋势。 -
'c': 包含常数项(即截距)。 -
't': 只包含线性时间趋势项。 -
'ct': 同时包含常数项和线性时间趋势项。
-
-
enforce_stationarity(bool, 默认为 True): 在模型估计前,是否对 AR 参数进行约束,以确保生成的过程是平稳的。通常建议保持为True。 -
enforce_invertibility(bool, 默认为 True): 在模型估计前,是否对 MA 参数进行约束,以确保过程是可逆的。通常建议保持为True,因为它能保证 MA 多项式收敛,使模型更稳定。 -
measurement_error(bool, 默认为 False): 是否假设因变量endog存在测量误差。如果为True,模型会在状态空间表示中添加一个误差项。 -
time_varying_regression(bool, 默认为 False): 是否允许外生变量的回归系数随时间变化。如果为True,模型会变得非常灵活但也更复杂。 -
mle_regression(bool, 默认为 True): 是否使用最大似然估计 (MLE) 来同时估计所有参数(包括回归系数和 ARIMA 参数)。如果为False,则会在估计 ARIMA 参数之前,先使用回归从因变量中移除外生变量的影响(即使用 GLS 回归)。 -
simple_differencing(bool, 默认为 False): 是否使用简单差分。如果为True,模型会在估计前对数据进行差分,然后对差分后的数据建模。如果为False(默认),差分将被纳入状态空间模型中进行整体估计。通常保持默认的False即可,尤其是在有缺失值的情况下。 -
hamilton_representation(bool, 默认为 False): 是否使用 Hamilton 表示法来处理 ARMA 过程。通常不需要更改。 -
concentrate_scale(bool, 默认为 False): 是否在似然函数中集中尺度参数(方差)。这可以略微提高数值优化的效率。
估计方法参数
这些参数传递给 fit() 方法,用于控制模型的估计过程。
-
disp(bool, 默认为 True): 是否在迭代过程中输出收敛信息。 -
maxiter(int, 默认为 50): 优化算法的最大迭代次数。如果模型难以收敛,可以尝试增加这个值(例如maxiter=200)。 -
method(str): 用于估计的优化算法。通常是'lbfgs'(默认)、'nm'(Nelder-Mead 单纯形法)、'powell'等。如果默认方法不收敛,可以尝试其他方法。 -
start_params(array_like, 可选): 参数的初始值。对于复杂模型,提供好的初始值可以帮助优化算法找到全局最优解,避免陷入局部最优。 -
globs(dict, 可选): 全局变量,用于高级定制。 -
iprint(int): 控制优化输出的详细程度(-1到2),值越大输出越详细。 -
ftol(float): 收敛的相对误差目标。 -
gtol(float): 收敛的梯度目标。 -
kappa(float): 用于算法计算。
import statsmodels.api as sm import pandas as pd # 加载数据 data = sm.datasets.co2.load_pandas() y = data.data # 处理缺失值:简单使用前向填充 y = y['co2'].resample('W').mean().ffill() # 定义模型 # 非季节性部分: (p=1, d=1, q=1) # 季节性部分: (P=1, D=1, Q=1, s=52) 因为现在是周数据,假设年度周期为52周 model = sm.tsa.SARIMAX(y, order=(1, 1, 1), seasonal_order=(1, 1, 1, 52), trend='c', # 包含常数项 enforce_stationarity=True, enforce_invertibility=True) # 估计模型 results = model.fit(disp=False, # 不输出迭代信息 maxiter=200) # 增加最大迭代次数 # 查看结果摘要 print(results.summary()) # 进行预测 forecast = results.get_forecast(steps=52)

浙公网安备 33010602011771号