3.3 趋势的去除与平稳化


3.3 趋势的去除与平稳化:差分

本节摘要:去趋势是把估计出的趋势"减掉",差分则是让序列逐项相减。两者都能让非平稳序列变得平稳,是 ARIMA 等下游方法的前提。本节给出"先减后差"还是"先差后减"的工程取舍,并演示 ADF 检验如何确认序列已经平稳。

学习目标速览

阅读完本节,你应当能够:

  1. 区分"去趋势(detrend)"和"差分(differencing)"两种平稳化方法。
  2. 写出 df.shift(1)df.diff(1) 的关系,并解释 lag-k 差分的几何含义。
  3. 用 ADF 检验判断序列是否平稳,并解释 p 值的工程解读。

本节把 3.2 估计出的趋势"剥掉"——但用差分而不是减法,给 ARIMA 等下游方法铺路。读完后你掌握"ADF 检验帮选差分阶数"的工程流程。

一、为什么要"剥掉"趋势

ARIMA、Prophet 等很多下游方法对输入有一个隐含假设:序列是平稳的(均值和方差随时间不变)。带趋势的序列显然不平稳——均值随时间漂移。如果不平稳化,模型的"拟合优度"会被趋势主导,看不出真正的预测能力。

平稳化是"为下游方法铺路"。两条主流路径:

  • 去趋势(detrend):先估计出趋势 T(t),然后计算 y'(t) = y(t) - T(t)。结果序列不再有趋势,但仍可能带季节性。
  • 差分(differencing):直接计算 Δy(t) = y(t) - y(t-1),不去估计趋势,靠"逐项相减"消除任何非平稳结构。

💡 关键直觉:差分不需要先估计趋势——它对所有非平稳(趋势、周期、漂移)一视同仁。这是为什么 ARIMA 的 d 阶差分被广泛使用:它不需要事先知道趋势是什么形态。

二、差分的工程实现

import pandas as pd import numpy as np # 一阶差分:y(t) - y(t-1) df = pd.DataFrame({"y": [10, 12, 13, 16, 20, 18, 22, 25]}) df["diff1"] = df["y"].diff(1) # 一阶差分 df["diff2"] = df["y"].diff(1).diff(1) # 二阶差分(在 diff1 上再做一阶) print(df)

直观理解:

  • 一阶差分消除线性趋势。线性 y = a + bt 差分后变常数 b
  • 二阶差分消除二次趋势。二次 y = a + bt + ct² 差分两次后变常数 2c
  • 季节差分消除季节性。y(t) - y(t-m)(m 是周期长度)消除固定周期模式。
# 季节差分(m=7:周季节性) df["diff7"] = df["y"].diff(7)

三、先减后差 vs 先差后减

一个常见困惑:先估计趋势、减掉、再做差,还是先做差、再估计趋势?

顺序 优点 缺点
先减后差 解释清晰,趋势项被显式分离 趋势估计误差会进入差分结果
先差后减 一步到位,模型更稳 差分后序列难解释

工程上更推荐先差后减

# 推荐写法:先用一阶差分让序列平稳,再估计剩余趋势 y_diff = s.diff(1).dropna() # 此时 y_diff 的趋势被消除,可以做 ARIMA 拟合 from statsmodels.tsa.arima.model import ARIMA model = ARIMA(s, order=(1, 1, 1)).fit()

⚠️ 常见坑:过度差分。二阶差分在原本已经平稳的序列上做会引入虚假自相关(差分运算本身就是一种滤波器)。一个经验法则:差分后如果方差比原序列更大,往往是过度差分;回到上一阶差分。

四、用 ADF 检验确认"已经平稳"

差分几次才够?最稳的办法是 ADF 检验(Augmented Dickey-Fuller Test):

  • 原假设 H₀:序列存在单位根(非平稳)。
  • 如果 p 值 < 0.05,拒绝 H₀ → 序列平稳。
from statsmodels.tsa.stattools import adfuller def adf_report(y, name="原序列"): stat, p, *_ = adfuller(y, autolag="AIC") print(f"{name}: ADF stat = {stat:.3f}, p = {p:.4f}", "→", "平稳" if p < 0.05 else "非平稳") adf_report(s, "原序列(含趋势)") adf_report(s.diff(1).dropna(), "一阶差分后") adf_report(s.diff(1).diff(1).dropna(), "二阶差分后") # 经验:通常一阶差分就够;过多阶差分会破坏信息

五、季节差分单独拎出来

对于带强季节性的序列(如月度数据有 12 个月周期),普通差分可能不够。季节差分 y(t) - y(t-12) 在月度数据上常常能让序列平稳化。但要注意:

  • 季节差分后仍可能带趋势,需要再叠加普通差分:y(t) - y(t-1) - y(t-12) + y(t-13)
  • 这就是 SARIMA 中 (D=1, m=12) 的来源。

六、回到业务:差分后预测怎么做

差分后的预测需要"还原"为原尺度:

# ARIMA(1,1,1) 模型 model = ARIMA(s, order=(1, 1, 1)).fit() forecast = model.forecast(steps=12) # forecast 自动还原差分,给出原尺度预测

statsmodels 的 forecast / get_forecast 会自动还原差分;如果你用底层实现手动算,记得把差分结果 cumsum 回去再加回最后一个观测值。

本节要点回顾

  • 去趋势 vs 差分:去趋势需要先估计趋势,差分直接逐项相减、不需要。
  • 工程推荐:先差分后估计,简单稳定;ARIMA 的 d 阶差分是这一思想的标准实现。
  • 差分阶数选择:ADF 检验。一般 1 阶够;过多阶会破坏信息。
  • 季节差分y(t) - y(t-m),常用于月度或季度数据;可以和普通差分叠加使用。
  • 下一章线索:4 章进入"季节性"专项——比趋势更精细、需要更长历史的周期信号。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U