时间序列预测(二)基于LSTM的销售额预测

news2025/1/12 23:16:03

时间序列预测(二)基于LSTM的销售额预测

小O:小H,Prophet只根据时间趋势去预测,会不会不太准啊

小H:你这了解的还挺全面,确实,销售额虽然很大程度依赖于时间趋势,但也会和其他因素有关。如果忽略这些因素可能造成预测结果不够准确

小O:那有没有什么办法把这些因素也加进去呢?

小H:那尝试下LSTM吧~

LSTM是一个循环神经网络,能够学习长期依赖。简单的解释就是它在每次循环时,不是从空白开始,而是记住了历史有用的学习信息。理论我是不擅长的,有想深入了解的可在网上找相关资料学习,这里只是介绍如何利用LSTM预测销售额,在训练时既考虑时间趋势又考虑其他因素。

本文主要参考自使用 LSTM 对销售额预测,但是该博客中的介绍数据与上期数据一致,但实战数据又做了更换。为了更好的对比,这里的实战数据也采用上期数据。

数据探索

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns
from fbprophet import Prophet
from sklearn.metrics import mean_squared_error
from math import sqrt
import datetime
from xgboost import XGBRegressor
from sklearn.metrics import explained_variance_score, mean_absolute_error, \
mean_squared_error, r2_score  # 批量导入指标算法

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM
from tensorflow.keras.layers import Dense, Dropout
from sklearn.preprocessing import MinMaxScaler
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import GridSearchCV

以下数据如果有需要的同学可关注公众号HsuHeinrich,回复【数据挖掘-时间序列01】自动获取~

# 读取数据
raw_data = pd.read_csv('train.csv')
raw_data.set_index('datetime', inplace=True)
raw_data.head()

image-20230206153419221

特征工程

# 拆分数据集
num = 24*14 # 将最后2周划分为测试集
train, test = raw_data.iloc[:-num,:], raw_data.iloc[-num:,:]
# 数据缩放
scaler = MinMaxScaler(feature_range=(0,1))
train_scaled=scaler.fit_transform(train)
test_scaled=scaler.transform(test)
# 构造XY(样本数+时间步数+特征数)
def createXY(dataset, n_past, target_p=-1):
    '''
    将数据集构造成LSTM需要的格式
    dataset:数据集
    n_past:时间步数,利用过去n的时间作为特征,以下一个时间的目标值作为当前的y
    target_p:目标值在数据集的位置,默认为-1
    '''
    dataX = []
    dataY = []
    for i in range(n_past, len(dataset)):
        dataX.append(dataset[i - n_past:i, 0:dataset.shape[1]])
        dataY.append(dataset[i,target_p])
    return np.array(dataX),np.array(dataY)

X_train, Y_train=createXY(train_scaled,30)
X_test, Y_test=createXY(test_scaled,30)
X_train.shape
(10520, 30, 11)

可以看到有10520个训练样本,每个样本的形状为30*11,即过去30天的数据集合(30个样本,11个特征)。Y实际为30个样本下一个样本的y值。即第0个训练样本X为原始数据df中[0-29]的所有数据,第0个训练Y为原始数据df中第30个样本的y值

# 定义LSTM
def build_model(optimizer):
    grid_model = Sequential()
    grid_model.add(LSTM(4, return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])))
    grid_model.add(LSTM(4)) # 防止预测值为三维
    grid_model.add(Dropout(0.2))
    grid_model.add(Dense(1))
    grid_model.compile(loss = 'mse',optimizer = optimizer)
    return grid_model 

grid_model=KerasRegressor(build_fn=build_model,verbose=1,validation_data=(X_test,Y_test))
 
parameters = {'batch_size' : [16,20],
            'epochs' : [8,10],
            'optimizer' : ['adam','Adadelta'] }
 
grid_search = GridSearchCV(estimator = grid_model,
                            param_grid = parameters,
                            cv = 2)
<ipython-input-41-930ab96e3919>:11: DeprecationWarning: KerasRegressor is deprecated, use Sci-Keras (https://github.com/adriangb/scikeras) instead. See https://www.adriangb.com/scikeras/stable/migration.html for help migrating.
  grid_model=KerasRegressor(build_fn=build_model,verbose=1,validation_data=(X_test,Y_test))

模型拟合

模型输出

# 模型拟合
grid_search = grid_search.fit(X_train,Y_train)
grid_search.best_params_

image-20221222185137536

# 输出最优模型参数
print(grid_search.best_params_)
# 获取最优模型
model_lstm=grid_search.best_estimator_.model
# 预测值
pre_y=model_lstm.predict(X_test)
{'batch_size': 16, 'epochs': 8, 'optimizer': 'adam'}

模型评估

# 逆缩放
# 构造同等宽度的pre_y,即生成与缩放同等列数
pre_y_repeat = np.repeat(pre_y, X_train.shape[2], axis=-1)
# 逆缩放并获取预测值
pred=scaler.inverse_transform(np.reshape(pre_y_repeat,(len(pre_y), X_train.shape[2])))[:,-1] # 选取目标列所在位置
# 对Y_test进行逆缩放
Y_test_repeat = np.repeat(Y_test, X_train.shape[2], axis=-1)
Y_test_original=scaler.inverse_transform(np.reshape(Y_test_repeat,(len(Y_test),X_train.shape[2])))[:,-1] # 选取目标列所在位置

# 评估指标
model_metrics_functions = [explained_variance_score, mean_absolute_error, mean_squared_error,r2_score]  # 回归评估指标对象集
model_metrics_list = [[m(Y_test_original, pred) for m in model_metrics_functions]]  # 回归评估指标列表
regresstion_score = pd.DataFrame(model_metrics_list, index=['model_xgbr'],
                   columns=['explained_variance', 'mae', 'mse', 'r2'])  # 建立回归指标的数据框
regresstion_score  # 模型回归指标
explained_variancemaemser2
model_xgbr0.76421958.9901797276.3102430.749074

结果展示

预测结果可视化

# 模型效果可视化
fig = plt.figure(figsize=(16,6))
plt.title('True and LSTM result comparison', fontsize=20)
# 时间索引
ds_index = [datetime.datetime.strptime(x, "%Y-%m-%d %H:%M:%S") for x in test.index[30:]]
# 真实序列
true_s=pd.Series(Y_test_original, index=ds_index)
plt.plot(true_s, color='red')
# 预测序列
pre_s=pd.Series(pred, index=ds_index)
plt.plot(pre_s, color='green')
plt.xlabel('Hour', fontsize=16)
plt.ylabel('Number of Shared Bikes', fontsize=16)
plt.legend(labels=['True', 'Pre_y'], fontsize=16)
plt.grid()
plt.show()

output_52_0

预测未来值

# 预测未来值
# 历史30日数据作为构造第一条数据
df_30_days_past=raw_data.iloc[-30:,:]
# 读取未来数据
start_time = '2012-12-19 23:00:00' # 原始数据最后一条记录
end_time=[]
for i in range(30):
    
    time_temp = (datetime.datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S") + datetime.timedelta(
        hours=i+1)).strftime("%Y-%m-%d %H:%M:%S")
    end_time.append(time_temp)

future=pd.read_csv("test.csv",parse_dates=["datetime"],index_col=[0])
df_30_days_future=future.loc[end_time,:]
# 补充缺失的列
df_30_days_future["registered"]=0
df_30_days_future["casual"]=0 # 测试样本缺失
df_30_days_future["count"]=0 # 测试样本缺失
# 构造旧新样本
old_scaled_array=scaler.transform(df_30_days_past)
new_scaled_array=scaler.transform(df_30_days_future)
new_scaled_df=pd.DataFrame(new_scaled_array)
new_scaled_df.iloc[:,-1]=np.nan # 对目标列的0修改为nan
full_df=pd.concat([pd.DataFrame(old_scaled_array),new_scaled_df]).reset_index().drop(["index"],axis=1)
full_df_scaled_array=full_df.values
all_data=[]
time_step=30
for i in range(time_step,len(full_df_scaled_array)):
    data_x=[]
    data_x.append(
        full_df_scaled_array[i-time_step :i , 0:full_df_scaled_array.shape[1]])
    data_x=np.array(data_x)
    prediction=model_lstm.predict(data_x)
    all_data.append(prediction)
    full_df.iloc[i,-1]=prediction # 替换目标列的nan
new_array=np.array(all_data)
new_array=new_array.reshape(-1,1)
prediction_copies_array = np.repeat(new_array,data_x.shape[2], axis=-1)
y_pred_future_30_days = scaler.inverse_transform(np.reshape(prediction_copies_array,(len(new_array),data_x.shape[2])))[:,-1]
print(y_pred_future_30_days)

# 因为测试样本casual和registered缺失,故预测不准确
[ 67.19963   28.726665  53.639095  77.41373   84.80948   97.550125
 105.34982  105.89546  105.45314  101.901405  98.7133    96.72031
 101.96429  107.16215  110.38648  111.0147   110.34529  109.8532
 107.00935  102.02435   91.798004  92.968605  93.628006  94.56274
 102.24291  113.515884  87.92808   78.71299   72.63906   70.64108 ]

总结

可以发现,预测效果还不错。如果在做预测的时候,不仅有时间序列数据,还有获得额外的因素,可以尝试使用LSTM进行预测~

共勉~

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

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

相关文章

YOLOv5教程-如何使用他人的数据集进行训练+测试评估模型

目录 一、前言与数据集 二、划分数据集以及配置文件的修改 1.把图片和.txt标注文件放入对应VOCData文件夹下 2..txt文件转为.xml文件 3.在VOCData目录下创建程序 split_train_val.py 并运行 4.将xml格式转为yolo_txt格式 5.设置测试文件 6.配置文件 三、聚类获得先验框 …

ABeam×StartUp | ABeam旗下艾宾信息技术开发(大连)与大连金勺科技展开合作交流

近日&#xff0c;ABeam 大中华区董事长兼总经理中野洋辅先生及艾宾信息技术开发&#xff08;大连&#xff09;&#xff08;以下简称“ABeam-TDC”&#xff09;的资深顾问团队一行人拜访了大连金勺科技有限公司&#xff08;以下简称“金勺科技”&#xff09;。 双方就各自发展的…

jsjiami.v6加密逆向分析介绍

随着互联网的不断发展&#xff0c;网站的安全性越来越受到重视。JS混淆加密技术是一种常用的保护网站安全的手段。jsjiami.v6是一款常用的JS混淆加密工具&#xff0c;下面我们来详细了解一下。 首先&#xff0c;我们来看一下一个使用jsjiami.v6进行混淆加密的案例代码&#xf…

线上 FullGC 问题排查实践 —— 手把手教你排查线上问题

一、问题发现与排查 1.1 找到问题原因 问题起因是我们收到了 jdos 的容器 CPU 告警&#xff0c;CPU 使用率已经达到 104% 观察该机器日志发现&#xff0c;此时有很多线程在执行跑批任务。正常来说&#xff0c;跑批任务是低 CPU 高内存型&#xff0c;所以此时考虑是 FullGC 引…

LC-1263. 推箱子(网格图BFS + DFS)

1263. 推箱子 难度困难105 「推箱子」是一款风靡全球的益智小游戏&#xff0c;玩家需要将箱子推到仓库中的目标位置。 游戏地图用大小为 m x n 的网格 grid 表示&#xff0c;其中每个元素可以是墙、地板或者是箱子。 现在你将作为玩家参与游戏&#xff0c;按规则将箱子 B 移…

Sleuth和zipkin

1、Sleuth是什么 为什么会出现这个技术&#xff1f;要解决哪些问题&#xff1f; 在微服务框架中&#xff0c;一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后的请求结果&#xff0c;每一个前段请求都会形成一条复杂的分布式服务调用链路&am…

2.RabbitMQ

RabbitMQ 1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&am…

查询文件路径

1 问题 如何利用Java来查询文件的路径&#xff1f; 2 方法 1首先在类中利用main函数调用所有文件的和目录的代码。 2 然后开始写查询展示所有文件和目录的方法&#xff08;运用了递归的思想&#xff09; import java.io.File;import java.util.Arrays;import java.util.Scanner…

ETO、MTO、ATO与MTS(按单设计、按单生产、按单装配和库存生产)

按照企业组织生产的特点&#xff0c;可以把制造企业划分为ETO、ATO、MTO与MTS&#xff08;按单设计、按单装配、按单生产和库存生产&#xff09;四种生产类型。 按单设计&#xff08;Engineer To Order&#xff0c;ETO&#xff09;   在这种生产类型下&#xff0c;一种产品在…

【Sentinel源码分析】

Sentinel源码分析 Sentinel源码分析1.Sentinel的基本概念1.1.ProcessorSlotChain1.2.Node1.3.Entry1.3.1.自定义资源1.3.2.基于注解标记资源 1.4.Context1.4.1.什么是Context1.4.2.Context的初始化1.4.2.1.自动装配1.4.2.2.AbstractSentinelInterceptor1.4.2.3.ContextUtil 2.P…

软件工具 | Python调用运筹优化求解器(一):以CVRPVRPTW为例

目录 1. 引言2. 求解器介绍3. 基础语言3.1 创建模型3.2 添加变量3.3 添加目标函数3.4 添加约束3.5 设置参数3.6 求解 4. 数学模型4.1 [CVRP数学模型](https://mp.weixin.qq.com/s/DYh-5WkrYxk1gCKo8ZjvAw)4.2 [VRPTW数学模型](https://mp.weixin.qq.com/s/tF-ayzjpZfuZvelvItue…

【网络】4万字细品TCP协议

文章目录 TCP协议关于UDP和TCP的优缺点 TCP协议格式4位首部长度可靠性的理解确认应答的工作方式序号和确认序号如何保证报文的顺序呢确认序号的特点:为什么有两套序号总结:序列号的原理 16位窗口大小TCP的缓冲区为什么TCP叫做传输控制协议缓冲区存在的意义 窗口大小 6个标记位为…

python-数据类型

Python基础数据类型(int,str,bool)、格式化输出、程序交换 捕翼 于 2020-07-28 21:29:14 发布 2179 收藏 3 分类专栏&#xff1a; Python3.6.5 版权 Python3.6.5 专栏收录该内容 33 篇文章0 订阅 订阅专栏 文章目录 一、程序交互 二、格式化输出 数据类型&#xff1a; 三、…

四维轻云地理空间数据在线管理软件能够在线管理哪些数据?

四维轻云是一款地理空间数据在线管理软件&#xff0c;支持各类地理空间数据的在线管理、浏览及分享&#xff0c;用户可不受时间地点限制&#xff0c;随时随地查看各类地理空间数据。软件还具有项目管理、场景搭建、素材库等功能模块&#xff0c;支持在线协作管理&#xff0c;便…

Spring Boot 如何让你的 bean 在其他 bean 之前完成加载 ?

问题 今天有个小伙伴给我出了一个难题&#xff1a;在 SpringBoot 中如何让自己的某个指定的 Bean 在其他 Bean 前完成被 Spring 加载&#xff1f;我听到这个问题的第一反应是&#xff0c;为什么会有这样奇怪的需求&#xff1f; Talk is cheap&#xff0c;show me the code&am…

精力管理金字塔

精力管理金字塔 由协和医学院的张遇升博士在《掌控精力&#xff1a;不疲惫的身心管理术》一书中提出&#xff0c;分层次对精力管理提出了解析和有效的建议。 模型介绍 精力管理是一个可以学会的技能&#xff0c;学会了科学的精力管理方法&#xff0c;就能使自己的精力越来越好…

实在智能RPA首推集约式“智能门户超自动化办公"新模式,加速司法、政企数字化升级

随着数字化和智能化的快速发展&#xff0c;数字技术已经深入到各个行业和领域。实在智能基于数字员工在行业的深厚理解和丰富的实践经验&#xff0c;打造一站式的智能化统一平台——智能门户&#xff0c;打破了技术壁垒和系统数据之间的割裂感&#xff0c;实现政府、企业内部信…

2023最新版本Camtasia电脑录屏软件好不好用?

在当今数字化时代&#xff0c;屏幕录制成为了许多用户制作教学视频、演示文稿、游戏攻略等内容的首选。本文将为您介绍几款常用的电脑录屏软件&#xff0c;包括Camtasia、OBS Studio、Bandicam等&#xff0c;并对其进行功能和用户体验方面的比较&#xff0c;同时给出10款电脑录…

PHP语言技术开发的手术麻醉管理系统源码

手术麻醉管理系统用于各个手术室和麻醉科&#xff0c;接受医生工作站、护士工作站发送过来的手术申请单 手术麻醉管理系统(DORIS)是应用于医院手术室、麻醉科室的计算机软件系统。该系统针对整个围术期&#xff0c;对病人进行全程跟踪与信息管理&#xff0c;自动集成病人HIS、…

上海约瑟 HJZ-J913静态中间继电器 导轨安装 触点容量16A/250VAC

品牌&#xff1a;JOSEF约瑟&#xff0c;型号&#xff1a;HJZ-J913&#xff0c;名称&#xff1a;静态中间继电器&#xff0c;额定电压&#xff1a;48220VDC&#xff1b;48415VAC&#xff0c;触点容量&#xff1a;250V/5A&#xff0c;功率消耗&#xff1a;≤5W&#xff0c;动作时…