第78步 时间序列建模实战:随机森林回归建模

news2024/11/27 19:59:56

基于WIN10的64位系统演示

一、写在前面

之前我们以决策树为例子,展示了各种花里胡哨的时间序列建模。

从这一期开始,我们继续基于python构建各种机器学习和深度学习的时间序列预测模型。

同样,这里使用这个数据:

《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个月的发病率数据。

这一期,我们介绍随机森林回归。

二、随机森林回归

(1)代码解读

class sklearn.ensemble.RandomForestRegressor(n_estimators=100, *, criterion='squared_error', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=1.0, max_leaf_nodes=None, min_impurity_decrease=0.0, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, ccp_alpha=0.0, max_samples=None)

咋一看,跟RandomForestClassifier(用于分类,上传送门)参数也差不多,因此,我们列举出它们相同和不同的地方,便于对比记忆:

共同的参数:

n_estimators: 树的数量。

criterion: 用于测量分裂质量的函数。

RandomForestRegressor 可选:{'mse', 'mae'},默认为 'mse'。

RandomForestClassifier 可选:{'gini', 'entropy'},默认为 'gini'。

max_depth: 树的最大深度。

min_samples_split: 分裂内部节点所需的最小样本数。

min_samples_leaf: 叶节点所需的最小样本数。

min_weight_fraction_leaf: 叶节点所需的权重的最小加权总和。

max_features: 在寻找最佳分裂时考虑的特征数量。

max_leaf_nodes: 使用 max_depth 之前的最大叶子节点数。

min_impurity_decrease: 如果节点分裂会导致杂质的减少大于或等于该值,则该节点将被分裂。

bootstrap: 是否使用 bootstrap 样本进行建树。

oob_score: 是否使用 out-of-bag 样本来估计泛化准确度。

n_jobs: 并行运行的任务数。

random_state: 用于控制随机性的种子。

verbose: 控制决策树建立过程的详细程度。

warm_start: 设置为 True 时,重用前一个调用的解决方案来适应并为森林添加更多的估计器。

class_weight (仅 RandomForestClassifier): 与类关联的权重。对于不平衡的分类问题很有用。

特定于 RandomForestClassifier 的参数:

ccp_alpha: 用于最小化成本复杂性修剪的复杂性参数。具有最大成本复杂性的树会被修剪。默认为 0.0。

max_samples: 从 X 中抽取的样本数量,用于训练每个基本估计器。

综上可见,大部分参数对于两者都是相同的,只是它们的默认值或者可选值有所不同。最主要的差异是在于 criterion 参数中回归器和分类器所接受的选项。

(2)单步滚动预测

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

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']

# 初始化随机森林模型
rf_model = RandomForestRegressor()

# 定义参数网格
param_grid = {
    'n_estimators': [50, 100, 150],
    'max_depth': [None, 5, 7],
}

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

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

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

# 使用最佳参数初始化随机森林模型
best_rf_model = RandomForestRegressor(**best_params)

# 在训练集上训练模型
best_rf_model.fit(X_train, y_train)

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

for i in range(len(X_validation)):
    if i == 0:
        pred = best_rf_model.predict([X_validation.iloc[0]])
    else:
        new_features = list(X_validation.iloc[i, 1:]) + [pred[0]] 
        pred = best_rf_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_rf_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)

看结果:

(3)多步滚动预测-vol. 1

import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_absolute_error, mean_squared_error

data = pd.read_csv('data.csv')
data['time'] = pd.to_datetime(data['time'], format='%b-%y')

n = 6  
m = 2  

# 创建滞后期特征
for i in range(n, 0, -1):
    data[f'lag_{i}'] = data['incidence'].shift(n - 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')]

X_train = train_data[[f'lag_{i}' for i in range(1, n+1)]]

# 创建m个目标变量
y_train_list = [train_data['incidence'].shift(-i) for i in range(m)]
y_train = pd.concat(y_train_list, axis=1)
y_train.columns = [f'target_{i+1}' for i in range(m)]
y_train = y_train.dropna()
X_train = X_train.iloc[:-m+1, :]

X_validation = validation_data[[f'lag_{i}' for i in range(1, n+1)]]
y_validation = validation_data['incidence']

rf_model = RandomForestRegressor()

param_grid = {
    'n_estimators': [50, 100, 150],
    'max_depth': [None, 3, 5, 7, 9],

}

grid_search = GridSearchCV(rf_model, param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train, y_train)
best_params = grid_search.best_params_

best_rf_model = RandomForestRegressor(**best_params)
best_rf_model.fit(X_train, y_train)

# 预测验证集
y_validation_pred = []

for i in range(len(X_validation) - m + 1):
    pred = best_rf_model.predict([X_validation.iloc[i]])
    y_validation_pred.extend(pred[0])

# 重叠预测值取平均
for i in range(1, m):
    for j in range(len(y_validation_pred) - i):
        y_validation_pred[j+i] = (y_validation_pred[j+i] + y_validation_pred[j]) / 2

y_validation_pred = np.array(y_validation_pred)[:len(y_validation)]

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)

print(mae_validation, mape_validation, mse_validation, rmse_validation)

# 拟合训练集
y_train_pred = []

for i in range(len(X_train) - m + 1):
    pred = best_rf_model.predict([X_train.iloc[i]])
    y_train_pred.extend(pred[0])

# 重叠预测值取平均
for i in range(1, m):
    for j in range(len(y_train_pred) - i):
        y_train_pred[j+i] = (y_train_pred[j+i] + y_train_pred[j]) / 2

y_train_pred = np.array(y_train_pred)[:len(y_train)]
mae_train = mean_absolute_error(y_train.iloc[:, 0], y_train_pred)
mape_train = np.mean(np.abs((y_train.iloc[:, 0] - y_train_pred) / y_train.iloc[:, 0]))
mse_train = mean_squared_error(y_train.iloc[:, 0], y_train_pred)
rmse_train = np.sqrt(mse_train)

print(mae_train, mape_train, mse_train, rmse_train)

结果:

(4)多步滚动预测-vol. 2

import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_absolute_error, mean_squared_error

data = pd.read_csv('data.csv')
data['time'] = pd.to_datetime(data['time'], format='%b-%y')

n = 6  
m = 2  

# 创建滞后期特征
for i in range(n, 0, -1):
    data[f'lag_{i}'] = data['incidence'].shift(n - 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')]

# 只对X_train、y_train、X_validation取奇数行
X_train = train_data[[f'lag_{i}' for i in range(1, n+1)]].iloc[::2].reset_index(drop=True)

# 创建m个目标变量
y_train_list = [train_data['incidence'].shift(-i) for i in range(m)]
y_train = pd.concat(y_train_list, axis=1)
y_train.columns = [f'target_{i+1}' for i in range(m)]
y_train = y_train.iloc[::2].reset_index(drop=True).dropna()
X_train = X_train.head(len(y_train))

X_validation = validation_data[[f'lag_{i}' for i in range(1, n+1)]].iloc[::2].reset_index(drop=True)
y_validation = validation_data['incidence']

rf_model = RandomForestRegressor()

param_grid = {
    'n_estimators': [50, 100, 150],
    'max_depth': [None, 3, 5, 7, 9],

}

grid_search = GridSearchCV(rf_model, param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train, y_train)
best_params = grid_search.best_params_

best_rf_model = RandomForestRegressor(**best_params)
best_rf_model.fit(X_train, y_train)

# 预测验证集
y_validation_pred = []

for i in range(len(X_validation)):
    pred = best_rf_model.predict([X_validation.iloc[i]])
    y_validation_pred.extend(pred[0])

y_validation_pred = np.array(y_validation_pred)[:len(y_validation)]

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)

print(mae_validation, mape_validation, mse_validation, rmse_validation)

# 预测训练集
y_train_pred = []

for i in range(len(X_train)):
    pred = best_rf_model.predict([X_train.iloc[i]])
    y_train_pred.extend(pred[0])

y_train_pred = np.array(y_train_pred)[:y_train.shape[0]]

mae_train = mean_absolute_error(y_train.iloc[:, 0], y_train_pred)
mape_train = np.mean(np.abs((y_train.iloc[:, 0] - y_train_pred) / y_train.iloc[:, 0]))
mse_train = mean_squared_error(y_train.iloc[:, 0], y_train_pred)
rmse_train = np.sqrt(mse_train)

print(mae_train, mape_train, mse_train, rmse_train)

结果:

(5)多步滚动预测-vol. 3

import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_absolute_error, mean_squared_error

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

n = 6

for i in range(n, 0, -1):
    data[f'lag_{i}'] = data['incidence'].shift(n - i + 1)

data = data.dropna().reset_index(drop=True)
train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
X_train = train_data[[f'lag_{i}' for i in range(1, n+1)]]
m = 3

X_train_list = []
y_train_list = []

for i in range(m):
    X_temp = X_train
    y_temp = data_y['incidence'].iloc[n + i:len(data_y) - m + 1 + i]
    
    X_train_list.append(X_temp)
    y_train_list.append(y_temp)

for i in range(m):
    X_train_list[i] = X_train_list[i].iloc[:-(m-1)]
    y_train_list[i] = y_train_list[i].iloc[:len(X_train_list[i])]

# 模型训练
rf_model = RandomForestRegressor()
param_grid = {
    'n_estimators': [50, 100, 150],
    'max_depth': [None, 3, 5, 7, 9],

}

best_rf_models = []

for i in range(m):
    grid_search = GridSearchCV(rf_model, param_grid, cv=5, scoring='neg_mean_squared_error')
    grid_search.fit(X_train_list[i], y_train_list[i])
    best_rf_model = RandomForestRegressor(**grid_search.best_params_)
    best_rf_model.fit(X_train_list[i], y_train_list[i])
    best_rf_models.append(best_rf_model)

validation_start_time = train_data['time'].iloc[-1] + pd.DateOffset(months=1)
validation_data = data[data['time'] >= validation_start_time]

X_validation = validation_data[[f'lag_{i}' for i in range(1, n+1)]]
y_validation_pred_list = [model.predict(X_validation) for model in best_rf_models]
y_train_pred_list = [model.predict(X_train_list[i]) for i, model in enumerate(best_rf_models)]

def concatenate_predictions(pred_list):
    concatenated = []
    for j in range(len(pred_list[0])):
        for i in range(m):
            concatenated.append(pred_list[i][j])
    return concatenated

y_validation_pred = np.array(concatenate_predictions(y_validation_pred_list))[:len(validation_data['incidence'])]
y_train_pred = np.array(concatenate_predictions(y_train_pred_list))[:len(train_data['incidence']) - m + 1]

mae_validation = mean_absolute_error(validation_data['incidence'], y_validation_pred)
mape_validation = np.mean(np.abs((validation_data['incidence'] - y_validation_pred) / validation_data['incidence']))
mse_validation = mean_squared_error(validation_data['incidence'], y_validation_pred)
rmse_validation = np.sqrt(mse_validation)
print("验证集:", mae_validation, mape_validation, mse_validation, rmse_validation)

mae_train = mean_absolute_error(train_data['incidence'][:-(m-1)], y_train_pred)
mape_train = np.mean(np.abs((train_data['incidence'][:-(m-1)] - y_train_pred) / train_data['incidence'][:-(m-1)]))
mse_train = mean_squared_error(train_data['incidence'][:-(m-1)], y_train_pred)
rmse_train = np.sqrt(mse_train)
print("训练集:", mae_train, mape_train, mse_train, rmse_train)

结果:

三、数据

链接:https://pan.baidu.com/s/1EFaWfHoG14h15KCEhn1STg?pwd=q41n

提取码:q41n

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

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

相关文章

python - os模块 常用api方法和demo练习

文章目录 前言python-os模块常用api方法和demo练习1. 常用方法2. demo 练习3. demo 执行结果 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#…

进入IT行业:选择前端开发还是后端开发?

一、前言 开发做前端好还是后端好&#xff1f;这是一个常见的问题&#xff0c;特别是对于初学者来说。在编程世界中&#xff0c;前端开发和后端开发分别代表着用户界面和数据逻辑&#xff0c;就像城市的两个不同街区一样。但是&#xff0c;究竟哪个街区更适合我们作为开发者呢…

chatgpt 只会死记硬背吗

本周写两篇关于 chatgpt 的随感&#xff0c;我不善于写文档&#xff0c;所以我的文字多是输出直感和观点&#xff0c;而不是知识&#xff0c;没有关于 chatgpt 的原理和应用&#xff0c;甚至术语也不匹配&#xff0c;反正就是想到哪算哪吧。 都说 chatgpt 没有内在逻辑&#xf…

51单片机用IIc控制OLED显示数组内容

为了能够看到51单片机接收到的串口数据&#xff0c;我选择了用oled显示收到的数据&#xff0c;特此花重金买了一块oled屏128X64的屏幕大概10来块钱吧&#xff01;首先要达成的小目标就是能够显示数组的内容&#xff0c;建立一个字符数组&#xff0c;用来接收串口收到的数据&…

北斗智能终端:助力森林保护的新利器

北斗智能终端&#xff1a;助力森林保护的新利器 近年来&#xff0c;大兴安岭图强林业局利用北斗等技术&#xff0c;推进森林保护的数字化进程&#xff0c;为高质量发展注入了新的动力和活力。 据了解&#xff0c;当地利用北斗终端对森林资源进行精准管理。为88名管护员和10名监…

软件设计模式系列之十九——中介者模式

中介者模式目录 1 模式的定义2 举例说明3 结构4 实现步骤5 代码实现6 典型应用场景7 优缺点8 类似模式9 小结 1 模式的定义 中介者模式是一种行为型设计模式&#xff0c;它用于降低对象之间的直接通信&#xff0c;通过引入一个中介者对象来管理对象之间的交互。这种模式有助于…

如何配置代理

打开Clask&#xff0c;设置为系统代理&#xff0c;选择规则判断&#xff0c;规则判断就是需要走代理的走代理&#xff0c;不需要走的就不用走代理 本地使用代理 如何想要让某个地方使用代理&#xff0c;可以直接在该地方的终端进行设置 先复制一下终端代理命令&#xff0c;然…

python使用mitmproxy和mitmdump抓包在手机上抓包(三)

现在手机的使用率远超过电脑&#xff0c;所以这篇记录用mitmproxy抓手机包&#xff0c;实现手机流量监控。 环境&#xff1a;win10 64位&#xff0c;Python 3.10.4&#xff0c;雷电模拟器4.0.78&#xff0c;android版本7.1.2&#xff08;设置-拉至最底部-关于平板电脑&#xf…

一篇博客学会系列(2)—— C语言中的自定义类型 :结构体、位段、枚举、联合体

目录 前言 1、结构体 1.1、结构体类型的声明 1.2、特殊的结构体类型声明 1.3、结构体的自引用 1.4、结构体的定义和初始化 1.5、结构体成员变量的调用 1.6、结构体内存对齐 1.6.1、offsetof 1.6.2、结构体大小的计算 1.6.3、为什么存在内存对齐&#xff1f; 1.7、…

C理解(一):内存与位操作

本文主要探讨C语言的内存和为操作操作相关知识。 冯诺依曼结构和哈佛结构 冯诺依曼结构&#xff1a;数据和代码放在一起,便于读取和修改,安全性低 哈佛结构是&#xff1a;数据和代码分开存放,安全性高,读取和修麻烦 内存 内存是用来存储全局变量、局…

chatgpt,神经网络与拥塞控制

chatgpt 是一个巨大的带答案的完形填空题库&#xff0c;它可以回答几乎所有的文字类问题&#xff0c;不保证完全正确&#xff0c;但大致正确。它是怎么做到的&#xff1f; 它怎么知道我要问什么&#xff0c;如果它知道我要问什么&#xff0c;那么问题的不同表达形式它也一定知…

如何利用AI算法+EasyCVR视频监控技术打造鱼塘养殖监管方案

对鱼塘养殖行业来说&#xff0c;养殖区域面积大、管理难&#xff0c;经常会遇到偷钓者、盗窃鱼苗、非法入侵等监管难题。传统的人工监管模式不仅耗费人力成本&#xff0c;而且监管效率低下&#xff0c;无法满足当前养殖户的需求。因此&#xff0c;搭建智能化的远程视频监控系统…

Linux 基本语句_5_创建静态库|动态库

静态库 创建主函数&#xff1a;main.c 应用函数&#xff1a;add.c、sub.c、mul.c 创建calc.h文件作为头文件 生成可执行文件*.o文件 gcc -c add.c -o add.o ....包装*.o文件为静态库 ar -rc libmymath.a add.o sub.o mul.o编译静态库并指明创建静态库的位置 sudo gcc mai…

原型、原型链、判断数据类型

目录 作用 原型链 引用类型&#xff1a;__proto__(隐式原型)属性&#xff0c;属性值是对象函数&#xff1a;prototype(原型)属性&#xff0c;属性值是对象 Function&#xff1a;本身也是函数 相关方法 person.prototype.isPrototypeOf(stu) Object.getPrototypeOf(objec…

论企业IPV4和IPV6网络融合互通网络规划设计

01、IPv6改造问题及整体改造思路 随着“十四五”期间国家政策对IPv6深化改造及规模部署的推动&#xff0c;在IPv6改造过程中出现了越来越多的系统性问题&#xff0c;如图1所示。 图1 关于IPv6改造的各种疑问 所有跨设备通信的IT软硬件系统均需要处理IP地址&#xff0c;各领域…

Android SDK目录结构

目录结构如下&#xff1a; 1&#xff1a;add-ons 该目录中存放 Android 的扩展库&#xff0c;比如 Google Maps&#xff0c;但若未选择安装 Google API&#xff0c;则该目录为空。 2&#xff1a;build-tools 编译工具目录&#xff1a;保存了Android开发常用的工具&#xff0…

【.NET源码解读】Configuration组件及自动更新

Configuration组件是.NET中一个核心的、非常重要的组件。它提供了一种方便的机制&#xff0c;用于从配置文件、环境变量、命令行参数等各种数据源中读取和配置应用程序&#xff0c;以满足不同环境下应用程序的需求。 在本篇文章中&#xff0c;将会介绍Configuration的基本用法…

使用Visual Studio调试排查Windows系统程序audiodg.exe频繁弹出报错

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…

智慧燃气平台的总体架构到底应怎样设计?

关键词&#xff1a;智慧燃气、智慧燃气平台、智能燃气、智能监控 智慧燃气平台功能设计的一些方向和思考&#xff1a; 1、资源统一&#xff0c;管理调度 城市燃气智慧调度运营管理平台收集并且整理出每个业务系统信息&#xff0c;并且根据所整理出的信息结果制定出标准规范&…

Excel·VBA分列、字符串拆分

看到一篇博客《VBA&#xff0c;用VBA进行分列&#xff08;拆分列&#xff09;的2种方法》&#xff0c;使用VBA对字符串进行拆分 目录 Excel分列功能将字符串拆分为二维数组&#xff0c;Split函数举例 将字符串拆分为一维数组&#xff0c;正则表达式举例 Excel分列功能 Sub 测…