时间序列平稳性检验的意义在于确保时间序列数据的稳定性,即数据的统计性质在不同时间点保持不变。这对于许多时间序列分析方法和模型是至关重要的,因为平稳性是许多模型的基本假设之一
1. 时间序列平稳性检验意义:
- 模型假设满足: 很多时间序列模型,例如ARIMA,要求数据是平稳的。通过进行平稳性检验,确保了模型的基本假设得到满足,提高模型的可靠性和准确性
- 消除趋势和季节性影响: 平稳时间序列更容易去除趋势和季节性影响,使得更容易观察到序列中的其他特征和模式,从而更好地进行预测和分析
- 提高模型性能: 在进行时间序列分析和建模时,平稳性检验有助于提高模型性能,非平稳性序列可能导致模型的不准确性和不稳定性,而平稳序列更有助于模型的稳健性
- 有效控制误差: 平稳序列有助于有效控制误差的影响,使得模型更加可靠。这对于预测和决策制定过程中的信任度至关重要
- 时间序列的可解释性: 平稳性有助于提高时间序列的可解释性,使得对数据背后机制的理解更加清晰
2. 时间序列平稳性统计学性质:
- 常数均值: 时间序列的均值在不同时间点上是常数。即使有波动,整体的平均水平应该是不变的
- 常数方差: 时间序列的方差在不同时间点上是常数。方差描述了数据的离散程度,平稳性要求这种离散程度是稳定的
- 常数自协方差: 自协方差是描述时间序列在不同时间点上的相关性。平稳性要求自协方差在不同时间点上是常数,表示时间序列的相关性模式是稳定的
- 缺乏趋势和季节性: 平稳性还要求时间序列中不存在明显的趋势和季节性影响,使得数据不受外部因素的影响而呈现稳定状态
3. 代码实例
3.1 数据展示
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
# 生成不平稳时间序列数据
np.random.seed(42)
data = np.cumsum(np.random.randn(1000))
# 可视化不平稳数据
plt.figure(figsize=(15,5 ),dpi=300)
plt.plot(data,color = 'c')
plt.title('Non-stationary Time Series')
plt.xlabel('Time')
plt.ylabel('Value')
plt.show()
3.2 ADF平稳性检验
from statsmodels.tsa.stattools import adfuller
import pandas as pd
def find_stationarity_order_with_p_values(time_series, max_diff=5, significance_level=0.05):
"""
循环进行差分,并输出每一阶差分的ADF检验结果,判断在几阶差分时数据达到平稳。
Parameters:
- time_series: 待差分的时间序列
- max_diff: 最大尝试的差分阶数,默认为5
- significance_level: ADF检验的显著性水平,默认为0.05
Returns:
- results: 每一阶差分的结果,包括差分阶数、p-value以及是否达到平稳
"""
results = []
# 差分阶数为0时进行原始序列的平稳性检验
result = adfuller(time_series)
p_value = result[1]
is_stationary = p_value <= significance_level
results.append({
'order': 0,
'p_value': p_value,
'is_stationary': is_stationary
})
# 从差分阶数为1开始循环
diff_order = 1
while diff_order <= max_diff:
diff_series = time_series.diff().dropna()
result = adfuller(diff_series)
p_value = result[1]
is_stationary = p_value <= significance_level
results.append({
'order': diff_order,
'p_value': p_value,
'is_stationary': is_stationary
})
if not is_stationary:
diff_order += 1
time_series = diff_series
else:
break
return results
# df['Price']为检验时间序列数据
results = find_stationarity_order_with_p_values(pd.Series(data))
for result in results:
print(f"第 {result['order']} 阶差分的p-value: {result['p_value']}, 是否达到平稳: {result['is_stationary']}")
通 过循环进行差分, 利用ADF检验判断每一阶差 分后的时间序列是否达 到平稳,原始数据P值大于0.05呈现不平稳状态,经过一阶差分后P值小于0.05数据在一阶差分时达到平稳,其中 ADF检验,是用于检验时间序列数据是否具有单位根,即数据是否是非平稳的, ADF检验的原假设是数据具有单位根,即非平稳; 备择假设是数据是平稳的, 通过检验ADF统计量的显著性水平(p-value),可以判断是否拒绝原假设,从而确定时间序列的平稳性
除了ADF检验之外,还有一些常用于检验平稳性的方法,其中包括:
KPSS 检验: 与ADF检验相反,KPSS检验的原假设是数据是平稳的,备择假设是数据具有单位根。通过检验统计量的显著性水平,可以判断是否拒绝原假设,从而确定平稳性
PP检验: 类似于ADF检验,PP检验也用于检验单位根。它在计算过程中采用不同的修正方法,但其基本思想是与ADF检验相似
走势图观察: 通过绘制时间序列的走势图,观察是否存在明显的趋势和季节性,以判断平稳性
3.3 数据差分
def difference_and_save(data, column_name, diff_order=1):
"""
对数据进行差分并保存为DataFrame。
Parameters:
- data: 包含时间序列数据的原始DataFrame
- column_name: 要差分的列名
- diff_order: 差分阶数,默认为1
Returns:
- diff_df: 差分后的DataFrame
"""
# 复制原始DataFrame以防修改原数据
diff_df = data.copy()
# 进行指定阶数的差分
for i in range(diff_order):
diff_df[column_name] = diff_df[column_name].diff()
# 删除NaN值
diff_df = diff_df.dropna()
return diff_df
column_names = ['Value']
df = pd.DataFrame(data, columns=column_names)
df_diff = difference_and_save(df, 'Value', diff_order=1)
# 可视化不平稳数据
plt.figure(figsize=(15,5 ),dpi=300)
plt.plot(data,color = 'c', label = '原始数据')
plt.plot(df_diff,color = 'r', label='一阶差分')
plt.title('Value')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Value')
plt.show()
通过一阶差分后的数据(即每个时间点的值与前一个时间点的值之差),代表的是原始时间序列在差分阶数下的变化趋势,经过一阶差分后数据达到平稳,差分通常用于去除数据的趋势和季节性,使得数据更趋于平稳
差分的数学表达:
一阶差分:
二阶差分:
阶差分:
其中, 表示差分操作,表示了当前时刻的值与前一个时刻值之差,以及递归地应用 次差分操作
结论
实验使用ADF检验判断序列是否平稳并给出平稳的差分阶数,通过差分操作,进一步展示了如何使非平稳的时间序列转变为平稳,为后续的分析和建模提供了基础
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~