时间序列——平稳性检验

火山方舟向量数据库智能内容

时间序列平稳性检验的意义在于确保时间序列数据的稳定性,即数据的统计性质在不同时间点保持不变。这对于许多时间序列分析方法和模型是至关重要的,因为平稳性是许多模型的基本假设之一

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()
      

picture.image

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']}")
      

picture.image

通 过循环进行差分, 利用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()
      

picture.image

通过一阶差分后的数据(即每个时间点的值与前一个时间点的值之差),代表的是原始时间序列在差分阶数下的变化趋势,经过一阶差分后数据达到平稳,差分通常用于去除数据的趋势和季节性,使得数据更趋于平稳

差分的数学表达:

一阶差分:

二阶差分:

阶差分:

其中, 表示差分操作,表示了当前时刻的值与前一个时刻值之差,以及递归地应用 次差分操作

结论

实验使用ADF检验判断序列是否平稳并给出平稳的差分阶数,通过差分操作,进一步展示了如何使非平稳的时间序列转变为平稳,为后续的分析和建模提供了基础

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

0
0
0
0
关于作者

文章

0

获赞

0

收藏

0

相关资源
云原生环境下的日志采集存储分析实践
云原生场景下,日志数据的规模和种类剧增,日志采集、加工、分析的多样性也大大增加。面对这些挑战,火山引擎基于超大规模下的 Kubernetes 日志实践孵化出了一套完整的日志采集、加工、查询、分析、消费的平台。本次主要分享了火山引擎云原生日志平台的相关实践。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论