7.2 时间序列基础(Time Series Basics)
"The only relevant test of the validity of a hypothesis is comparison of prediction with experience.""检验假设有效性的唯一相关测试是将预测与经验进行比较。"— Milton Friedman, 1976 Nobel Laureate in Economics (1976年诺贝尔经济学奖得主)
理解时间序列数据的特性与平稳性检验
本节目标
完成本节后,你将能够:
- 理解时间序列数据的核心特征
- 使用 pandas 处理时间序列数据
- 掌握平稳性的概念和重要性
- 实施 ADF、KPSS、PP 检验
- 应用差分和变换技术
- 分析真实经济数据的平稳性
时间序列数据的特征
时间序列的定义
时间序列是按时间顺序排列的一组观测值:
时间序列的核心特征
| 特征 | 描述 | 例子 |
|---|---|---|
| 时间依赖性 | 观测值之间存在相关性 | 今天的股价依赖昨天的股价 |
| 趋势 | 长期上升或下降的运动 | GDP 长期增长趋势 |
| 季节性 | 固定周期的波动 | 零售额的季度周期 |
| 周期性 | 非固定周期的波动 | 经济周期(4-7年) |
| 随机性 | 不可预测的波动 | 白噪声扰动项 |
Python 中的时间序列处理
pandas 时间序列核心功能
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 创建时间序列数据
dates = pd.date_range(start='2010-01-01', end='2023-12-31', freq='M')
np.random.seed(42)
values = 100 + np.cumsum(np.random.randn(len(dates)) * 2)
ts = pd.Series(values, index=dates)
print(ts.head())
print(f"\n数据类型: {type(ts.index)}")
print(f"频率: {ts.index.freq}")
print(f"时间范围: {ts.index.min()} 到 {ts.index.max()}")时间序列切片和索引
# 按年份选择
ts_2015 = ts['2015']
# 按日期范围选择
ts_range = ts['2015-01':'2016-12']
# 按条件筛选
ts_high = ts[ts > 110]
# 访问特定日期
value_jan_2015 = ts['2015-01-31']
print(f"2015年平均值: {ts_2015.mean():.2f}")
print(f"2015-2016年数据点数: {len(ts_range)}")重采样(Resampling)
# 降采样:月度 → 季度
ts_quarterly = ts.resample('Q').mean()
# 升采样:月度 → 日度(前向填充)
ts_daily = ts.resample('D').ffill()
# 降采样:不同聚合函数
ts_q_stats = pd.DataFrame({
'mean': ts.resample('Q').mean(),
'std': ts.resample('Q').std(),
'min': ts.resample('Q').min(),
'max': ts.resample('Q').max()
})
print("季度统计:")
print(ts_q_stats.head())滚动窗口(Rolling Windows)
# 移动平均
ts_ma_12 = ts.rolling(window=12).mean()
# 滚动标准差
ts_std_12 = ts.rolling(window=12).std()
# 可视化
fig, ax = plt.subplots(figsize=(14, 6))
ax.plot(ts, label='原始数据', alpha=0.6)
ax.plot(ts_ma_12, label='12个月移动平均', linewidth=2, color='red')
ax.fill_between(ts.index,
ts_ma_12 - 2*ts_std_12,
ts_ma_12 + 2*ts_std_12,
alpha=0.2, color='red', label='±2σ区间')
ax.set_title('时间序列与移动平均', fontsize=14, fontweight='bold')
ax.set_xlabel('时间')
ax.set_ylabel('值')
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()滞后和差分
# 滞后算子
ts_lag1 = ts.shift(1)
ts_lag12 = ts.shift(12)
# 一阶差分
ts_diff1 = ts.diff(1)
# 季节差分
ts_diff12 = ts.diff(12)
# 对数差分(近似增长率)
ts_log = np.log(ts)
ts_growth = ts_log.diff(1) * 100 # 百分比
print(f"平均月度增长率: {ts_growth.mean():.3f}%")
print(f"增长率标准差: {ts_growth.std():.3f}%")平稳性(Stationarity)
为什么平稳性重要?
统计推断的基础:
- 非平稳序列:统计性质随时间变化,样本统计量不可靠
- 平稳序列:统计性质恒定,样本均值/方差是总体的一致估计量
虚假回归(Spurious Regression):
- 两个独立的非平稳序列回归,可能得到显著但无意义的结果
- Granger & Newbold (1974): "nonsense correlations"
平稳性的数学定义
严格平稳(Strictly Stationary):
对所有 和 成立。
弱平稳/协方差平稳(Weakly Stationary/Covariance Stationary):
- 期望恒定: (常数)
- 方差恒定: (常数)
- 自协方差只依赖滞后长度:
实际应用中,我们通常关注弱平稳。
平稳性的直观判断
# 生成平稳和非平稳序列
np.random.seed(123)
n = 300
# 平稳序列:AR(1) with |ρ| < 1
rho = 0.7
stationary = np.zeros(n)
stationary[0] = np.random.randn()
for t in range(1, n):
stationary[t] = rho * stationary[t-1] + np.random.randn()
# 非平稳序列:随机游走(单位根)
random_walk = np.cumsum(np.random.randn(n))
# 非平稳序列:确定性趋势
trend = np.arange(n) * 0.05 + np.random.randn(n) * 2
# 可视化
fig, axes = plt.subplots(3, 2, figsize=(14, 10))
# 时间序列图
for i, (data, title) in enumerate([(stationary, '平稳: AR(1), ρ=0.7'),
(random_walk, '非平稳: 随机游走'),
(trend, '非平稳: 确定性趋势')]):
axes[i, 0].plot(data, linewidth=1.5)
axes[i, 0].set_title(title, fontsize=12, fontweight='bold')
axes[i, 0].set_ylabel('值')
axes[i, 0].grid(True, alpha=0.3)
# ACF 图
from statsmodels.graphics.tsaplots import plot_acf
plot_acf(data, lags=40, ax=axes[i, 1], alpha=0.05)
axes[i, 1].set_title(f'ACF: {title.split(":")[1]}', fontsize=12)
axes[2, 0].set_xlabel('时间')
axes[2, 1].set_xlabel('滞后阶数')
plt.tight_layout()
plt.show()关键观察:
- 平稳序列的 ACF 快速衰减
- 随机游走的 ACF 缓慢衰减(接近1)
- 趋势序列的 ACF 也缓慢衰减
平稳性检验
1. ADF 检验(Augmented Dickey-Fuller Test)
原假设:: 序列有单位根(非平稳)
备择假设:: 序列无单位根(平稳)
检验方程:
检验 (单位根)vs (平稳)
from statsmodels.tsa.stattools import adfuller
def adf_test(series, name=''):
"""执行 ADF 检验并打印结果"""
result = adfuller(series, autolag='AIC')
print(f'\n{"="*60}')
print(f'ADF 检验结果: {name}')
print(f'{"="*60}')
print(f'ADF 统计量: {result[0]:.4f}')
print(f'p-value: {result[1]:.4f}')
print(f'滞后阶数: {result[2]}')
print(f'观测数: {result[3]}')
print('临界值:')
for key, value in result[4].items():
print(f' {key}: {value:.4f}')
if result[1] <= 0.05:
print(f"\n结论: 拒绝原假设 (p={result[1]:.4f}) → 序列平稳 ")
else:
print(f"\n结论: 无法拒绝原假设 (p={result[1]:.4f}) → 序列非平稳 ")
return result
# 测试平稳和非平稳序列
adf_test(stationary, 'AR(1) 序列')
adf_test(random_walk, '随机游走')
adf_test(trend, '趋势序列')2. KPSS 检验(Kwiatkowski-Phillips-Schmidt-Shin Test)
原假设:: 序列平稳
备择假设:: 序列非平稳(有单位根)
️ 注意:KPSS 与 ADF 的原假设相反!
from statsmodels.tsa.stattools import kpss
def kpss_test(series, name='', regression='c'):
"""
执行 KPSS 检验
regression: 'c' (常数), 'ct' (常数+趋势)
"""
result = kpss(series, regression=regression, nlags='auto')
print(f'\n{"="*60}')
print(f'KPSS 检验结果: {name}')
print(f'{"="*60}')
print(f'KPSS 统计量: {result[0]:.4f}')
print(f'p-value: {result[1]:.4f}')
print(f'滞后阶数: {result[2]}')
print('临界值:')
for key, value in result[3].items():
print(f' {key}: {value:.4f}')
if result[1] >= 0.05:
print(f"\n结论: 无法拒绝原假设 (p={result[1]:.4f}) → 序列平稳 ")
else:
print(f"\n结论: 拒绝原假设 (p={result[1]:.4f}) → 序列非平稳 ")
return result
# 测试
kpss_test(stationary, 'AR(1) 序列')
kpss_test(random_walk, '随机游走')
kpss_test(trend, '趋势序列', regression='ct')3. PP 检验(Phillips-Perron Test)
原理:与 ADF 类似,但使用非参数方法处理序列相关性和异方差
from statsmodels.tsa.stattools import pp_test
def pp_test_custom(series, name=''):
"""执行 PP 检验"""
# 注意:statsmodels 0.13.0+ 才有 pp_test
try:
result = pp_test(series, lags='auto')
print(f'\n{"="*60}')
print(f'PP 检验结果: {name}')
print(f'{"="*60}')
print(f'PP 统计量: {result[0]:.4f}')
print(f'p-value: {result[1]:.4f}')
print('临界值:')
for key, value in result[4].items():
print(f' {key}: {value:.4f}')
if result[1] <= 0.05:
print(f"\n结论: 拒绝原假设 (p={result[1]:.4f}) → 序列平稳 ")
else:
print(f"\n结论: 无法拒绝原假设 (p={result[1]:.4f}) → 序列非平稳 ")
return result
except AttributeError:
print(f"\n️ 当前 statsmodels 版本不支持 pp_test,请升级到 0.13.0+")
print("pip install --upgrade statsmodels")
return None
pp_test_custom(stationary, 'AR(1) 序列')
pp_test_custom(random_walk, '随机游走')检验方法对比
| 检验 | 原假设 | 优势 | 适用场景 |
|---|---|---|---|
| ADF | 非平稳 | 最常用,稳健 | 通用检验 |
| KPSS | 平稳 | 与ADF互补 | 与ADF联合使用 |
| PP | 非平稳 | 处理异方差 | 高频金融数据 |
最佳实践:同时使用 ADF 和 KPSS
| ADF | KPSS | 结论 |
|---|---|---|
| 拒绝H0(平稳) | 不拒绝H0(平稳) | 确定平稳 |
| 不拒绝H0(非平稳) | 拒绝H0(非平稳) | 确定非平稳 |
| 拒绝H0 | 拒绝H0 | ️ 结果矛盾,检查数据 |
| 不拒绝H0 | 不拒绝H0 | ️ 不确定,需进一步分析 |
差分与变换
一阶差分(First Differencing)
# 对随机游走进行一阶差分
rw_diff = pd.Series(random_walk).diff().dropna()
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
axes[0].plot(random_walk)
axes[0].set_title('原始序列:随机游走(非平稳)', fontsize=12, fontweight='bold')
axes[0].set_ylabel('值')
axes[0].grid(True, alpha=0.3)
axes[1].plot(rw_diff)
axes[1].set_title('一阶差分后(平稳)', fontsize=12, fontweight='bold')
axes[1].set_ylabel('Δy')
axes[1].axhline(y=0, color='r', linestyle='--', alpha=0.5)
axes[1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 检验差分后的平稳性
adf_test(rw_diff, '随机游走(一阶差分后)')季节差分(Seasonal Differencing)
其中 是季节周期(例如,月度数据 ,季度数据 )
# 生成季节性数据
dates = pd.date_range('2010-01', periods=120, freq='M')
seasonal = 10 + 5*np.sin(2*np.pi*np.arange(120)/12) + np.random.randn(120)
trend_seasonal = seasonal + np.arange(120) * 0.1
ts_seasonal = pd.Series(trend_seasonal, index=dates)
# 应用差分
ts_diff1 = ts_seasonal.diff(1) # 一阶差分(去趋势)
ts_diff12 = ts_seasonal.diff(12) # 季节差分(去季节性)
ts_diff1_12 = ts_seasonal.diff(1).diff(12) # 组合差分
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
axes[0, 0].plot(ts_seasonal)
axes[0, 0].set_title('原始序列(趋势+季节性)', fontsize=12, fontweight='bold')
axes[0, 1].plot(ts_diff1)
axes[0, 1].set_title('一阶差分(去趋势)', fontsize=12, fontweight='bold')
axes[0, 1].axhline(y=0, color='r', linestyle='--', alpha=0.5)
axes[1, 0].plot(ts_diff12)
axes[1, 0].set_title('季节差分(去季节性)', fontsize=12, fontweight='bold')
axes[1, 0].axhline(y=0, color='r', linestyle='--', alpha=0.5)
axes[1, 1].plot(ts_diff1_12.dropna())
axes[1, 1].set_title('组合差分(去趋势+季节性)', fontsize=12, fontweight='bold')
axes[1, 1].axhline(y=0, color='r', linestyle='--', alpha=0.5)
for ax in axes.flat:
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()对数变换(Log Transformation)
用途:
- 稳定方差(对数方差接近常数)
- 将乘法模型转为加法模型
- 近似计算增长率
# 生成指数增长数据(异方差)
exp_data = 100 * np.exp(0.05 * np.arange(100)) + np.random.randn(100) * np.arange(100) * 0.5
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
axes[0].plot(exp_data)
axes[0].set_title('原始数据(异方差)', fontsize=12, fontweight='bold')
axes[0].set_ylabel('值')
axes[1].plot(np.log(exp_data))
axes[1].set_title('对数变换后(方差稳定)', fontsize=12, fontweight='bold')
axes[1].set_ylabel('log(值)')
for ax in axes:
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 计算增长率
growth_rate = pd.Series(np.log(exp_data)).diff() * 100
print(f"平均增长率: {growth_rate.mean():.2f}%")
print(f"增长率标准差: {growth_rate.std():.2f}%")Box-Cox 变换
自动寻找最优幂变换参数:
from scipy.stats import boxcox
# Box-Cox 变换
data_positive = exp_data - exp_data.min() + 1 # 确保正值
transformed, lambda_opt = boxcox(data_positive)
print(f"最优 λ 参数: {lambda_opt:.4f}")
fig, axes = plt.subplots(1, 3, figsize=(16, 5))
axes[0].plot(data_positive)
axes[0].set_title('原始数据', fontsize=12, fontweight='bold')
axes[1].plot(transformed)
axes[1].set_title(f'Box-Cox 变换 (λ={lambda_opt:.3f})', fontsize=12, fontweight='bold')
axes[2].hist(data_positive, bins=30, alpha=0.5, label='原始', density=True)
axes[2].hist(transformed, bins=30, alpha=0.5, label='变换后', density=True)
axes[2].set_title('分布对比', fontsize=12, fontweight='bold')
axes[2].legend()
for ax in axes:
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()完整案例:中国GDP增长率平稳性分析
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller, kpss
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# 模拟中国GDP数据(1978-2023,单位:亿元)
np.random.seed(2024)
years = pd.date_range('1978', '2023', freq='Y')
n = len(years)
# GDP水平:指数增长 + 周期 + 随机扰动
t = np.arange(n)
log_gdp = 8.5 + 0.12*t - 0.003*t**2 + 0.2*np.sin(2*np.pi*t/10) + np.random.randn(n)*0.05
gdp = np.exp(log_gdp)
# GDP增长率
gdp_growth = pd.Series(log_gdp).diff() * 100
gdp_growth = gdp_growth.dropna()
df_gdp = pd.DataFrame({
'year': years,
'gdp': gdp,
'log_gdp': log_gdp,
'growth_rate': [np.nan] + list(gdp_growth)
})
# 1. 可视化
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# GDP 水平
axes[0, 0].plot(df_gdp['year'], df_gdp['gdp'], linewidth=2)
axes[0, 0].set_title('中国GDP水平(1978-2023)', fontsize=12, fontweight='bold')
axes[0, 0].set_ylabel('GDP(亿元)')
axes[0, 0].grid(True, alpha=0.3)
# log(GDP)
axes[0, 1].plot(df_gdp['year'], df_gdp['log_gdp'], linewidth=2, color='orange')
axes[0, 1].set_title('log(GDP)', fontsize=12, fontweight='bold')
axes[0, 1].set_ylabel('log(GDP)')
axes[0, 1].grid(True, alpha=0.3)
# GDP 增长率
axes[1, 0].plot(df_gdp['year'][1:], df_gdp['growth_rate'][1:], linewidth=2, color='green')
axes[1, 0].axhline(y=df_gdp['growth_rate'].mean(), color='r', linestyle='--',
label=f'平均: {df_gdp["growth_rate"].mean():.2f}%')
axes[1, 0].set_title('GDP增长率', fontsize=12, fontweight='bold')
axes[1, 0].set_ylabel('增长率(%)')
axes[1, 0].legend()
axes[1, 0].grid(True, alpha=0.3)
# 增长率分布
axes[1, 1].hist(df_gdp['growth_rate'].dropna(), bins=15, edgecolor='black', alpha=0.7)
axes[1, 1].axvline(x=df_gdp['growth_rate'].mean(), color='r', linestyle='--', linewidth=2)
axes[1, 1].set_title('增长率分布', fontsize=12, fontweight='bold')
axes[1, 1].set_xlabel('增长率(%)')
axes[1, 1].set_ylabel('频数')
axes[1, 1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 2. 描述性统计
print("\n" + "="*60)
print("GDP 增长率描述性统计")
print("="*60)
print(df_gdp['growth_rate'].describe())
# 3. ACF/PACF 图
fig, axes = plt.subplots(3, 2, figsize=(14, 12))
# GDP 水平
plot_acf(df_gdp['gdp'].dropna(), lags=20, ax=axes[0, 0], alpha=0.05)
axes[0, 0].set_title('ACF: GDP水平', fontsize=12, fontweight='bold')
plot_pacf(df_gdp['gdp'].dropna(), lags=20, ax=axes[0, 1], alpha=0.05)
axes[0, 1].set_title('PACF: GDP水平', fontsize=12, fontweight='bold')
# log(GDP)
plot_acf(df_gdp['log_gdp'].dropna(), lags=20, ax=axes[1, 0], alpha=0.05)
axes[1, 0].set_title('ACF: log(GDP)', fontsize=12, fontweight='bold')
plot_pacf(df_gdp['log_gdp'].dropna(), lags=20, ax=axes[1, 1], alpha=0.05)
axes[1, 1].set_title('PACF: log(GDP)', fontsize=12, fontweight='bold')
# GDP 增长率
plot_acf(df_gdp['growth_rate'].dropna(), lags=20, ax=axes[2, 0], alpha=0.05)
axes[2, 0].set_title('ACF: GDP增长率', fontsize=12, fontweight='bold')
plot_pacf(df_gdp['growth_rate'].dropna(), lags=20, ax=axes[2, 1], alpha=0.05)
axes[2, 1].set_title('PACF: GDP增长率', fontsize=12, fontweight='bold')
plt.tight_layout()
plt.show()
# 4. 平稳性检验
def comprehensive_stationarity_test(series, name):
"""综合平稳性检验"""
print(f"\n{'='*70}")
print(f"平稳性检验: {name}")
print(f"{'='*70}")
# ADF 检验
adf_result = adfuller(series.dropna(), autolag='AIC')
print(f"\n【ADF 检验】(H0: 非平稳)")
print(f" 统计量: {adf_result[0]:.4f}")
print(f" p-value: {adf_result[1]:.4f}")
print(f" 临界值 (5%): {adf_result[4]['5%']:.4f}")
adf_conclusion = "平稳 " if adf_result[1] < 0.05 else "非平稳 "
print(f" 结论: {adf_conclusion}")
# KPSS 检验
kpss_result = kpss(series.dropna(), regression='c', nlags='auto')
print(f"\n【KPSS 检验】(H0: 平稳)")
print(f" 统计量: {kpss_result[0]:.4f}")
print(f" p-value: {kpss_result[1]:.4f}")
print(f" 临界值 (5%): {kpss_result[3]['5%']:.4f}")
kpss_conclusion = "平稳 " if kpss_result[1] > 0.05 else "非平稳 "
print(f" 结论: {kpss_conclusion}")
# 综合判断
print(f"\n【综合结论】")
if adf_result[1] < 0.05 and kpss_result[1] > 0.05:
print(f" 两项检验一致支持:序列平稳 ")
elif adf_result[1] >= 0.05 and kpss_result[1] <= 0.05:
print(f" 两项检验一致支持:序列非平稳 ")
else:
print(f" 检验结果矛盾,需进一步分析 ️")
# 检验 GDP 水平
comprehensive_stationarity_test(df_gdp['gdp'], 'GDP水平')
# 检验 log(GDP)
comprehensive_stationarity_test(df_gdp['log_gdp'], 'log(GDP)')
# 检验 GDP 增长率
comprehensive_stationarity_test(df_gdp['growth_rate'], 'GDP增长率')
# 5. 差分效果对比
print(f"\n{'='*70}")
print("一阶差分效果")
print(f"{'='*70}")
gdp_diff = df_gdp['gdp'].diff().dropna()
comprehensive_stationarity_test(gdp_diff, 'GDP水平(一阶差分后)')
# 6. 可视化总结
fig, axes = plt.subplots(3, 1, figsize=(14, 10))
axes[0].plot(df_gdp['year'], df_gdp['gdp'])
axes[0].set_title('GDP水平(非平稳)', fontsize=12, fontweight='bold')
axes[0].set_ylabel('GDP(亿元)')
axes[0].grid(True, alpha=0.3)
axes[1].plot(df_gdp['year'][1:], df_gdp['growth_rate'][1:], color='green')
axes[1].axhline(y=0, color='black', linestyle='-', linewidth=0.8)
axes[1].set_title('GDP增长率(平稳)', fontsize=12, fontweight='bold')
axes[1].set_ylabel('增长率(%)')
axes[1].grid(True, alpha=0.3)
axes[2].plot(df_gdp['year'][1:], gdp_diff, color='orange')
axes[2].axhline(y=0, color='black', linestyle='-', linewidth=0.8)
axes[2].set_title('GDP一阶差分(平稳)', fontsize=12, fontweight='bold')
axes[2].set_ylabel('Δ GDP')
axes[2].set_xlabel('年份')
axes[2].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
print("\n" + "="*70)
print(" 案例分析完成!")
print("="*70)
print("\n关键发现:")
print(" 1. GDP水平是I(1)序列(一阶单整),非平稳")
print(" 2. log(GDP)也是I(1)序列,非平稳")
print(" 3. GDP增长率是I(0)序列(平稳)")
print(" 4. 一阶差分可以使GDP水平变为平稳")
print("\n政策含义:")
print(" - 分析GDP增长率(而非水平)更可靠")
print(" - 回归分析时需要差分或协整检验")
print(" - 经济冲击对增长率的影响是暂时的")本节小结
核心概念
| 概念 | 定义 | 重要性 |
|---|---|---|
| 平稳性 | 统计性质不随时间变化 | 统计推断的基础 |
| 单位根 | AR(1)系数=1,序列非平稳 | 检验非平稳性 |
| 差分 | Δy = y_t - y_ | 将I(1)转为I(0) |
| 对数变换 | 稳定方差,近似增长率 | 处理指数增长数据 |
实践检查清单
- [ ] 绘制时间序列图,观察趋势/季节性
- [ ] 绘制 ACF/PACF 图,检查自相关结构
- [ ] 同时使用 ADF 和 KPSS 检验平稳性
- [ ] 如果非平稳,尝试差分或对数变换
- [ ] 验证变换后序列的平稳性
- [ ] 记录变换步骤(建模时需要反变换)
常见错误
避免:
- 只用 ADF 检验(可能得出错误结论)
- 过度差分(例如,对I(1)序列差分两次)
- 忽略季节性模式
- 对已平稳序列进行差分
推荐:
- ADF + KPSS 双重检验
- 可视化检查变换效果
- 理解数据的经济含义(例如,增长率通常平稳)
下节预告
在下一节中,我们将学习如何分解时间序列的趋势、季节性和随机成分。
掌握时间序列的基础!
延伸阅读
Dickey, D. A., & Fuller, W. A. (1979). "Distribution of the estimators for autoregressive time series with a unit root." Journal of the American Statistical Association, 74(366a), 427-431.
Kwiatkowski, D., et al. (1992). "Testing the null hypothesis of stationarity against the alternative of a unit root." Journal of Econometrics, 54(1-3), 159-178.
Hamilton, J. D. (1994). Time Series Analysis. Princeton University Press. (Chapters 15-17)
Enders, W. (2014). Applied Econometric Time Series (4th ed.). Wiley. (Chapter 4)