一、学习内容
在本节中,我们将综合应用前几周学习的时间序列分析与预测方法,完成一个完整的时间序列预测项目,包含从数据预处理、异常检测、模型选择、预测到评估的全流程。项目流程:
1. 数据获取与预处理
- 数据加载,处理缺失值和异常值。
- 数据的季节性分解和趋势分析。
2. 模型选择与预测
- 选择适合的时间序列预测模型,如 ARIMA、SARIMA、Holt-Winters 等。
- 使用滚动预测或多步预测方法进行预测。
3. 模型评估
- 使用 MAE、MSE 和 RMSE 等指标评估模型性能。
4. 结果可视化
- 绘制原始数据、预测值和置信区间。
二、实战案例
在此示例中,我们使用著名的航空乘客数据集 (Airline Passengers Dataset),该数据集记录了1949年到1960年每月的国际航空乘客人数。
1. 数据加载与预处理
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.statespace.sarimax import SARIMAX
from statsmodels.tsa.holtwinters import ExponentialSmoothing
from sklearn.metrics import mean_absolute_error, mean_squared_error
# 1. 数据加载与预处理
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv'
data = pd.read_csv(url, header=0, parse_dates=['Month'], index_col='Month')
# 绘制原始数据
plt.figure(figsize=(10, 6))
plt.plot(data['Passengers'], label='Airline Passengers')
plt.title('Airline Passengers Dataset')
plt.xlabel('Date')
plt.ylabel('Passengers')
plt.legend()
plt.grid(True)
plt.show()
代码解释:
- 我们从公开的 URL 加载航空乘客数据,解析日期并将其设置为索引。数据记录的是每月的国际航空乘客数量。
- 首先绘制时间序列,展示乘客数量随时间的变化趋势。
结果输出:
2. 时间序列分解
# 2. 时间序列分解
result = seasonal_decompose(data['Passengers'], model='multiplicative', period=12)
result.plot()
plt.show()
代码解释:
- 使用
seasonal_decompose
对时间序列进行分解,将其分为趋势、季节性和随机成分。这一步帮助我们理解数据的长期趋势和季节性波动。
结果输出:
3. SARIMA 模型选择与预测
# 3. 模型选择与预测:SARIMA 模型
sarima_model = SARIMAX(data['Passengers'], order=(1, 1, 1), seasonal_order=(1, 1, 1, 12))
sarima_fitted = sarima_model.fit()
# 预测未来12个月的乘客数量
sarima_forecast = sarima_fitted.get_forecast(steps=12)
forecast_ci = sarima_forecast.conf_int()
代码解释:
- 使用 SARIMA 模型进行建模。SARIMA 模型适合于包含季节性和非季节性成分的时间序列。我们设定季节性周期为 12(每年)。
4. Holt-Winters 模型选择与预测
# 4. 模型选择与预测:Holt-Winters 模型
hw_model = ExponentialSmoothing(data['Passengers'], trend='add', seasonal='mul', seasonal_periods=12).fit()
hw_forecast = hw_model.forecast(steps=12)
代码解释:
- 使用 Holt-Winters 模型进行建模,该模型适合带有季节性、趋势的时间序列。
5. 模型评估
# 5. 评估模型性能
sarima_mae = mean_absolute_error(data['Passengers'], sarima_fitted.fittedvalues)
sarima_rmse = np.sqrt(mean_squared_error(data['Passengers'], sarima_fitted.fittedvalues))
hw_mae = mean_absolute_error(data['Passengers'], hw_model.fittedvalues)
hw_rmse = np.sqrt(mean_squared_error(data['Passengers'], hw_model.fittedvalues))
print(f"SARIMA MAE: {sarima_mae}, RMSE: {sarima_rmse}")
print(f"Holt-Winters MAE: {hw_mae}, RMSE: {hw_rmse}")
代码解释:
- 使用 MAE 和 RMSE 指标对 SARIMA 和 Holt-Winters 模型进行评估,比较两个模型的预测性能。
结果输出:
SARIMA MAE: 10.04080588740737, RMSE: 15.555814305174993
Holt-Winters MAE: 7.953222055847547, RMSE: 10.52539423545747
6. 结果可视化
# 6. 绘制预测结果
plt.figure(figsize=(10, 6))
plt.plot(data.index, data['Passengers'], label='Original Data')
plt.plot(pd.date_range(start=data.index[-1], periods=12, freq='M'), sarima_forecast.predicted_mean, label='SARIMA Forecast')
plt.fill_between(pd.date_range(start=data.index[-1], periods=12, freq='M'),
forecast_ci.iloc[:, 0], forecast_ci.iloc[:, 1], color='gray', alpha=0.3, label='SARIMA CI')
plt.plot(pd.date_range(start=data.index[-1], periods=12, freq='M'), hw_forecast, label='Holt-Winters Forecast')
plt.title('Airline Passengers Forecast')
plt.xlabel('Date')
plt.ylabel('Passengers')
plt.legend()
plt.grid(True)
plt.show()
代码解释:
- 绘制 SARIMA 和 Holt-Winters 模型的预测结果,并展示 SARIMA 模型的置信区间。通过对比两个模型的预测曲线,我们可以进一步分析哪种模型更适合于该数据集。
结果输出:
三、结果分析
1. 时间序列分解
- 分解结果展示了航空乘客数据的趋势、季节性和残差成分,帮助我们更好地理解数据的结构。
2. SARIMA 与 Holt-Winters 模型的预测
- 通过预测结果可见,SARIMA 和 Holt-Winters 模型都捕捉到了数据的季节性和趋势。SARIMA 模型的置信区间提供了对未来乘客数量的不确定性估计。
3. 模型评估
- 通过 MAE 和 RMSE 评估模型性能,RMSE 越小,模型的预测效果越好。我们可以通过比较这两个模型的误差来判断哪个模型更适合该数据集。
四、总结
通过本次案例,我们综合应用了时间序列分析与预测的多种方法,完成了从数据预处理、模型选择、预测到评估的完整项目流程。我们通过 SARIMA 和 Holt-Winters 模型对航空乘客数据进行了预测,并比较了两个模型的性能。