ARIMA算法
statsmodels 中两个至关重要的函数:ACF(自相关函数) 和 PACF(偏自相关函数)。它们是时间序列分析,尤其是 ARIMA 模型建模中的核心工具。
1. ACF (Autocorrelation Function) - 自相关函数
-
它衡量什么? ACF 衡量的是时间序列 y_t与其自身滞后 k 期(y_{t-k})的简单相关性。
-
如何理解? 例如,
ACF(k=1)就是今天的气温和昨天气温的相关系数;ACF(k=2)是今天和前天气温的相关系数,以此类推。 -
关键点: ACF 在计算 y_t 和 y_{t-k} 的相关性时,并没有排除中间期(y_{t-1}, y_{t-2}, ..., y_{t-k+1})的影响。它包含了所有间接和直接的影响。
2. PACF (Partial Autocorrelation Function) - 偏自相关函数
-
它衡量什么? PACF 衡量的是在剔除了中间滞后项(y_{t-1}, ..., y_{t-k+1})的影响后,时间序列 y_t 与其滞后 k 期(y_{t-k})的纯粹、直接的相关性。
-
如何理解? 比如,
PACF(k=2)衡量的是在今天和昨天的气温已知的情况下,今天和前天气温之间还有多少额外的相关性。它剥离了昨天(y_{t-1})这个“中间人”带来的影响。 -
关键点: PACF 就像是 y_t和 y_{t-k} 之间的 “净相关性” 或 “直接相关性”。
在 statsmodels 中的函数
在 statsmodels.tsa.stattools 中,计算这两个函数的函数分别是:
-
acf(x, nlags=None, alpha=None, ...)-
x: 输入的时间序列数据(一维数组或 Pandas Series)。 -
nlags: 计算多少期的滞后。默认为min(10 * np.log10(nobs), nobs - 1),通常需要手动指定一个合理的值(如 20, 40)。 -
alpha: 如果设置(如alpha=0.05),函数会返回置信区间,用于判断哪些自相关系数是统计显著的。
-
-
pacf(x, nlags=None, alpha=None, method='ywunbiased' ...)-
参数与
acf类似。 -
method: 计算 PACF 的方法。常用选项有:-
'yw'或'ywunbiased': Yule-Walker 方程(基于样本自相关),这是最经典的方法。 -
'ols': 对每个滞后 k,用 OLS 回归拟合 y_t ~ y_{t-1} + ... + y_{t-k},并取 y_{t-k}$的系数。计算精确但较慢。 -
'ld': 使用 Levinson-Durbin 递归,更高效。
-
-
如何使用?
-
首先确保时间序列是平稳的(可以通过差分实现,即确定
d)。 -
绘制平稳序列的 ACF 和 PACF 图。
-
观察图形:
-
识别 MA(q) 的
q:看 ACF 图在滞后多少期后“截尾”(显著为0)。 -
识别 AR(p) 的
p:看 PACF 图在滞后多少期后“截尾”。
-
import numpy as np import pandas as pd import matplotlib.pyplot as plt from statsmodels.graphics.tsaplots import plot_acf, plot_pacf from statsmodels.tsa.arima_process import ArmaProcess # 1. 模拟一个 AR(2) 过程: y_t = 0.6*y_{t-1} + 0.2*y_{t-2} + epsilon_t ar2 = np.array([1, -0.6, -0.2]) # 注意 statsmodels 的约定:系数符号取反 ma = np.array([1]) simulated_data = ArmaProcess(ar2, ma).generate_sample(nsample=1000) # 2. 绘制时间序列图 plt.figure(figsize=(10, 6)) plt.plot(simulated_data) plt.title('Simulated AR(2) Process') plt.show() # 3. 绘制 ACF 和 PACF 图 fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8)) # 绘制 ACF图 (拖尾) plot_acf(simulated_data, lags=40, alpha=0.05, ax=ax1) ax1.set_title('Autocorrelation Function (ACF)') # 注意:ACF 是缓慢衰减的(拖尾) # 绘制 PACF图 (2阶后截尾) plot_pacf(simulated_data, lags=40, alpha=0.05, ax=ax2, method='ywm') ax2.set_title('Partial Autocorrelation Function (PACF)') # 注意:PACF 在 lag=2 之后急剧下降并保持在置信区间内(截尾) plt.tight_layout() plt.show()
拖尾:指的是ACF或PACF并不在某阶后均为0,而是呈现出一种衰减的趋势,但并不会完全为0。这通常意味着时间序列数据具有长期记忆性,即过去的数据对未来的数据仍有一定的影响。拖尾的情况在AR模型和MA模型中都有可能出现。
截尾:截尾则是指ACF或PACF在某阶后均为0的性质。这意味着时间序列数据在某一阶数后,过去的数据对未来数据的影响可以忽略不计。在AR模型中,PACF通常表现出截尾性,而在MA模型中,ACF则通常表现出截尾性。
模型选择:对于ARMA模型的ACF和PACF图,我们可以通过观察其图形特征来判断模型的阶数。如果ACF图呈现出拖尾的特征,而PACF图呈现出截尾的特征,那么可以考虑使用AR模型进行拟合;如果ACF图呈现出截尾的特征,而PACF图呈现出拖尾的特征,那么可以考虑使用MA模型进行拟合。如果ACF和PACF图都呈现出拖尾的特征,那么可能需要考虑使用ARMA模型进行拟合。

adfuller 是构建ARIMA模型前的必备步骤,用于确定差分阶数 d,是时间序列分析的基础工具。
adfuller 是 Augmented Dickey-Fuller test(增广迪基-富勒检验)的简称。它是一种统计检验方法,用于检验一个时间序列是否具有单位根(unit root),即判断时间序列是否是非平稳的。
核心概念理解
-
单位根(Unit Root):如果时间序列包含单位根,意味着它具有随机游走的性质,其方差随时间增长而增大,是非平稳的。
-
平稳性(Stationarity):大多数时间序列模型(如ARIMA)都要求数据是平稳的。平稳序列的统计特性(如均值、方差)不随时间变化。
-
原假设(H₀):序列具有单位根(即序列是非平稳的)。
-
备择假设(H₁):序列没有单位根(即序列是平稳的)。
from statsmodels.tsa.stattools import adfuller result = adfuller(x, maxlag=None, regression='c', autolag='AIC', store=False, regresults=False)
主要参数说明:
-
x:要检验的时间序列数据(一维数组或Series)。 -
maxlag:检验中使用的最大滞后阶数。如果为None,自动选择。 -
regression:最重要参数之一,指定回归方程的类型:-
'c':仅包含截距项(默认)y_t = α + β*t + ρ*y_{t-1} + ... -
'ct':包含截距项和线性时间趋势y_t = α + β*t + ρ*y_{t-1} + ... -
'ctt':包含截距项、线性和时间二次趋势 -
'nc':不包含截距项或趋势项y_t = ρ*y_{t-1} + ...
-
-
autolag:自动选择滞后阶数的方法:-
'AIC':Akaike信息准则(默认) -
'BIC':Bayesian信息准则 -
't-stat':基于t统计量 -
None:使用maxlag指定的滞后阶数
-
返回值
函数返回一个包含5个元素的元组:
-
adf:ADF检验统计量(Test statistic) -
pvalue:p值(用于判断是否拒绝原假设) -
usedlag:使用的滞后阶数 -
nobs:用于检验的观测值数量 -
critical values:不同显著性水平(1%, 5%, 10%)下的临界值字典 -
icbest:如果autolag不是None,返回最佳信息准则值
解读结果
决策规则:
-
如果 p值 < 显著性水平(如0.05):拒绝原假设,认为序列是平稳的
-
如果 ADF统计量 < 临界值(如5%水平):拒绝原假设,认为序列是平稳的
-
否则:不能拒绝原假设,认为序列是非平稳的
在ARIMA模型中,将差分后的预测结果恢复到原始尺度需要反向差分(逆差分)操作。(satesmodel中已自动实现)
ARIMA(p,d,q)中:
-
d:差分阶数
-
经过d阶差分后,需要进行d次反向差分来恢复原始数据
一阶差分恢复
import numpy as np import pandas as pd from statsmodels.tsa.arima.model import ARIMA # 示例数据 original_data = pd.Series([10, 15, 20, 25, 30, 35]) # 一阶差分 diff_data = original_data.diff().dropna() print("一阶差分:", diff_data.values) # [5, 5, 5, 5, 5] # 假设我们对差分数据进行了预测,得到下一个值 predicted_diff = 5 # 预测的差分值 # 恢复预测值 last_original_value = original_data.iloc[-1] predicted_original = last_original_value + predicted_diff print(f"预测的原始值: {predicted_original}") # 40
多阶差分恢复
# 二阶差分示例 data = pd.Series([10, 15, 23, 34, 48, 65]) # 二阶差分 diff1 = data.diff().dropna() # 一阶差分: [5, 8, 11, 14, 17] diff2 = diff1.diff().dropna() # 二阶差分: [3, 3, 3, 3] # 假设预测下一个二阶差分值 predicted_diff2 = 3 # 反向恢复 # 第一步:从二阶差分恢复一阶差分 last_diff1 = diff1.iloc[-1] # 17 predicted_diff1 = last_diff1 + predicted_diff2 # 17 + 3 = 20 # 第二步:从一阶差分恢复原始值 last_original = data.iloc[-1] # 65 predicted_original = last_original + predicted_diff1 # 65 + 20 = 85

浙公网安备 33010602011771号