第100+33步 ChatGPT学习:时间序列EMD-ARIMA-LSTM模型

基于Python 3.9版本演示

 

一、写在前面

上一节,我们学了经验模态分解(Empirical Mode Decomposition,EMD)。

如同结尾所说,“那么,做这些分解有什么作用呢?有大佬基于这些分解出来的序列分别作预测,然后再次合并,达到提升预测性能的作用。”

 

二、EMD&LSTM-ARIMA组合策略

该组合策略主要是将传统的经验模态分解(EMD)方法和现代的机器学习技术(LSTM 和 ARIMA 模型)相结合,用于增强时序数据的预测能力。下面是这个策略的具体描述:

(1)经验模态分解 (EMD):

1)首先,使用 EMD 方法处理原始时序数据,将其分解为多个内模函数(IMF)和一个剩余信号。这一步骤的目的是提取数据中的不同频率成分,每个 IMF 代表原始信号的不同频率层次,而剩余信号包含了趋势信息。

2)EMD 是一种自适应方法,适用于非线性和非平稳时间序列数据分析,可以揭示隐藏在复杂数据集中的简单结构和成分。

(2)LSTM 和 ARIMA 模型的应用:

1)将不同的 IMF 成分分配给不同的预测模型:选定的IMF由 LSTM 模型处理,通常选择那些更具高频和复杂动态的成分;而趋势性较强的成分(包括剩余信号)则交由 ARIMA 模型进行分析。

2)LSTM (长短期记忆网络):适合处理和预测时间序列数据中的长期依赖关系,因此用于捕捉和预测时序数据中的非线性模式和复杂关系。

3)ARIMA (自回归积分滑动平均模型):擅长处理线性关系和趋势变化,适用于具有明显趋势或季节性的时间序列数据。

 

三、EMD&LSTM-ARIMA组合策略代码Pyhton实现

下面,我使用的是之前分享过的肺结核的数据做演示:

311fef53b2d142c087306ca3061bc39a.png

Pyhon代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import CubicSpline
import torch
import torch.nn as nn
import torch.optim as optim
from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_absolute_error, mean_squared_error# 读取数据
file_path = 'pone.0277314.s006.xlsx'
data = pd.read_excel(file_path)# 提取时间和PTB病例数
time_series = data['Time']
ptb_cases = data['PTB cases']# 将时间转换为数值形式
time_numeric = np.arange(len(time_series))def get_envelope_mean(signal):"""计算信号的上包络线和下包络线的均值"""maxima = np.where(np.r_[True, signal[1:] > signal[:-1]] & np.r_[signal[:-1] > signal[1:], True])[0]minima = np.where(np.r_[True, signal[1:] < signal[:-1]] & np.r_[signal[:-1] < signal[1:], True])[0]if len(maxima) < 2 or len(minima) < 2:return np.zeros_like(signal)upper_env = CubicSpline(maxima, signal[maxima])(time_numeric)lower_env = CubicSpline(minima, signal[minima])(time_numeric)return (upper_env + lower_env) / 2def sift(signal, max_iter=1000, tol=1e-6):"""对信号进行sifting操作,提取IMF"""h = signalfor _ in range(max_iter):m = get_envelope_mean(h)h1 = h - mif np.mean(np.abs(h - h1)) < tol:breakh = h1return hdef emd(signal, max_imfs=6):"""进行EMD分解"""residual = signalimfs = []for _ in range(max_imfs):imf = sift(residual)imfs.append(imf)residual = residual - imfif np.all(np.abs(residual) < 1e-6):breakreturn np.array(imfs), residual# 执行EMD分解
imfs, residual = emd(ptb_cases.values)# 绘制分解结果
num_imfs = imfs.shape[0]
plt.figure(figsize=(12, 9))
for i in range(num_imfs):plt.subplot(num_imfs + 1, 1, i + 1)plt.plot(time_series, imfs[i], label=f'IMF {i + 1}')plt.legend()plt.subplot(num_imfs + 1, 1, num_imfs + 1)
plt.plot(time_series, residual, label='Residual')
plt.legend()
plt.tight_layout()
plt.show()# LSTM模型
class LSTMModel(nn.Module):def __init__(self, input_size=1, hidden_layer_size=50, output_size=1):super(LSTMModel, self).__init__()self.hidden_layer_size = hidden_layer_sizeself.lstm = nn.LSTM(input_size, hidden_layer_size)self.linear = nn.Linear(hidden_layer_size, output_size)self.hidden_cell = (torch.zeros(1,1,self.hidden_layer_size),torch.zeros(1,1,self.hidden_layer_size))def forward(self, input_seq):lstm_out, self.hidden_cell = self.lstm(input_seq.view(len(input_seq) ,1, -1), self.hidden_cell)predictions = self.linear(lstm_out.view(len(input_seq), -1))return predictions[-1]def train_lstm_model(train_data, n_steps):model = LSTMModel()loss_function = nn.MSELoss()optimizer = optim.Adam(model.parameters(), lr=0.001)epochs = 200for epoch in range(epochs):for seq in range(len(train_data) - n_steps):model.hidden_cell = (torch.zeros(1, 1, model.hidden_layer_size),torch.zeros(1, 1, model.hidden_layer_size))seq_train = torch.FloatTensor(train_data[seq:seq + n_steps])label = torch.FloatTensor(train_data[seq + n_steps:seq + n_steps + 1])optimizer.zero_grad()y_pred = model(seq_train)single_loss = loss_function(y_pred, label)single_loss.backward()optimizer.step()if epoch % 50 == 0:print(f'Epoch {epoch+1} loss: {single_loss.item()}')return modeldef arima_model(train_data, order):model = ARIMA(train_data, order=order)model_fit = model.fit()return model_fitn_steps = 10
imfs_lstm = [3, 4]  # 分配给LSTM的IMFs索引
imfs_arima = [0, 1, 2]  # 分配给ARIMA的IMFs索引lstm_predictions = np.zeros(len(time_numeric))
arima_predictions = np.zeros(len(time_numeric))# LSTM预测
for idx in imfs_lstm:print(f'Training LSTM for IMF {idx+1}')train_data = imfs[idx].flatten()model = train_lstm_model(train_data, n_steps)for i in range(n_steps, len(train_data)):seq = torch.FloatTensor(train_data[i-n_steps:i])with torch.no_grad():lstm_predictions[i] += model(seq).item()print(f'LSTM predictions for IMF {idx+1} completed')# ARIMA预测
for idx in imfs_arima:print(f'Training ARIMA for IMF {idx+1}')train_data = imfs[idx]model_fit = arima_model(train_data, order=(5, 1, 0))arima_predictions += model_fit.predict(start=0, end=len(train_data) - 1)print(f'ARIMA predictions for IMF {idx+1} completed')# 合并预测结果
final_predictions = lstm_predictions + arima_predictions# 计算误差
mae = mean_absolute_error(ptb_cases, final_predictions)
mse = mean_squared_error(ptb_cases, final_predictions)
rmse = np.sqrt(mse)
mape = np.mean(np.abs((ptb_cases - final_predictions) / ptb_cases)) * 100# 打印误差
print(f'MAE: {mae}')
print(f'MSE: {mse}')
print(f'RMSE: {rmse}')
print(f'MAPE: {mape}')# 绘制预测结果
plt.figure(figsize=(12, 6))
plt.plot(time_numeric, ptb_cases, label='Original Data')
plt.plot(time_numeric, final_predictions, label='Predicted Data')
plt.legend()
plt.show()

输出:

d132d76bacaf4b23a1b55c63857090db.png

跟原图对比:

发现了没,似乎是整体向下偏移了一波。让GPT帮忙优化一下算法。

 

五、优化后

根据每个模型的误差(MAE)微调一下试试:

Pyhon代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import CubicSpline
import torch
import torch.nn as nn
import torch.optim as optim
from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_absolute_error, mean_squared_error# 读取数据
file_path = 'pone.0277314.s006.xlsx'
data = pd.read_excel(file_path)# 提取时间和PTB病例数
time_series = data['Time']
ptb_cases = data['PTB cases']# 将时间转换为数值形式
time_numeric = np.arange(len(time_series))def get_envelope_mean(signal):"""计算信号的上包络线和下包络线的均值"""maxima = np.where(np.r_[True, signal[1:] > signal[:-1]] & np.r_[signal[:-1] > signal[1:], True])[0]minima = np.where(np.r_[True, signal[1:] < signal[:-1]] & np.r_[signal[:-1] < signal[1:], True])[0]if len(maxima) < 2 or len(minima) < 2:return np.zeros_like(signal)upper_env = CubicSpline(maxima, signal[maxima])(time_numeric)lower_env = CubicSpline(minima, signal[minima])(time_numeric)return (upper_env + lower_env) / 2def sift(signal, max_iter=1000, tol=1e-6):"""对信号进行sifting操作,提取IMF"""h = signalfor _ in range(max_iter):m = get_envelope_mean(h)h1 = h - mif np.mean(np.abs(h - h1)) < tol:breakh = h1return hdef emd(signal, max_imfs=6):"""进行EMD分解"""residual = signalimfs = []for _ in range(max_imfs):imf = sift(residual)imfs.append(imf)residual = residual - imfif np.all(np.abs(residual) < 1e-6):breakreturn np.array(imfs), residual# 执行EMD分解
imfs, residual = emd(ptb_cases.values)# 绘制分解结果
num_imfs = imfs.shape[0]
plt.figure(figsize=(12, 9))
for i in range(num_imfs):plt.subplot(num_imfs + 1, 1, i + 1)plt.plot(time_series, imfs[i], label=f'IMF {i + 1}')plt.legend()plt.subplot(num_imfs + 1, 1, num_imfs + 1)
plt.plot(time_series, residual, label='Residual')
plt.legend()
plt.tight_layout()
plt.show()# LSTM模型
class LSTMModel(nn.Module):def __init__(self, input_size=1, hidden_layer_size=50, output_size=1):super(LSTMModel, self).__init__()self.hidden_layer_size = hidden_layer_sizeself.lstm = nn.LSTM(input_size, hidden_layer_size)self.linear = nn.Linear(hidden_layer_size, output_size)self.hidden_cell = (torch.zeros(1,1,self.hidden_layer_size),torch.zeros(1,1,self.hidden_layer_size))def forward(self, input_seq):lstm_out, self.hidden_cell = self.lstm(input_seq.view(len(input_seq) ,1, -1), self.hidden_cell)predictions = self.linear(lstm_out.view(len(input_seq), -1))return predictions[-1]def train_lstm_model(train_data, n_steps):model = LSTMModel(hidden_layer_size=100)  # 调整隐藏层大小loss_function = nn.MSELoss()optimizer = optim.Adam(model.parameters(), lr=0.001)  # 调整学习率epochs = 300  # 增加训练轮数for epoch in range(epochs):for seq in range(len(train_data) - n_steps):model.hidden_cell = (torch.zeros(1, 1, model.hidden_layer_size),torch.zeros(1, 1, model.hidden_layer_size))seq_train = torch.FloatTensor(train_data[seq:seq + n_steps])label = torch.FloatTensor(train_data[seq + n_steps:seq + n_steps + 1])optimizer.zero_grad()y_pred = model(seq_train)single_loss = loss_function(y_pred, label)single_loss.backward()optimizer.step()if epoch % 50 == 0:print(f'Epoch {epoch+1} loss: {single_loss.item()}')return modeldef arima_model(train_data, order):model = ARIMA(train_data, order=order)model_fit = model.fit()return model_fitn_steps = 10
imfs_lstm = [3, 4]  # 分配给LSTM的IMFs索引
imfs_arima = [0, 1, 2]  # 分配给ARIMA的IMFs索引lstm_predictions = np.zeros(len(time_numeric))
arima_predictions = np.zeros(len(time_numeric))# LSTM预测
for idx in imfs_lstm:print(f'Training LSTM for IMF {idx+1}')train_data = imfs[idx].flatten()model = train_lstm_model(train_data, n_steps)for i in range(n_steps, len(train_data)):seq = torch.FloatTensor(train_data[i-n_steps:i])with torch.no_grad():lstm_predictions[i] += model(seq).item()print(f'LSTM predictions for IMF {idx+1} completed')# ARIMA预测
for idx in imfs_arima:print(f'Training ARIMA for IMF {idx+1}')train_data = imfs[idx]model_fit = arima_model(train_data, order=(5, 1, 0))arima_predictions += model_fit.predict(start=0, end=len(train_data) - 1)print(f'ARIMA predictions for IMF {idx+1} completed')# 合并预测结果
final_predictions = lstm_predictions + arima_predictions# 计算LSTM和ARIMA模型的误差
lstm_error = np.mean(ptb_cases - lstm_predictions)
arima_error = np.mean(ptb_cases - arima_predictions)# 根据误差平移预测结果
final_predictions += (lstm_error + arima_error) / 2# 计算误差
mae = mean_absolute_error(ptb_cases, final_predictions)
mse = mean_squared_error(ptb_cases, final_predictions)
rmse = np.sqrt(mse)
mape = np.mean(np.abs((ptb_cases - final_predictions) / ptb_cases)) * 100# 打印误差
print(f'MAE: {mae}')
print(f'MSE: {mse}')
print(f'RMSE: {rmse}')
print(f'MAPE: {mape}')# 绘制预测结果
plt.figure(figsize=(12, 6))
plt.plot(time_numeric, ptb_cases, label='Original Data')
plt.plot(time_numeric, final_predictions, label='Predicted Data')
plt.legend()
plt.show()

看看结果:

a16746d0046246e6b010ed115f534fd9.png

效果也不是太好。

 

六、最后

下一期,我们来测试一下其他矫正方法。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/491073.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker创建一个mongodb实例,并用springboot连接 mongodb进行读写文件

一、通过Docker 进行运行一个 mongodb实例 1、拉取镜像 docker pull mongo:5.0.5 2、创建 mongodb容器实例 docker run -d --name mongodb2 \-e MONGO_INITDB_ROOT_USERNAMEsalaryMongo \-e MONGO_INITDB_ROOT_PASSWORD123456 \-p 27017:27017 \mongo:5.0.5 3、进入容器&am…

12-2周 周总结

上周主要工作在英语六级&#xff0c;其它暂无进展 新的一周任务安排如下: ① 读完四篇重要文献论文 ② 搭建完云平台 ③ 整理小论文雏形 ④ 学习侧线系统代码 ⑤ 复习应用数理统计 前半部分 ⑥ springspringboot源码部分完结

云计算HCIP-OpenStack04

书接上回&#xff1a; 云计算HCIP-OpenStack03-CSDN博客 12.Nova计算管理 Nova作为OpenStack的核心服务&#xff0c;最重要的功能就是提供对于计算资源的管理。 计算资源的管理就包含了已封装的资源和未封装的资源。已封装的资源就包含了虚拟机、容器。未封装的资源就是物理机提…

【蓝桥杯选拔赛真题93】Scratch青蛙过河 第十五届蓝桥杯scratch图形化编程 少儿编程创意编程选拔赛真题解析

目录 Scratch青蛙过河 一、题目要求 编程实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、python资料 Scr…

Elasticsearch 7.x入门学习-Spring Data Elasticsearch框架

1 Spring Data框架 Spring Data 是一个用于简化数据库、非关系型数据库、索引库访问&#xff0c;并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷&#xff0c;并支持 map-reduce 框架和云计算数据服务。 Spring Data 可以极大的简化 JPA的写法&#xff0c;…

OpenCV实验篇:识别图片颜色并绘制轮廓

第三篇&#xff1a;识别图片颜色并绘制轮廓 1. 实验原理 颜色识别的原理&#xff1a; 颜色在图像处理中通常使用 HSV 空间来表示。 HSV 空间是基于人类视觉系统的一种颜色模型&#xff0c;其中&#xff1a; H&#xff08;Hue&#xff09;&#xff1a;色调&#xff0c;表示颜色…

MySql5.7安装、配置最新版

网上有很多的安装教程&#xff0c;但是有很多同学找不到历史安装包&#xff0c;而且官网变动比较大&#xff0c;我就直接给安装包了&#xff0c;下载 这个是安装包msi下载&#xff0c;可以参考下面的 MySQL详细安装教程&#xff0c;关于msi版和zip版详解&#xff0c;Windows …

ISP算法之坏点校正DPC(二):Verilog硬件实现与仿真

DPC的算法讲解和MATLAB仿真参考上一节&#xff1a; ISP算法之坏点校正DPC(一)&#xff1a;MATLAB仿真验证-CSDN博客 本节讲解Verilog的硬件实现与仿真 行缓存设计 DPC算法是基于窗口邻域的像素级别算法&#xff0c;因此需要对实时到来的视频流进行行缓存&#xff0c;行缓存…

UE5制作倒计时功能

设置画布和文本 文本绑定 格式化时间 转到事件图表&#xff0c;计算时间&#xff0c;时间结束后面的事件可以按自己需求写 进入关卡蓝图&#xff0c;添加倒计时UI

在Spring Boot中的实现国际化(i18n)

1.什么是国际化&#xff08;i18n&#xff09;&#xff1f; 国际化&#xff08;Internationalization&#xff0c;简称i18n&#xff09;是指在软件应用中支持多种语言和文化的能力。通过国际化&#xff0c;应用可以根据用户的语言和地区设置&#xff0c;动态地显示不同的文本内…

大模型的构建与部署(3)——数据标注

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl1. 数据标注的重要性 1.1 增强数据可解释性 数据标注通过为原始数据添加标签或注释,显著增强了数据的可解释性。在机器学习和深度学习领域,模型的训练依赖于大量带标签的数据。这些标签不仅帮助…

【考前预习】4.计算机网络—网络层

往期推荐 【考前预习】3.计算机网络—数据链路层-CSDN博客 【考前预习】2.计算机网络—物理层-CSDN博客 【考前预习】1.计算机网络概述-CSDN博客 目录 1.网络层概述 2.网络层提供的两种服务 3.分类编址的IPV4 4.无分类编址的IPV4—CIDR 5.IPV4地址应用规划 5.1使用定长子…

需求管理(尊享版)

需求管理 由于需求是正在构建的系统必须符合的事务&#xff0c;而且符合某些需求决定了项目的成功或失败&#xff0c;因此找出需求是什么&#xff0c;将它们记下来&#xff0c;进行组织&#xff0c;并在发生变化时对它们进行追踪&#xff0c;这些活动都是有意义的。 需求管理…

前后端跨域问题(CROS)

前端 在src中创建util文件&#xff0c;写request.js文件&#xff1a; request.js代码如下&#xff1a; import axios from axios import { ElMessage } from element-plus;const request axios.create({// baseURL: /api, // 注意&#xff01;&#xff01; 这里是全局统一加…

【python从入门到精通】-- 第六战:列表和元组

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;重生之我在学Linux&#xff0c;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持…

操作系统课后习题2.2节

操作系统课后习题2.2节 第1题 CPU的效率指的是CPU的执行速度&#xff0c;这个是由CPU的设计和它的硬件来决定的&#xff0c;具体的调度算法是不能提高CPU的效率的&#xff1b; 第3题 互斥性&#xff1a; 指的是进程之间的同步互斥关系&#xff0c;进程是一个动态的过程&#…

openlane

openlane数据集&#xff0c;lane3d_1000里训练集157807张图片&#xff0c;测试集39981张图&#xff0c;md太多了

在pycharm2024.3.1中配置anaconda3-2024-06环境

version: anaconda3-2024.06-1 pycharm-community-2024.3.1 1、安装anaconda和pycharm 最新版最详细Anaconda新手安装配置环境创建教程_anaconda配置-CSDN博客 【2024最新版】超详细Pycharm安装保姆级教程&#xff0c;Pycharm环境配置和使用指南&#xff0c;看完这一篇就够了…

深度解读:Top14金融顶刊

作者Toby&#xff1a;来源&#xff1a;Python风控模型&#xff0c;Top14金融顶刊 各位同学好&#xff0c;我是Toby老师&#xff0c;今天为大家介绍金融风控领域的顶级学术期刊&#xff0c;用于小论文发布平台参考。 金融风控领域内有许多顶级学术期刊&#xff0c;它们发表高质…

系列2:基于Centos-8.6Kubernetes 集成GPU资源信息

每日禅语 自省&#xff0c;就是自我反省、自我检查&#xff0c;自知己短&#xff0c;从而弥补短处、纠正过失。佛陀强调自觉觉他&#xff0c;强调以达到觉行圆满为修行的最高境界。要改正错误&#xff0c;除了虚心接受他人意见之外&#xff0c;还要不忘时时观照己身。自省自悟之…