第89步 时间序列建模实战:时间序列融合模型

news2024/12/23 3:52:00

基于WIN10的64位系统演示

一、写在前面

这一期,我们介绍融合模型模型。

(1)数据源:

《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Syndrome in Jiangsu Province, China》文章的公开数据做演示。数据为江苏省2004年1月至2012年12月肾综合症出血热月发病率。运用2004年1月至2011年12月的数据预测2012年12个月的发病率数据。

(2)融合策略:

时间序列模型融合是指将多种时间序列模型的预测结果组合起来,以期获得比任何单一模型更好的预测效果。以下是一些常见的时间序列模型融合方法:

(a)简单平均法(Simple Averaging):简单地对所有模型的预测结果取平均值。这种方法假设每个模型都有相同的权重。

(b)加权平均法(Weighted Averaging):与简单平均法类似,但每个模型的预测结果按其权重进行加权平均。

(c)模型堆叠(Stacking):使用一个基学习器,例如LSTM、决策树等,将其他所有模型的预测结果作为输入,进行再次的预测。需要将数据集分为两部分或多部分,一部分用于训练初级模型,另一部分用于生成训练数据以训练次级模型。

(d)Bagging:对原始数据进行多次重采样生成多个子数据集,使用同一模型或多种模型对每个子数据集进行训练,对多个模型的预测结果进行平均或加权平均。

(e)Boosting:一个迭代的过程,其中每次迭代都会尝试修正之前所有模型的预测错误。

(f)深度学习模型的融合:设计一个深度学习架构,将多个模型的输出作为输入,进一步进行训练。

三、实战

(a)简单平均法

这个不用演示了吧,直接用把结果简单平均即可。

(b)加权平均法

该方法的关键在于权重如何确定,可以根据几个模型的训练误差来确定这些模型的权重。模型的权重可以被视为其训练误差的反比,这意味着误差越小的模型权重越大。这里的误差,MAE、MAPE、MSE和RMSE都可以。

举个例子:

假设三个模型的训练误差分别为:ARIMA为0.1,LSTM为0.09,KNN为0.15,那么它们的权重分别为:

ARIMA:(1/0.1)/(1/0.1+1/0.09+1/0.15)=9/25

LSTM:(1/0.09)/(1/0.1+1/0.09+1/0.15)=10/25

KNN:(1/0.15)/(1/0.1+1/0.09+1/0.15)=6/25

因此,融合模型的最终数值就是:

预测值 = 9/25 × ARIMA + 10/25 × LSTM + 6/25 × KNN

(c)模型堆叠

模型堆叠(Stacking)是一种集成学习方法,其目标是通过结合多个模型的预测来提高整体的预测准确性。下面是对所提策略的详细解释:

1)基学习器与次级学习器:

基学习器:这是第一层的模型,通常有多个。它们可以是任何类型的模型,例如决策树、神经网络、SVM等。

次级学习器:也被称为“元学习器”或“堆叠器”。这是第二层的模型,它的任务是学习如何最佳地结合基学习器的预测结果。在你描述的策略中,这个模型可以是LSTM、决策树等。

2)训练过程:

首先,将数据集分成至少两部分。例如,可以使用K折交叉验证的方法。使用一部分数据(例如K-1折)训练所有的基学习器。

然后,使用这些基学习器对剩下的一折数据进行预测。这些预测结果被称为“堆叠特征”。使用这些堆叠特征作为输入,对次级学习器进行训练。

3)预测过程:

对于一个新的输入样本,首先使用所有的基学习器进行预测。然后,使用这些预测作为次级学习器的输入,得到最终的预测结果。

4)代码如下:

import pandas as pd
import numpy as np
from sklearn.metrics import mean_absolute_error, mean_squared_error
from sklearn.svm import SVR
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV, KFold

# 读取数据
data = pd.read_csv('data.csv')
data['time'] = pd.to_datetime(data['time'], format='%b-%y')

lag_period = 6
# 创建滞后期特征
for i in range(lag_period, 0, -1):
    data[f'lag_{i}'] = data['incidence'].shift(lag_period - i + 1)
data = data.dropna().reset_index(drop=True)

# 划分训练集和验证集
train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
validation_data = data[(data['time'] >= '2012-01-01') & (data['time'] <= '2012-12-31')]

# 定义特征和目标变量
features = ['lag_1', 'lag_2', 'lag_3', 'lag_4', 'lag_5', 'lag_6']
X_train = train_data[features]
y_train = train_data['incidence']
X_validation = validation_data[features]
y_validation = validation_data['incidence']

# KFold and Out-of-Fold Predictions
kf = KFold(n_splits=5, shuffle=True, random_state=42)
oof_predictions_svr = np.zeros(X_train.shape[0])
oof_predictions_tree = np.zeros(X_train.shape[0])

for train_idx, valid_idx in kf.split(X_train):
    X_train_fold, X_valid_fold = X_train.iloc[train_idx], X_train.iloc[valid_idx]
    y_train_fold, y_valid_fold = y_train.iloc[train_idx], y_train.iloc[valid_idx]

    # Train SVM
    param_grid_svr = {
        'C': [0.1, 1, 10],
        'epsilon': [0.01, 0.1, 1],
        'kernel': ['linear', 'rbf']
    }
    grid_search_svr = GridSearchCV(SVR(), param_grid_svr, cv=5, scoring='neg_mean_squared_error')
    grid_search_svr.fit(X_train_fold, y_train_fold)
    best_svr = SVR(**grid_search_svr.best_params_)
    best_svr.fit(X_train_fold, y_train_fold)
    oof_predictions_svr[valid_idx] = best_svr.predict(X_valid_fold)

    # Train Decision Tree
    param_grid_tree = {
        'max_depth': [None, 3, 5, 7, 9],
        'min_samples_split': range(2, 11),
        'min_samples_leaf': range(1, 11)
    }
    grid_search_tree = GridSearchCV(DecisionTreeRegressor(), param_grid_tree, cv=5, scoring='neg_mean_squared_error')
    grid_search_tree.fit(X_train_fold, y_train_fold)
    best_tree = DecisionTreeRegressor(**grid_search_tree.best_params_)
    best_tree.fit(X_train_fold, y_train_fold)
    oof_predictions_tree[valid_idx] = best_tree.predict(X_valid_fold)

X_train_stacked_oof = pd.DataFrame({
    'svm': oof_predictions_svr,
    'tree': oof_predictions_tree
})

# Train meta learner (Random Forest)
param_grid_rf = {
    'n_estimators': [50, 100, 150],
    'max_depth': [None, 5, 7],
}
grid_search_rf = GridSearchCV(RandomForestRegressor(), param_grid_rf, cv=5, scoring='neg_mean_squared_error')
grid_search_rf.fit(X_train_stacked_oof, y_train)
best_rf_oof = RandomForestRegressor(**grid_search_rf.best_params_)
best_rf_oof.fit(X_train_stacked_oof, y_train)

# Predict with base learners
validation_predictions_svr = []
validation_predictions_tree = []

for i in range(len(X_validation)):
    if i == 0:
        pred_svr = best_svr.predict([X_validation.iloc[0]])
        pred_tree = best_tree.predict([X_validation.iloc[0]])
    else:
        new_features = list(X_validation.iloc[i, 1:]) + [pred_svr[0]]
        pred_svr = best_svr.predict([new_features])
        
        new_features = list(X_validation.iloc[i, 1:]) + [pred_tree[0]]
        pred_tree = best_tree.predict([new_features])
        
    validation_predictions_svr.append(pred_svr[0])
    validation_predictions_tree.append(pred_tree[0])

# Use predictions from base learners as new features
X_validation_stacked = pd.DataFrame({
    'svm': validation_predictions_svr,
    'tree': validation_predictions_tree
})

# Predict with meta learner
y_validation_pred_stacked_oof = best_rf_oof.predict(X_validation_stacked)


def mean_absolute_percentage_error(y_true, y_pred): 
    y_true, y_pred = np.array(y_true), np.array(y_pred)
    # Avoid division by zero
    non_zero_indices = y_true != 0
    return np.mean(np.abs((y_true[non_zero_indices] - y_pred[non_zero_indices]) / y_true[non_zero_indices])) * 100

# Calculate evaluation metrics for training set
mae_train_oof = mean_absolute_error(y_train, best_rf_oof.predict(X_train_stacked_oof))
mape_train_oof = mean_absolute_percentage_error(y_train, best_rf_oof.predict(X_train_stacked_oof))
mse_train_oof = mean_squared_error(y_train, best_rf_oof.predict(X_train_stacked_oof))
rmse_train_oof = np.sqrt(mse_train_oof)

# Calculate evaluation metrics for validation set
mae_validation_oof = mean_absolute_error(y_validation, y_validation_pred_stacked_oof)
mape_validation_oof = mean_absolute_percentage_error(y_validation, y_validation_pred_stacked_oof)
mse_validation_oof = mean_squared_error(y_validation, y_validation_pred_stacked_oof)
rmse_validation_oof = np.sqrt(mse_validation_oof)

# Prepare the metrics for display
metrics_df = pd.DataFrame({
    'Metric': ['MAE', 'MAPE', 'MSE', 'RMSE'],
    'Training Set': [mae_train_oof, mape_train_oof, mse_train_oof, rmse_train_oof],
    'Validation Set': [mae_validation_oof, mape_validation_oof, mse_validation_oof, rmse_validation_oof]
})

metrics_df

解读:首先在训练数据上使用K折交叉验证训练基学习器(SVM和决策树),并使用其预测结果作为新特征训练次级学习器(随机森林)。然后,使用基学习器对验证数据进行预测,并使用这些预测结果作为新特征,让次级学习器进行预测,结果如下:

感觉吧,一顿骚操作,效果一般般。当然可能是组合的不好。

(d)Bagging

Bagging是Bootstrap Aggregating的缩写是一种集成学习方法,它通过从训练数据中采样多个子集(使用重采样)并在每个子集上训练模型来工作。预测结果是所有模型预测结果的平均值(对于回归问题)或是最常见的类别(对于分类问题)。Bagging的主要目的是减少模型的方差,特别是对于容易过拟合的模型,例如决策树。Bagging可以应用于多种机器学习算法,不仅仅是决策树。

随机森林是一种特定的Bagging实现,它专门用于决策树。除了使用Bagging方法外,随机森林在每次分裂时还采用了随机特征选择,这意味着它在决策树的每个节点都会随机选择一部分特征来考虑分裂。这种随机性的引入旨在确保每棵树都是不同的,从而进一步增强整体模型的鲁棒性

随机森林介绍过了,我们来介绍基于SVM的Bagging:

# 读取数据
import pandas as pd
import numpy as np
from sklearn.metrics import mean_absolute_error, mean_squared_error
from sklearn.svm import SVR
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import BaggingRegressor

data = pd.read_csv('data.csv')

# 将时间列转换为日期格式
data['time'] = pd.to_datetime(data['time'], format='%b-%y')

# 拆分输入和输出
lag_period = 6

# 创建滞后期特征
for i in range(lag_period, 0, -1):
    data[f'lag_{i}'] = data['incidence'].shift(lag_period - i + 1)

# 删除包含NaN的行
data = data.dropna().reset_index(drop=True)

# 划分训练集和验证集
train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
validation_data = data[(data['time'] >= '2012-01-01') & (data['time'] <= '2012-12-31')]

# 定义特征和目标变量
X_train = train_data[['lag_1', 'lag_2', 'lag_3', 'lag_4', 'lag_5', 'lag_6']]
y_train = train_data['incidence']

X_validation = validation_data[['lag_1', 'lag_2', 'lag_3', 'lag_4', 'lag_5', 'lag_6']]
y_validation = validation_data['incidence']

# 初始化SVR模型
svr_model = SVR()

# 定义参数网格
param_grid = {
    'C': [0.1, 1, 10],
    'epsilon': [0.01, 0.1, 1],
    'kernel': ['linear', 'rbf']
}

# 初始化网格搜索
grid_search = GridSearchCV(svr_model, param_grid, cv=5, scoring='neg_mean_squared_error')

# 进行网格搜索
grid_search.fit(X_train, y_train)

# 获取最佳参数
best_params = grid_search.best_params_

# 使用最佳参数初始化SVR模型,并使用Bagging
best_svr_model = BaggingRegressor(base_estimator=SVR(**best_params), n_estimators=10, random_state=42)
best_svr_model.fit(X_train, y_train)

# 对于验证集,我们需要迭代地预测每一个数据点
y_validation_pred = []

for i in range(len(X_validation)):
    if i == 0:
        pred = best_svr_model.predict([X_validation.iloc[0]])
    else:
        new_features = list(X_validation.iloc[i, 1:]) + [pred[0]]
        pred = best_svr_model.predict([new_features])
    y_validation_pred.append(pred[0])

y_validation_pred = np.array(y_validation_pred)

# 计算验证集上的MAE, MAPE, MSE和RMSE
mae_validation = mean_absolute_error(y_validation, y_validation_pred)
mape_validation = np.mean(np.abs((y_validation - y_validation_pred) / y_validation))
mse_validation = mean_squared_error(y_validation, y_validation_pred)
rmse_validation = np.sqrt(mse_validation)

# 计算训练集上的MAE, MAPE, MSE和RMSE
y_train_pred = best_svr_model.predict(X_train)
mae_train = mean_absolute_error(y_train, y_train_pred)
mape_train = np.mean(np.abs((y_train - y_train_pred) / y_train))
mse_train = mean_squared_error(y_train, y_train_pred)
rmse_train = np.sqrt(mse_train)

print("Train Metrics:", mae_train, mape_train, mse_train, rmse_train)
print("Validation Metrics:", mae_validation, mape_validation, mse_validation, rmse_validation)

解读:首先导入BaggingRegressor,创建一个BaggingRegressor实例,其基学习器是使用网格搜索找到的最佳参数的SVM,最后使用Bagging进行训练和预测。看看结果:

大同小异的感觉。

(e)Boosting

这个不用介绍了吧,之前的各种boost系列就是了。

(f)深度学习模型的融合

设计一个深度学习架构,将多个模型的输出作为输入,进一步进行训练。其实很类似之前说的模型堆叠了,只不过次级模型我们自己设计模型框架而已。

以下是如何使用Keras来实现深度学习模型的融合的一个基本示范:

1)首先,为每个模型训练一个独立的模型并保存预测结果。

2)使用这些预测结果作为新的特征,输入到一个深度学习模型中进行训练。

代码的示例:

import numpy as np
from keras.models import Model
from keras.layers import Dense, Input, Concatenate

# 假设我们已经有了3个模型的预测输出
model_1_preds = np.random.rand(1000, 1)
model_2_preds = np.random.rand(1000, 1)
model_3_preds = np.random.rand(1000, 1)

# 这是真实的目标值
y_true = np.random.rand(1000, 1)

# 将3个模型的输出合并为一个新的输入特征
merged_inputs = np.concatenate([model_1_preds, model_2_preds, model_3_preds], axis=1)

# 定义深度学习模型的结构
input_layer = Input(shape=(3,))
dense_1 = Dense(10, activation='relu')(input_layer)
dense_2 = Dense(10, activation='relu')(dense_1)
output_layer = Dense(1)(dense_2)

model = Model(inputs=input_layer, outputs=output_layer)
model.compile(optimizer='adam', loss='mean_squared_error')

# 训练模型
model.fit(merged_inputs, y_true, epochs=50, batch_size=32)

解读:在上述示例中,我们创建了一个简单的神经网络,该网络接收三个模型的预测输出作为输入,并进行进一步的训练。这只是一个基本的例子,实际应用中可能会更复杂。

深度学习模型融合的关键是选择合适的网络结构、损失函数和优化器,以及确保你有足够的数据来训练融合模型。如果数据很少,使用深度学习模型进行融合可能会导致过拟合。

四、写在后面

组合模型不是万能的,还得看数据,因地制宜!!!

不要为了融合而融合!!!

五、数据

链接:https://pan.baidu.com/s/1r32fnMI69LgfxEWa7MHt9w?pwd=62uh

提取码:62uh

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

创建进程中的内核操作

fork 是一个系统调用&#xff0c;流程的最后会在 sys_call_table 中找到相应的系统调用 sys_fork。 _do_fork 里面做的第一件大事就是 copy_process&#xff0c;咱们前面讲过这个思想。如果所有数据结构都从头创建一份太麻烦了&#xff0c;还不如使用惯用“伎俩”&#xff0c;…

shell脚本中数组

分界点&#xff1a;以下内容需要更改&#xff0c;正常放假更改 数组&#xff1a; 数组的作用&#xff1a;可以一次性的定义多个变量&#xff0c;数组的长度是不限的 数组的元素类型&#xff1a;int string float. 就是形成变量池&#xff0c;可以随时的遍历和使用 数组的写…

c#方法中的参数

无参 //无参数直接调用即可MethodWithoutParameters();/// <summary>/// 没有参数的方法/// </summary>private void MethodWithoutParameters(){Debug.Log("没有参数的方法");}有参 //有一个参数MethodWithOneParameters("我是参数");/// <…

【算法|动态规划 | 01背包问题No.2】AcWing 423. 采药

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【AcWing算法提高学习专栏】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&a…

JDBC与MySql数据库

一、系统开发前的环境准备 1.下载Mysql 下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 文件解压缩到本地 在此路径下新增my.ini文件以及新建data文件夹 编辑my.ini文件 配置环境变量 注意是编辑系统变量的Path 以管理员身份运行cmd 输入命令&#xff1a…

【Go】格式化字符串指令大全 Redis常用命令

【Go】格式化字符串指令大全 && Redis常用命令 原创&#xff1a;As.Kai 博客地址&#xff1a;https://blog.csdn.net/qq_42362997 如果以下内容对您有帮助&#xff0c;点赞点赞点赞~ 目录 格式化格式化字符串指令大全%s 用于插入字符串%d 用于插入整数%f 用于插入浮点数…

Spring AOP源码解读

今天我们来分析Spring中AOP的源码&#xff0c;主要是关于SpringAOP是如何发挥作用的。 前期准备 首先我们需要有一个Spring AOP项目&#xff0c;添加好了SpringAOP的依赖。 <dependency><groupId>org.springframework</groupId><artifactId>spring-co…

项目基础配置

1、Spring整合MyBatis&#xff1a; 在子工程中加入所需要的依赖 准备jdbc.properties 创建spring的配置文件、整合spring和mybatis 在spring的配置文件中加载jdbc.properties 配置数据源 测试数据库连接 配置SqlSessionFactoryBean 装配数据源 指定XXXMapper.xml文件的位…

DVWA-SQL Injection SQL注入

概念 SQL注入&#xff0c;是指将特殊构造的恶意SQL语句插入Web表单的输入或页面请求的查询字符串中&#xff0c;从而欺骗后端Web服务器以执行该恶意SQL语句。 成功的 SQL 注入漏洞可以从数据库中读取敏感数据、修改数据库数据&#xff08;插入/更新/删除&#xff09;、对数据…

【已解决】VSCode运行C#控制台乱码显示

问题描述 如上图所示&#xff0c;最近在学习C#突然发现我在运行Hello World的时候出现这样的乱码情况。 分析原因 主要是因为VS Code 是UTF-8的编码格式&#xff0c;而我们的PC是Unicode编码&#xff0c;所以我们需要对其进行一个统一即可解决问题。那么知道这个的问题那就开…

“创新深化 数实融合”,AntDB数据库邀您参与“2023世界数字经济大会暨第十三届智慧城市与智能经济博览会”

10月13日&#xff0c;“2023世界数字经济大会暨第十三届智慧城市与智能经济博览会”将在浙江宁波国际会议展览中心隆重启幕&#xff0c;AntDB数据库受邀参会&#xff0c;并诚挚邀请各位领导嘉宾莅临会场参观指导。 图1&#xff1a;会议邀请函 “2023世界数字经济大会暨第十三届…

BUUCTF Reverse 新年快乐

下载文件先查壳&#xff0c;可以看到有UPX壳 用upx脱壳 拖到ida pro32&#xff0c;shiftF12查看字符串&#xff0c;看到关键字flag&#xff0c;双击进去 双击然后f5查看伪代码 main函数伪代码 关键函数&#xff1a; strncmp(const char *str1, const char *str2, size_t n)…

asp.net老年大学教务管理信息系统VS开发sqlserver数据库web结构c#编程

一、源码特点 asp.net 老年大学教务管理信息系统是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使 用c#语言开发 asp.net老年大学教务管理…

【java学习—十】HashSet集合(4)

文章目录 1. Java集合概述2. HashSet3. 泛型 1. Java集合概述 Java 集合类存放于 java.util 包中&#xff0c;是一个用来存放对象的容器。 ① 集合只能存放对象。比如你存一个 int 型数据 1 放入集合中&#xff0c;其实它是自动转换成 Integer类后存入的&#xff0c; Java 中每…

Animate(原Flash)和木疙瘩中遮罩动画秒懂

遮罩&#xff1a;就是遮住别人的罩&#xff0c;比如桌布遮住桌子&#xff0c;床单遮住床面&#xff01; 桌布就是遮罩层&#xff0c;桌子就是被遮罩层&#xff01; 让一个立方体在圆中显示&#xff0c;把圆作为遮罩层&#xff0c;放在上面图层&#xff01;立方体紧挨放在下面…

C语言 每日一题 PTA 10.29 day7

1.特殊a串数列求和 给定两个均不超过9的正整数a和n&#xff0c;要求编写程序求a aa aaa⋯ aa⋯a&#xff08;n个a&#xff09;之和。 输入格式&#xff1a; 输入在一行中给出不超过9的正整数a和n。 输出格式&#xff1a; 在一行中按照“s 对应的和”的格式输出。 思路 n…

yolov5的pqt、qat量化---1(知识准备工作)

1、Pytorch-Quantization简介 PyTorch Quantization是一个工具包,用于训练和评估具有模拟量化的PyTorch模型。PyTorch Quantization API支持将 PyTorch 模块自动转换为其量化版本。转换也可以使用 API 手动完成,这允许在不想量化所有模块的情况下进行部分量化。例如,一些层可…

LV.12 D11 FS4412开发环境搭建 学习笔记

开发板硬件资源介绍 初识电路原理图 元器件查找 1.搜索丝印 2.查找目录 网络标号 电路图中网络标号相同的节点在电气上是连接在一起的 交叉开发环境搭建 1.在ubuntu下安装交叉编译工具链 2.在windows下安装SecureCRT 3.在windows下安装USB转串口驱动…

C++之Args可变参数模板总结(二百五十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…