Day 56 时序数据的检验

文章目录

  • [Day 56 · 时序数据的检验](#Day 56 · 时序数据的检验)
    • 环境准备
    • 一、假设检验基础
      • [1.1 原假设与备择假设](#1.1 原假设与备择假设)
      • [1.2 统计量与P值](#1.2 统计量与P值)
    • 二、白噪声检验
      • [2.1 白噪声的定义](#2.1 白噪声的定义)
      • [2.2 ACF检验(自相关函数检验)](#2.2 ACF检验(自相关函数检验))
      • [2.3 PACF检验(偏自相关函数检验)](#2.3 PACF检验(偏自相关函数检验))
      • [2.4 Ljung-Box检验](#2.4 Ljung-Box检验)
    • 三、平稳性检验
      • [3.1 平稳性的定义](#3.1 平稳性的定义)
      • [3.2 ADF检验(单位根检验)](#3.2 ADF检验(单位根检验))
    • 四、季节性检验
      • [4.1 季节性的定义](#4.1 季节性的定义)
      • [4.2 通过ACF图检测季节性](#4.2 通过ACF图检测季节性)
      • [4.3 通过序列分解检测季节性](#4.3 通过序列分解检测季节性)
    • 五、总结
      • [5.1 检验流程](#5.1 检验流程)
      • [5.2 检验方法速查表](#5.2 检验方法速查表)

Day 56 · 时序数据的检验

在学习时间序列预测模型之前,我们需要掌握时序数据的检验方法。本节将系统介绍假设检验的基本概念,以及白噪声检验、平稳性检验和季节性检验的原理与实现。

环境准备

python 复制代码
# 导入必要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf  # 绘制自相关/偏自相关图
from statsmodels.stats.diagnostic import acorr_ljungbox  # Ljung-Box检验
from statsmodels.tsa.stattools import adfuller  # ADF检验
from statsmodels.tsa.seasonal import seasonal_decompose  # 序列分解
import warnings
warnings.filterwarnings("ignore")

# 中文显示设置
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示为方块的问题

一、假设检验基础

1.1 原假设与备择假设

核心思想:在统计学中,我们不能直接证明一件事是什么,而是先假设它不是,然后用证据去推翻这个假设。

类比理解

  • 在法庭上,嫌疑人在被定罪前被假设为无罪(原假设 H0)
  • 检察官需要提供证据证明嫌疑人有罪(备择假设 H1)

原假设的特点

  • 通常是一个清晰、单一的状态
  • 用数学语言表示为等式形式(如:罪 = 0)
  • 是我们想要挑战或推翻的假设

备择假设的特点

  • 是原假设的对立面
  • 通常是我们期待证明的、有价值的发现

1.2 统计量与P值

统计量

  • 反映样本数据偏离原假设的程度
  • 统计量的值越大,说明两组数据的差异越明显

P值(p-value)

  • 证据强度的量化指标
  • 回答的核心问题:如果原假设是真的,我们现在看到的证据有多大可能性纯属巧合?
  • P值越小,说明证据越与原假设格格不入

显著性水平

  • 通常设定为 0.05(即5%)
  • p-value < 0.05:拒绝原假设(reject H0)
  • p-value >= 0.05:无法拒绝原假设(fail to reject H0)

置信区间

  • 落在置信区间内 -> 无法拒绝原假设
  • 落在置信区间外 -> 拒绝原假设

记忆口诀:p越小,落在置信区间外,越拒绝原假设。


二、白噪声检验

2.1 白噪声的定义

为什么要检验白噪声?

  • 时序预测的前提是数据本身具有可预测性
  • 完全随机的序列(白噪声)是不可预测的
  • 白噪声的未来值与过去值没有任何相关性

白噪声的三大特征

  1. 均值为0
  2. 方差恒定
  3. 自相关性为0(过去的值对未来的值没有影响)
python 复制代码
# 生成白噪声序列
np.random.seed(42)  # 设置随机种子,保证结果可复现
num_points = 200  # 序列长度

# 从标准正态分布(均值为0,方差为1)中抽取随机样本
random_sequence = np.random.randn(num_points)

print("生成的前10个数据点:")
print(random_sequence[:10])

# 可视化白噪声序列
plt.figure(figsize=(12, 6))
plt.plot(random_sequence, label='Random Sequence (White Noise)', alpha=0.8)
plt.axhline(y=0, color='r', linestyle='--', label='Mean')
plt.title('White Noise Sequence Visualization', fontsize=16)
plt.xlabel('Time Step', fontsize=12)
plt.ylabel('Value', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.6)
plt.legend()
plt.show()
复制代码
生成的前10个数据点:
[ 0.49671415 -0.1382643   0.64768854  1.52302986 -0.23415337 -0.23413696
  1.57921282  0.76743473 -0.46947439  0.54256004]

2.2 ACF检验(自相关函数检验)

ACF(Autocorrelation Function)

  • 衡量序列与其滞后版本之间的相关性
  • 对于白噪声,只有lag=0时相关性为1,其他滞后的相关性都应在置信区间内

ACF图的解读

  • 蓝色阴影区域:95%置信区间
  • 如果所有滞后项都在置信区间内,说明序列可能是白噪声
python 复制代码
# 检验白噪声属性
print("--- Start White Noise Test ---")
print(f"1. Mean of sequence: {random_sequence.mean():.4f}")
print("   (Conclusion: Mean is very close to 0, condition satisfied.)\n")

print(f"2. Variance of sequence: {random_sequence.var():.4f}")
print("   (Conclusion: Variance is close to 1, condition satisfied.)\n")

print("3. Test autocorrelation (using ACF plot):")
print("   - ACF plot shows correlation between sequence and its lagged values.")
print("   - For white noise, only lag=0 has correlation=1, others should be within confidence interval.")

# 绘制ACF图
fig, ax = plt.subplots(figsize=(12, 5))
plot_acf(random_sequence, lags=40, ax=ax, alpha=0.05)  # alpha=0.05表示95%置信区间
ax.set_title('ACF Plot of White Noise Sequence', fontsize=14)
ax.set_xlabel('Lag', fontsize=12)
ax.set_ylabel('Autocorrelation', fontsize=12)
plt.tight_layout()
plt.show()
复制代码
--- Start White Noise Test ---
1. Mean of sequence: -0.0408
   (Conclusion: Mean is very close to 0, condition satisfied.)

2. Variance of sequence: 0.8624
   (Conclusion: Variance is close to 1, condition satisfied.)

3. Test autocorrelation (using ACF plot):
   - ACF plot shows correlation between sequence and its lagged values.
   - For white noise, only lag=0 has correlation=1, others should be within confidence interval.

2.3 PACF检验(偏自相关函数检验)

PACF(Partial Autocorrelation Function)

  • 衡量序列与其第k阶滞后之间的直接相关性
  • 直观理解:把中间滞后项(lag=1...k-1)的影响剔除后,看 y(t) 与 y(t-k) 是否仍有线性关系

ACF vs PACF

  • ACF:总体相关性(包含间接影响)
  • PACF:直接相关性(剔除间接影响)

对白噪声的判断

  • 如果各滞后阶(lag>0)都落在置信区间内,说明没有显著相关性,序列可能是白噪声
python 复制代码
# 绘制PACF图
fig, ax = plt.subplots(figsize=(12, 5))
plot_pacf(random_sequence, lags=40, ax=ax, alpha=0.05)  # alpha=0.05表示95%置信区间
ax.set_title('PACF Plot of White Noise Sequence', fontsize=14)
ax.set_xlabel('Lag', fontsize=12)
ax.set_ylabel('Partial Autocorrelation', fontsize=12)
plt.tight_layout()
plt.show()

2.4 Ljung-Box检验

检验目的:综合检验多个滞后阶的自相关性是否显著

假设设定

  • 原假设 (H0):序列是白噪声(各阶自相关系数都为0)
  • 备择假设 (H1):序列不是白噪声

判断标准

  • p-value >= 0.05 -> 无法拒绝原假设,认为序列是白噪声
  • p-value < 0.05 -> 拒绝原假设,认为序列不是白噪声
python 复制代码
# Ljung-Box检验
print("=" * 50)
print("Ljung-Box Test")
print("=" * 50)
print("   - H0: Sequence is white noise.")
print("   - Criterion: If p-value >= 0.05, cannot reject H0, sequence is white noise.")

# 执行Ljung-Box检验,检查前10、20、30个滞后项
ljung_box_result = acorr_ljungbox(random_sequence, lags=[10, 20, 30], return_df=True)

print("\nLjung-Box Test Results:")
print(ljung_box_result)

# 结论解释
print("\n--- Test Conclusion ---")
last_p_value = ljung_box_result.iloc[-1]['lb_pvalue']  # 获取最后一个滞后阶的p值

if last_p_value < 0.05:
    print(f"At lag 30, p-value ({last_p_value:.4f}) < 0.05.")
    print("Conclusion: Reject H0, sequence is NOT white noise.")
else:
    print(f"At lag 30, p-value ({last_p_value:.4f}) >= 0.05.")
    print("Conclusion: Cannot reject H0, sequence IS white noise.")
复制代码
==================================================
Ljung-Box Test
==================================================
   - H0: Sequence is white noise.
   - Criterion: If p-value >= 0.05, cannot reject H0, sequence is white noise.

Ljung-Box Test Results:
      lb_stat  lb_pvalue
10   8.849179   0.546474
20  18.264036   0.570020
30  21.000649   0.887868

--- Test Conclusion ---
At lag 30, p-value (0.8879) >= 0.05.
Conclusion: Cannot reject H0, sequence IS white noise.

结果解读

  • lb_stat:Ljung-Box统计量的值(证据强度)
  • lb_pvalue:p值(判断依据)
  • 行索引 10, 20, 30:综合考虑了前10个、前20个、前30个滞后项的自相关性

所有的p值都远大于0.05,代表无法拒绝原假设,序列是白噪声。


三、平稳性检验

3.1 平稳性的定义

为什么要检验平稳性?

  • 如果一个序列不是白噪声,说明它包含可预测的规律
  • 但在寻找规律前,我们需要确认这个规律本身是否稳定
  • 平稳性是很多经典模型(如ARIMA)能够有效工作的前提

平稳序列的特征

  • 统计特性(均值、方差)不随时间变化
  • 序列中的规律是可重复、可学习的

非平稳序列的例子

  • 持续上涨的股票价格(均值在变)
  • 夏天销量高、冬天销量低的冰淇淋销售数据(存在季节性)

注意:白噪声虽然看起来很乱,但实际上是平稳的(均值和方差恒定)。

3.2 ADF检验(单位根检验)

检验目的:判断时间序列是否平稳

假设设定

  • 原假设 (H0):序列是非平稳的(存在单位根)
  • 备择假设 (H1):序列是平稳的

判断规则

  • p-value < 0.05 -> 拒绝原假设,认为序列是平稳的
  • p-value >= 0.05 -> 无法拒绝原假设,认为序列是非平稳的

辅助判断

  • 如果ADF统计量 < 临界值(如5%临界值),也表明序列是平稳的
python 复制代码
# ADF平稳性检验
print("Starting ADF Stationarity Test...")

# 执行ADF检验
adf_result = adfuller(random_sequence)

# 提取并展示主要结果
adf_statistic = adf_result[0]  # ADF统计量
p_value = adf_result[1]  # p值
critical_values = adf_result[4]  # 临界值

print(f"ADF Statistic: {adf_statistic:.4f}")
print(f"p-value: {p_value:.4f}")
print("Critical Values:")
for key, value in critical_values.items():
    print(f'    {key}: {value:.4f}')

print("\n--- Test Conclusion ---")
# 根据p值进行判断
if p_value < 0.05:
    print(f"p-value ({p_value:.4f}) < 0.05, strongly reject H0.")
    print("Conclusion: Sequence is Stationary.")
else:
    print(f"p-value ({p_value:.4f}) >= 0.05, cannot reject H0.")
    print("Conclusion: Sequence is Non-stationary.")

# 通过比较ADF统计量和临界值来判断
if adf_statistic < critical_values['5%']:
    print("\nAdditional: ADF statistic < 5% critical value, also indicates stationarity.")
复制代码
Starting ADF Stationarity Test...
ADF Statistic: -14.7442
p-value: 0.0000
Critical Values:
    1%: -3.4636
    5%: -2.8762
    10%: -2.5746

--- Test Conclusion ---
p-value (0.0000) < 0.05, strongly reject H0.
Conclusion: Sequence is Stationary.

Additional: ADF statistic < 5% critical value, also indicates stationarity.

四、季节性检验

4.1 季节性的定义

什么是季节性?

  • 时间序列中以固定、已知的频率重复出现的模式或周期性波动
  • 可以理解为数据的心跳或呼吸,有规律、可预测

季节性的例子

  • 冰淇淋销量:每年夏天达到高峰,冬天降到谷底(周期:12个月)
  • 工作日用电量:每天早上8点开始攀升,晚上回落(周期:24小时)
  • 零售业销售额:每年第四季度(节假日)最高(周期:4个季度)

季节性 vs 周期性

  • 季节性:频率固定且已知(年、季度、月、周、日)
  • 周期性:模式长度可变且不固定(如商业周期)

为什么要检验季节性?

  • 季节性是数据中最强大、最明显的预测信号之一
  • 如果模型不能识别和利用季节性,预测结果将出现系统性的周期性误差

4.2 通过ACF图检测季节性

ACF图的季节性特征

  • 如果序列存在季节性,ACF图会在代表季节性周期的滞后点上出现显著的尖峰
  • 例如:月度数据(年度季节性,周期为12),在 lag=12, 24, 36, ... 的位置会看到很高的相关性
python 复制代码
# 生成具有季节性的序列
np.random.seed(42)
n = 120  # 10年的月度数据
time = np.arange(n)

# 创建季节性成分(周期为12个月)
seasonal_component = 10 * np.sin(2 * np.pi * time / 12)

# 创建趋势成分
trend_component = 0.1 * time

# 创建随机噪声
noise = np.random.randn(n) * 2

# 合成序列
seasonal_series = seasonal_component + trend_component + noise

# 可视化
fig, axes = plt.subplots(2, 1, figsize=(14, 8))

# 绘制时序图
axes[0].plot(seasonal_series, label='Seasonal Series', color='blue')
axes[0].set_title('Time Series with Seasonality', fontsize=14)
axes[0].set_xlabel('Time (Month)', fontsize=12)
axes[0].set_ylabel('Value', fontsize=12)
axes[0].legend()
axes[0].grid(True, linestyle='--', alpha=0.6)

# 绘制ACF图
plot_acf(seasonal_series, lags=40, ax=axes[1], alpha=0.05)
axes[1].set_title('ACF Plot of Seasonal Series', fontsize=14)
axes[1].set_xlabel('Lag', fontsize=12)
axes[1].set_ylabel('Autocorrelation', fontsize=12)

plt.tight_layout()
plt.show()

print("\n--- Seasonality Analysis ---")
print("Observe the ACF plot: significant spikes at lag=12, 24, 36...")
print("This indicates the series has seasonality with period=12 (annual seasonality).")
复制代码
--- Seasonality Analysis ---
Observe the ACF plot: significant spikes at lag=12, 24, 36...
This indicates the series has seasonality with period=12 (annual seasonality).

4.3 通过序列分解检测季节性

思路:把序列拆分为 趋势(Trend) + 季节性(Seasonal) + 残差(Residual)

解读要点

  • Seasonal部分是否呈现稳定重复的周期
  • Resid残差不一定是白噪声:如果残差仍有结构,说明还存在可学习的信息(可进一步对残差画ACF或做Ljung-Box检验)
python 复制代码
# 序列分解(加法模型)
series = pd.Series(seasonal_series)
decomposition = seasonal_decompose(series, model='additive', period=12)

fig = decomposition.plot()
fig.set_size_inches(14, 8)
plt.suptitle('Time Series Decomposition', y=1.02, fontsize=16)
plt.show()

# 可选:对残差画ACF,查看是否接近白噪声
resid = decomposition.resid.dropna()
fig, ax = plt.subplots(figsize=(12, 5))
plot_acf(resid, lags=40, ax=ax, alpha=0.05)
ax.set_title('ACF Plot of Residual', fontsize=14)
ax.set_xlabel('Lag', fontsize=12)
ax.set_ylabel('Autocorrelation', fontsize=12)
plt.tight_layout()
plt.show()

五、总结

5.1 检验流程

在进行时间序列分析前,建议按以下顺序进行检验:

  1. 白噪声检验:确认数据是否具有可预测性

    • 使用ACF/PACF图和Ljung-Box检验
    • 如果是白噪声,则无法进行有效预测
  2. 平稳性检验:确认数据的统计特性是否稳定

    • 使用ADF检验
    • 如果非平稳,需要进行差分等处理
  3. 季节性检验:识别数据中的周期性模式

    • 观察ACF图中的周期性尖峰,或使用序列分解
    • 如果存在季节性,需要在模型中考虑

5.2 检验方法速查表

检验类型 方法 原假设 判断标准
白噪声检验 ACF/PACF图 - 观察滞后项是否落在置信区间
白噪声检验 Ljung-Box 序列是白噪声 p >= 0.05 无法拒绝
平稳性检验 ADF 序列非平稳 p < 0.05 拒绝(平稳)
季节性检验 ACF图 - 观察周期性尖峰
季节性检验 序列分解 - 观察Seasonal是否周期重复

@浙大疏锦行

相关推荐
weixin_438077492 分钟前
CS336 Assignment 4 (data): Filtering Language Modeling Data 翻译和实现
人工智能·python·语言模型·自然语言处理
合方圆~小文2 分钟前
工业摄像头工作原理与核心特性
数据库·人工智能·模块测试
小郭团队3 分钟前
未来PLC会消失吗?会被嵌入式系统取代吗?
c语言·人工智能·python·嵌入式硬件·架构
Aaron15883 分钟前
全频段SDR干扰源模块设计
人工智能·嵌入式硬件·算法·fpga开发·硬件架构·信息与通信·基带工程
摆烂咸鱼~4 分钟前
机器学习(9-2)
人工智能·机器学习
超的小宝贝5 分钟前
机器学习期末复习
深度学习·机器学习·强化学习
环黄金线HHJX.6 分钟前
拼音字母量子编程PQLAiQt架构”这一概念。结合上下文《QuantumTuan ⇆ QT:Qt》
开发语言·人工智能·qt·编辑器·量子计算
子夜江寒6 分钟前
基于PyTorch的CBOW模型实现与词向量生成
pytorch·python
sonadorje11 分钟前
谈谈贝叶斯回归
人工智能·数据挖掘·回归
Python极客之家12 分钟前
基于深度学习的刑事案件智能分类系统
人工智能·python·深度学习·机器学习·数据挖掘·毕业设计·情感分析