时间序列基础知识

1基础知识

识别时间序列中的模式,我们可以做的第一件事是将其分成具有易于理解特征的组件:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> X t = T t + S t + C t + I t \begin{equation} X_t = T_t + S_t + C_t + I_t \quad \end{equation} </math>Xt=Tt+St+Ct+It

  • T_t: 该趋势显示了长时间内时间序列数据的总体方向。它代表系列的长期进展(长期变化)
  • S_t: 具有固定和已知周期的季节性成分。当由于季节性因素(每年、每月或每周)在定期间隔之间观察到明显的重复模式时,就会观察到这种情况。明显的例子包括每日电力消耗模式或季节性商品的年销售额。
  • C_t: (可选)周期性成分是一种不以固定间隔出现的重复模式,通常在经济环境中观察,如商业周期。
  • I_t: 不规则分量(残差)由去除趋势和季节/周期变化后观察到的时间序列波动组成。

我们可能有不同的趋势和季节性组合。根据趋势和季节性的性质,时间序列可以建模为加法或乘法时间序列。系列中的每个观测值可以表示为分量的和或乘积。

值得指出的是,使用乘法分解的另一种方法是首先变换数据,直到序列中的变化看起来随时间稳定,然后使用加法分解。当使用对数变换时,这相当于使用乘法分解,因为
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> X t = T t ∗ S t ∗ I t \begin{equation} X_t = T_t * S_t * I_t \end{equation} </math>Xt=Tt∗St∗It
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 等价于 l o g X t = l o g T t + l o g S t + l o g I t 等价于\begin{equation} log X_t = log T_t + log S_t + log I_t \end{equation} </math>等价于logXt=logTt+logSt+logIt

下面是例子介绍

py 复制代码
series = pd.read_csv(CFG.data_folder + 'passengers.csv')
series['date'] = pd.to_datetime(series['date'])
series.set_index('date').plot()
py 复制代码
decomposition = sm.tsa.seasonal_decompose(series["passengers"],period= 12) figure = decomposition.plot()

趋势和季节性的表现或多或少与预期一致,但残差的行为显然随时间而不一致(样本中间的平均振荡水平与两端非常不同)。虽然有很多可能的原因,但一个快速的解释是序列分量之间的加法与乘法关系-这是我们可以快速检查的:

  • 使用乘法分解
py 复制代码
figure = decomposition.plot()
plt.show()

趋势和季节性成分没有太大的质的变化,但残差看起来在恒定水平附近更稳定------这种现象本身并不意味着平稳,但至少相反方向的明确信号不再存在。

2数学公式

补充一下概率论和数理统计知识


<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 时间序列的平均函数: μ t = E [ X t ] 时间序列的平均函数: \mu_t = E [X_t] </math>时间序列的平均函数:μt=E[Xt]
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 时间序列的自协方差函数: γ ( s , t ) = C o v ( X s , X t ) = E [ X s X t ] − E [ X s ] E [ X t ] 时间序列的自协方差函数: \gamma(s,t) = Cov(X_s, X_t) = E [X_s X_t] - E[X_s]E[X_t] </math>时间序列的自协方差函数:γ(s,t)=Cov(Xs,Xt)=E[XsXt]−E[Xs]E[Xt]

这引出了以下对 ACF/PACF 的定义: 成功预测的唯一方法是,如果一个序列的过去值携带了一些关于未来行为的信息,换句话说,如果当前值依赖于过去。一种快速且因此非常流行的检查这种相关性的方法是自相关函数和部分自相关函数,其定义如下:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 自相关 A C F : ρ ( u , t + u ) = C o r ( X u , X t + u ) = C o v ( X t , X t + u ) V a r ( X t ) V a r ( X t + u ) 自相关ACF: \begin{equation} \rho(u,t+u) = Cor(X_{u}, X_{t+u}) = \frac{Cov(X_t, X_{t+u})}{Var(X_t) Var(X_{t+u})} \end{equation} </math>自相关ACF:ρ(u,t+u)=Cor(Xu,Xt+u)=Var(Xt)Var(Xt+u)Cov(Xt,Xt+u)
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 部分自相关: ϕ ( u ) = C o r ( X t , X t + u ∣ X t + 1 , ... , X t + u − 1 ) 部分自相关: \begin{equation} \phi(u) = Cor(X_t, X_{t+u}|X_{t+1}, \ldots , X_{t+u-1}) \end{equation} </math>部分自相关:ϕ(u)=Cor(Xt,Xt+u∣Xt+1,...,Xt+u−1)

表示的是:用两个变量的协方差 除以两个变量标准差的乘积

  • Cov(X,Y):表示的是协方差
  • Var[X]:表示的是方差,开根号之后就变成了标准差

⚠️总结:两个变量之间的Pearson相关系数定义为两个变量之间的协方差标准差的商

平稳性

为了更正式地定义事物,平稳时间序列是指无条件联合概率分布在时间上移动时不发生变化的时间序列。这意味着均值和方差等参数也不会随时间变化。

由于平稳性是时间序列分析中使用的许多统计程序的基础假设,因此非平稳数据通常被转换为平稳数据。趋势平稳过程并不是严格的平稳过程,但可以通过去除基本趋势(它只是时间的函数)而容易地转变为平稳过程;对于具有附加循环分量的平稳过程也是如此。

核心思想是,如果统计特性不发生变化,就更容易对随时间变化的动态行为进行建模:振荡发生在同一水平附近,振幅不会发生太大变化等(换句话说,x_t 的概率分布与 x_{t+h} 的分布相同)-这类模型很容易理解。如果我们将算法应用于平稳过程,算法可能会产生更好的预测,因为我们不需要担心例如训练和测试集之间的概念漂移。

如果我们处理的是一个不符合这些特征的过程,我们可以尝试直接捕捉它们,或者以一种可以被视为静止的方式对其进行转换。

下面我们从最简单的非平凡平稳序列:高斯白噪声开始,绘制了平稳和非平稳序列的几个例子

py 复制代码
xseries = pd.DataFrame(data = np.random.normal(0, 1, 10000), columns = ['noise'] )
xseries.plot()
print()

理论

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 给定一个随机过程 X _ t , 和 c d f F _ x , 一个过程是严格平稳的 F X ( X t 1 , ... , X t n ) = F X ( X t 1 + τ , ... , X t n + τ ) 这个定义非常强大(如果我们知道一个分布的 c d f ,我们可以推断出一切) ------然而,在实践中无法验证。因此,引入了一个不太严格的变体:弱二阶平稳性: − 弱相关如果过程 { X t } 满足以下条件,则它是弱平稳的: μ t = μ t + τ γ ( s , t ) = γ ( s − t ) V a r ( X t ) < ∞ \begin{equation} \begin{aligned} 给定一个随机过程 {X\t},和cdfF\x ,一个过程是严格平稳的\\ F_X(X{t_1}, \ldots, X{t_n}) = F_X(X_{t_1 + \tau}, \ldots, X_{t_n + \tau}) && \end{aligned} \end{equation} \\这个定义非常强大(如果我们知道一个分布的 cdf,我们可以推断出一切) \\------然而,在实践中无法验证。因此,引入了一个不太严格的变体:弱二阶平稳性: \\- 弱相关如果过程\{X_t\} 满足以下条件,则它是弱平稳的: \\ \mu_t = \mu_{t + \tau} \\ \gamma(s,t) = \gamma(s-t) \\ Var(X_t) < \infty </math>给定一个随机过程X_t,和cdfF_x,一个过程是严格平稳的FX(Xt1,...,Xtn)=FX(Xt1+τ,...,Xtn+τ)这个定义非常强大(如果我们知道一个分布的cdf,我们可以推断出一切)------然而,在实践中无法验证。因此,引入了一个不太严格的变体:弱二阶平稳性:−弱相关如果过程{Xt}满足以下条件,则它是弱平稳的:μt=μt+τγ(s,t)=γ(s−t)Var(Xt)<∞

含义:

  • 常数平均值
  • 协方差仅取决于变量之间的时间距离
  • 自相关:

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> a u t o c o r r e l a t i o n : ρ ( u ) = γ ( u ) γ ( 0 ) autocorrelation: \begin{equation} \rho(u) = \frac{\gamma(u)}{\gamma(0)} \end{equation} </math>autocorrelation:ρ(u)=γ(0)γ(u)

平稳性试验

虽然在转换前/转换后检查曲线有助于评估趋势或季节性的存在(正如我们在上面对乘客数据集所做的那样),但实际上我们需要一种更正式的方法------比如测试假设。

处理平稳性的最流行测试是:

  • Augmented Dickey-Fuller (ADF))
  • Kwiatkowski--Phillips--Schmidt--Shin (KPSS)
  • Philips-Perron (PP)

ADF测试是一种单位根测试。它决定了趋势对时间序列的定义程度。

  • 零假设(H0):测试的零假设是时间序列可以用非平稳的单位根表示。
  • 替代假设(H1):测试的替代假设是时间序列是平稳的。

p值的解释:

  • 上面的\alpha:接受空假设(H0),数据具有单位根并且是非平稳的。
  • 低于\alpha:拒绝空假设(H0),数据是固定的。

这里用ADF进行演示

py 复制代码
# 计算 Augmented Dickey-Fuller (ADF) 检验
result = adfuller(np.array(agricultural_data).ravel(), regression='c')

# 打印 ADF 检验结果
print('ADF Statistic: %f' % result[0])
print('p-value: %f' % result[1])
print('Critical Values:')
for key, value in result[4].items():
    print('%s: %.3f' % (key, value))

# 判断时间序列是否为平稳序列
if result[0] < result[4]['1%']:
    print('时间序列是平稳序列.')
else:
    print('时间序列不是平稳序列')

# 判断时间序列是否为纯随机序列
if result[1] > 0.05:
    print('时间序列是随机的。')
else:
    print('时间序列不是随机的。')
makefile 复制代码
结果:
ADF Statistic: -1.117544
p-value: 0.708025
Critical Values:
1%: -3.568
5%: -2.921
10%: -2.599
时间序列不是平稳序列
时间序列是随机的。

非平稳序列变成平稳序列

  • 差分序列
  • log转换
  • 其他转换

这边展示差分的方法

py 复制代码
plt.figure(figsize=(15, 4))
plt.plot(pig_data, 'ro-')
plt.ylabel('Number of pigs slaughtered per month')
plt.show()
py 复制代码
pig_data_diff = np.diff(pig_data.values.flatten())
plt.plot(pig_data_diff, color='red', alpha=0.6)
plt.title('Differenced Series (Order 1)')
plt.show()

可以看到序列在差分一次之后变得平稳

原教程

中文版

相关推荐
高洁0132 分钟前
DNN案例一步步构建深层神经网络(二)
人工智能·python·深度学习·算法·机器学习
Insight.39 分钟前
背包问题——01背包、完全背包、多重背包、分组背包(Python)
开发语言·python
Lucky高44 分钟前
Pandas库实践1_预备知识准备
python·pandas
Salt_07281 小时前
DAY 36 官方文档的阅读
python·算法·机器学习·github
k***92161 小时前
Python 科学计算有哪些提高运算速度的技巧
开发语言·python
superman超哥1 小时前
仓颉条件变量深度解析与实践:解锁高效并发同步
开发语言·python·c#·仓颉
长空任鸟飞_阿康1 小时前
LangGraph 技术详解:基于图结构的 AI 工作流与多智能体编排框架
人工智能·python·langchain
love530love2 小时前
ComfyUI 升级 v0.4.0 踩坑记录:解决 TypeError: QM_Queue.task_done() 报错
人工智能·windows·python·comfyui
阿坤带你走近大数据3 小时前
Python基础知识-数据结构篇
开发语言·数据结构·python
小智RE0-走在路上3 小时前
Python学习笔记(7)--集合,字典,数据容器总结
笔记·python·学习