当前位置: 首页 > news >正文

python学习打卡day59

DAY 59 经典时序预测模型3

知识点回顾:

  1. SARIMA模型的参数和用法:SARIMA(p, d, q)(P, D, Q)m
  2. 模型结果的检验可视化(昨天说的是摘要表怎么看,今天是对这个内容可视化)
  3. 多变量数据的理解:内生变量和外部变量
  4. 多变量模型
    1. 统计模型:SARIMA(单向因果)、VAR(考虑双向依赖)
    2. 机器学习模型:通过滑动窗口实现,往往需要借助arima等作为特征提取器来捕捉线性部分(趋势、季节性),再利用自己的优势捕捉非线性的残差
    3. 深度学习模型:独特的设计天然为时序数据而生

作业:由于篇幅问题,无法实战SARIMAX了,可以自己借助AI尝试尝试,相信大家已经有这个能力了。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.statespace.sarimax import SARIMAX
import warnings
import itertools
warnings.filterwarnings('ignore')
# 显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 1. 加载数据
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv'
df = pd.read_csv(url, header=0, index_col=0, parse_dates=True)
df.columns = ['Passengers']# 2. 划分训练集和测试集(保留最后12个月作为测试)
train_data = df.iloc[:-12]
test_data = df.iloc[-12:]print("--- 训练集 ---")
print(train_data.tail()) # 观察训练集最后5行
print("\n--- 测试集 ---")
print(test_data.head()) # 观察测试集前5行
# 3. 可视化原始数据
plt.figure(figsize=(12, 6))
plt.plot(train_data['Passengers'], label='训练集')
plt.plot(test_data['Passengers'], label='测试集', color='orange')
plt.title('国际航空乘客数量 (1949-1960)')
plt.xlabel('年份')
plt.ylabel('乘客数量 (千人)')
plt.legend()
plt.show()

# 进行季节性差分 (D=1, m=12)
seasonal_diff = df['Passengers'].diff(12).dropna()
# 再进行普通差分 (d=1)
seasonal_and_regular_diff = seasonal_diff.diff(1).dropna()# 绘制差分后的数据
plt.figure(figsize=(12, 6))
plt.plot(seasonal_and_regular_diff)
plt.title('经过一次季节性差分和一次普通差分后的数据')
plt.show()# ADF检验
result = adfuller(seasonal_and_regular_diff)
print(f'ADF Statistic: {result[0]}')
print(f'p-value: {result[1]}') # p-value越小,越说明数据平稳

 

# 绘制ACF和PACF图
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
plot_acf(seasonal_and_regular_diff, lags=36, ax=ax1) # 绘制36个时间点
plot_pacf(seasonal_and_regular_diff, lags=36, ax=ax2)
plt.show()

 

手动的超参数搜索:

# 固定已知参数
d = 1           # 非季节性差分阶数
D = 1           # 季节性差分阶数
m = 12          # 季节性周期(月度数据为12)# 定义待搜索的参数范围
p = q = range(0, 3)  # 非季节性参数 p和q取0-2
P = Q = range(0, 2)  # 季节性参数 P和Q取0-1# 生成所有可能的参数组合
pdq = list(itertools.product(p, [d], q))  # d固定为1
seasonal_pdq = [(x[0], D, x[2], m) for x in list(itertools.product(P, [D], Q))]  # D固定为1# 修正列名引用(假设数据列名为'Passengers')
train_column = 'Passengers'  # 请根据实际数据列名调整# 初始化最佳参数和最小AIC
best_aic = float('inf')
best_pdq = None
best_seasonal_pdq = None
best_model = Noneprint("开始网格搜索最佳SARIMA参数...")# 网格搜索最佳参数
for param in pdq:for param_seasonal in seasonal_pdq:try:# 拟合SARIMA模型model = SARIMAX(train_data[train_column],order=param,seasonal_order=param_seasonal,enforce_stationarity=False,  # 放宽平稳性约束enforce_invertibility=False, # 放宽可逆性约束disp=False)# 使用优化的拟合方法results = model.fit(method='bfgs',  # 使用BFGS优化算法maxiter=200,    # 增加最大迭代次数disp=False)# 打印当前参数组合及AICprint(f'SARIMA{param}x{param_seasonal} - AIC: {results.aic:.2f}')# 更新最佳参数if results.aic < best_aic:best_aic = results.aicbest_pdq = parambest_seasonal_pdq = param_seasonalbest_model = resultsexcept Exception as e:print(f'SARIMA{param}x{param_seasonal} 拟合失败: {str(e)}')continue
# 输出最佳模型
if best_pdq:print(f"\n最佳模型: SARIMA{best_pdq}x{best_seasonal_pdq} - AIC: {best_aic:.2f}")final_model = SARIMAX(train_data[train_column],order=best_pdq,seasonal_order=best_seasonal_pdq,enforce_stationarity=False,enforce_invertibility=False)final_results = final_model.fit(disp=False)

 

# 检查是否找到有效模型
if best_model is not None:print(f'\n最佳模型: SARIMA{best_pdq}x{best_seasonal_pdq} - AIC: {best_aic:.2f}')# 打印最佳模型摘要print(best_model.summary())# 绘制模型诊断图best_model.plot_diagnostics(figsize=(15, 10))plt.tight_layout()plt.show()else:print("\n未能找到合适的SARIMA模型。请检查:")print("1. 数据列名是否正确(当前使用:", train_column, ")")print("2. 数据是否包含缺失值或异常值")print("3. 尝试进一步调整参数范围")print("4. 考虑使用其他时间序列模型")

 

# 1. 预测测试集
forecast = final_results.get_forecast(steps=len(test_data))
forecast_mean = forecast.predicted_mean
forecast_ci = forecast.conf_int()# 2. 评估模型
from sklearn.metrics import mean_squared_error
import numpy as npmse = mean_squared_error(test_data[train_column], forecast_mean)
rmse = np.sqrt(mse)
print(f'测试集 MSE: {mse:.2f}')
print(f'测试集 RMSE: {rmse:.2f}')# 3. 绘制预测结果
plt.figure(figsize=(12, 6))
plt.plot(train_data.index, train_data[train_column], label='训练数据')
plt.plot(test_data.index, test_data[train_column], label='真实值', color='orange')
plt.plot(test_data.index, forecast_mean, label='预测值', color='red')
plt.fill_between(forecast_ci.index,forecast_ci.iloc[:, 0],forecast_ci.iloc[:, 1],color='pink', alpha=0.5, label='95%置信区间')
plt.title('SARIMA模型预测 vs. 真实值')
plt.xlabel('日期')
plt.ylabel('乘客数量 (千人)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

 

@浙大疏锦行 

http://www.dtcms.com/a/265734.html

相关文章:

  • 【轨物洞见】光伏机器人与组件、支架智能化协同白皮书
  • Linux操作系统之文件(二):重定向
  • Android 系统默认的Launcher3,Android 系统的导航栏(通常是屏幕底部)显示的 4 个快捷应用图标,如何替换这4个应用图标为客户想要的。
  • Fiddler中文版抓包工具在后端API调试与Mock中的巧用
  • Treap树
  • thinkphp8接管异常处理类
  • linux系统 weblogic10.3.6(jar) 下载及安装
  • 后端 Maven打包 JAR 文件、前端打包dist文件、通过后端服务访问前端页面、Nginx安装与部署
  • Josn模块的使用
  • MVC 架构设计模式
  • Docker 安装 Redis 哨兵模式
  • 【数据结构】C++的unordered_map/set模拟实现(开散列(哈希桶)作底层)
  • 机器人“触摸”水果成熟度突破:SwishFormer模型与DIGIT视触觉传感器在HelloRobot上的水果检测应用
  • TDSQL如何查出某一列中的逗号数量
  • 从 TCP/IP 协议栈角度深入分析网络文件系统 (NFS)
  • (1)手摸手-学习 Vue3 之 Vite 创建项目
  • grpc 和限流Sentinel
  • STC8G 8051内核单片机开发(GPIO)
  • 2025年6月微短剧备案分析:都市题材占四成,20-29集成主流体量
  • OS15.【Linux】gdb调试器的简单使用
  • 修改文件属主
  • 活体检测api集成方案-炫彩活体检测助力身份核验
  • 马斯克脑机接口(Neuralink)技术进展,已经实现瘫痪患者通过BCI控制电脑、玩视频游戏、学习编程,未来盲人也能恢复视力了
  • [极客时间]LangChain 实战课 -----|(10) 链(下):想学“育花”还是“插花”?用RouterChain确定客户意图
  • 预警:病毒 “黑吃黑”,GitHub 开源远控项目暗藏后门
  • 2024年INS SCI2区,强化搜索自适应大邻域搜索算法RSALNS+无人机扩展型协作多任务分配,深度解析+性能实测
  • 实现如何利用 Kafka 延时删除 用户邮箱的验证码(如何发送邮箱+源码) - 第一期
  • 前缀和算法详解
  • FASTAPI+VUE3平价商贸管理系统
  • React自学 基础一