# 3.1.1 理解平稳性

许多时间序列的统计学模型都是依赖于时间序列是平稳的这一前提条件，通常来说，一个平稳的时间序列指的是这个时间序列在一段时间内具有稳定的统计值，如均值，方差。由于我们对于一个数据是否平稳是有自己的直觉的，所以在实践的过程中要谨防过于依赖直觉而被直觉所欺骗。

为此我们引入了一些统计上的假设检验来测试一个时间序列数据的平稳性。

其中Augmented Dickey Fuller Test (ADF Test) 是最常使用的一种方法，ADF test也是单位根检验（unit root test）的一种。单位根是一个使得时间序列非平稳的一个特征，从技术上说，在下面的公式中如果alpha=1，那么我们说存在单位根。

$$
Y\_t = \alpha Y\_{t-1} + \beta X\_e + \epsilon
$$

其中$$Yt，Y{t-1}$$分别表示t时刻和t-1时刻的时间序列值，$$X\_e$$表示外生变量，$$\epsilon$$表示误差项。

从直觉上我们可以理解为，只有当alpha<1时，整个时间序列的趋势才是有可能出现逆转的。而ADF test就是对alpha值的假设检验，它的原假设是alpha =1，即原假设成立，则时间序列非平稳。

但是我们需要记住，ADF test不是一个永远行之有效的方法，它存在一些不足：

* 对于区分近似单位根(near unit roots)和单位根不是很有效
* 当数据点很少时，容易出现假阳性的问题
* 大多数测试不会检测所有导致非平稳的因素，例如有些测试只是检验均值或方差两者之一是否平稳，有些测试只是检验总体分布。因此在使用任何假设检验时都要先充分理解数据的特点和检验的限制因素。

此外还有一种Kwiatkowski-Phillips-Schmidt-Shin (KPSS) test也是常用的时间序列平稳性假设检验，它和ADF的区别是KPSS的原假设是关于平稳过程，而ADF的原假设是关于单位根。

时间序列平稳性的重要性在于：

1. 大量的统计学模型基于平稳性的假设
2. 对于一个应用于非平稳时间序列的模型，它的准确性和模型指标会随着时间序列本身变化而变化，从而造成模型本身不稳定。

而对于一个非平稳的时间序列，其实是可以通过一些简单的变换使之变成平稳性的。log变换和平方根变换是两个常用的方式，其适用于非等方差的场景。另外可以通过差分的方式消除时间序列趋势。

**Python代码实现**

```python
from statsmodels.tsa.stattools import adfuller
import pandas as pd
import numpy as np
%matplotlib inline
```

```python
# 导入原始数据
url = 'data/a10.csv'
df = pd.read_csv(url, parse_dates=['date'], index_col='date')
series = df.loc[:, 'value'].values
df.plot(figsize=(14,8), legend=None, title='a10 - Drug Sales Series')
```

```python
# 使用ADF Test
result = adfuller(series, autolag='AIC')
print(f'ADF Statistic: {result[0]}')
print(f'n_lags: {result[1]}')
print(f'p-value: {result[1]}')
```

![](https://3993849477-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhv1ams1lvf_fMUn_is%2F-MiFR7EXWOKmUDP-2U9g%2F-MiFSgRSH4OUUGSmBzB2%2F3_1.png?alt=media\&token=635b67f4-db13-41da-89c7-125e38e3e3db)

```
ADF Statistic: 3.1451856893067363
n_lags: 1.0
p-value: 1.0
```

**p值为1表示没有理由拒绝原假设，也就是存在单位根，时间序列非平稳，这也和我们的直觉是相符的**

```python
# 生产一组随机数检验平稳性
series1 = np.random.randn(100)
plt.plot(series1)
```

![](https://3993849477-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mhv1ams1lvf_fMUn_is%2F-MiFR7EXWOKmUDP-2U9g%2F-MiFSjD2QgW4ow-qIIGc%2F3_2.png?alt=media\&token=857ada05-c99c-4727-b764-6e9aadeaf842)

```python
result1 = adfuller(series1, autolag='AIC')
print(f'ADF Statistic: {result1[0]}')
print(f'p-value: {result1[1]}')
```

```
ADF Statistic: -9.588680806555054
p-value: 2.0639843020333296e-16
```

**p值远远小于0.05，表示拒绝原假设，即时间序列是平稳的**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://skywateryang.gitbook.io/timeseriesanalysis101/untitled-1/3.1-zhen-dui-shi-jian-xu-lie-de-te-shu-fang-fa/3.1.1-li-jie-ping-wen-xing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
