【价格预测】LSTM价格预测模型(生猪价格、多变量-经管)

news/2025/2/11 2:04:38/

一、前言

        本文基于LSTM模型,使用torch搭载,本文输入的为多变量,输出结果为生猪价格。数据结构如下图所示:

        由于数据本身版权原因,因此仅公布部分数据。

 二、输入特征选择

        明确猪肉价格的伙伴应当知道猪周期的道理。以下是本人浅略简介:

猪肉价格是农产品市场的晴雨表,猪肉是百姓菜篮子中的关键食物。生猪与粮食价格的重要性可以从每年的中央一号文件窥见一斑。对于中国来说,中国人吃掉了全球一半的猪肉。对中国上下五千年的“家文化“中的”家“咬文嚼字可以发现,家里面就是一只猪,足以体现猪在中国国民生活中的重要地位和猪的文化色彩。从量上说,2010年以来,中国猪肉的人均占有量都在45公斤以上。2019年,虽然受到非洲猪瘟疫情的影响,国内猪肉产量有加有较大幅度的下降但仍然达到了4255万吨。而猪肉价格的波动,从消费者的角度来说,猪肉价格上涨将降低人民生活水平,抑制猪肉消费、抑制其他消费,抬高物价水平;从生产者的角度来说,由于我国养猪户大多都是农村散养农民,经济理性程度低,当猪肉价格上涨,农户养猪利润增大,便会扩大生猪养殖,进而造成供给增加,然而随着平衡点的越过,猪肉市场供大于求,又会促使猪肉价格下降,农户养猪热情降低,因而减少生猪供给,进而猪肉价格抬高,农民开始养殖猪肉,这就造成了猪肉价格的周期性波动。而该周期性波动就被称为猪周期。

         “猪周期“与猪肉价格影响因素:猪周期是猪肉价格随着市场经济呈现周期性波动的一种经济现象,具体成因已然陈述,而其具体周期为:

 

        由于猪肉价格与生猪价格的波动高度一致,因此猪肉价格可以使用生猪价格进行代理。由上述所言,在生猪价格的波动分析中需要重点关注猪周期的影响。猪周期是猪肉价格波动的关键原因之一,而生猪的养殖还和养殖成本、市场需求等高度相关,如生猪的食物价格、替代品价格以及宏观经济环境等因素等的影响。

>因此,在选择输入变量时,应当充分考虑到猪周期的影响,选择滞后多少期的变量非常关键。

>本文选择的是相关系数与互信息的选择方法。

 三、时序图绘制

        左图为时间序列图,右图为STL分解图:

 

在STL分解法中周期大致也是小周期6个月,大周期4年左右。通过对生猪价格时间序列的分解,直接证明了猪周期的存在。同时也不难发现,生猪价格波动的季节效应也明显,这符合客观认知

四、自相关分析

自相关图显示,生猪价格具有非常强烈的短期相关性,但事实上延长到18期左右也依然有一定的相关性。质言之,短期相关与长期相关都非常强烈。而从偏相关图可以看出,生猪价格也呈现出了非常明显的周期性和季节性。一个大周期大致持续2年左右,期间也有较多的小周期和季节效应的影响。这进一步佐证了猪周期的存在。而这也充分说明了在生猪价格的分析中,有必要纳入生猪价格滞后期的影响。此外,通过ADF检验,该时间序列为平稳时间序列

LSTM模型

 LSTM,全称Long Short Term Memory(长短期记忆),是一种特殊的递归神经网络。这种网络与一般的前馈神经网络不同,LSTM可以利用时间序列对输入进行分析;质言之,当使用前馈神经网络时,神经网络会认为我们t时刻输入的内容与t+1输入的内容完全无关。为了运用到时间维度上信息,人们设计了递归神经网络RNN,一个简单的递归神经网络可以用这种方式表示:、

 在图中,xt是在t时刻的输入信息,ht是在t时刻的输入信息,我们可以看到神经元A会递归的调用自身并且将t-1时刻的信息传递给t时刻。

而上述简单的递归神经网络存在硬伤,即长期依赖问题:递归神经网络只能处理我们需要较接近的上下文情况。而LSTM从设计之初就是用于解决一般RNN中普遍存在的长期以来问题。使用LSTM可以有效的传递和表达长时间序列中的信息并且不会导致长时间前的有用信息被忽略。此外还可以解决RNN中的梯度爆炸问题。

 在这里,我们可以看到A在 t−1 时刻的输出值 ht−1 被复制到了 t 时刻,与 t 时刻的输入 xt 整合后经过一个带权重和偏置的tanh函数后形成输出,并继续将数据复制到 t+1 时刻,以此循环往复。但与上图朴素的RNN相比,单个LSTM单元拥有更加复杂的内部结构和输入输出:

上述表述借鉴于知乎、CSDN其他博主表述,侵删。

因此,LSTM非常适合用来作时间序列的预测分析,在多特征时间序列预测中也能展现出较快的运行速度和拟合能力。、

六、预测数据

结合生猪价格时间序列的自相关分析,我认为12期多步纳入的期间甚至不能涵盖一个大型猪周期,学习的效果一定不佳。最终的拟合情况正如我所预料,因此,我认为有必要作至少18期的多步预测,而为了减少对2019年-2021年上半年异常数据的学习,减少极端值的影响,我认为还需要再多纳入一个季节效应,因此,最终选择21步的多步预测。

 

七、SHAP可视化

1.神经网络的主要缺陷在于其是一种黑匣子,并不像决策树、线性回归那样知道每一个变量的权重或者说系数。但是SHAP值(Shapley Additive explanations)即沙普利加和解释,是将输出值归因到每一个特征的shapely的值上。可以通过每一个特征的SHAP值来衡量特征对最终输出值的影响。具体阐述本人才疏学浅,参考知乎代码博主进行解释。

 2. 特征数值对生猪价格预测值的影响可视化

以上图像为每个样本绘制其每个特征的SHAP值,这可以更好地理解整体模式,并允许发现预测异常值。每一行代表一个特征,横坐标为SHAP值。一个点代表一个样本,颜色表示特征值(红色高,蓝色低)。

八、部分代码

        仅列示部分核心步骤,请使用Jupyter完成,没有一步到位的。完整代码若需要请私信。

import torch
from torch import nn,optim
import torch.utils.data as Data
import torch.nn.functional as F
import seaborn as sns
import numpy as np
import pandas as pd
import os ,re ,random
import matplotlib.pylab as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
import sklearn.preprocessing as preprocessing
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score,recall_score,precision_score,roc_curve,roc_auc_score,accuracy_score,confusion_matrix,r2_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import brier_score_loss
from sklearn.calibration import calibration_curve
from sklearn import metrics
import scipydf = pd.read_excel('生猪价格数据集-LSTM.xlsx',sheet_name="0")
df.head(148)df = df.iloc[:,1:]plt.plot(df['生猪价格'])df = pd.read_excel('生猪价格数据集-LSTM.xlsx',sheet_name="0")
df = df.iloc[:,1:]
n=21s1 = StandardScaler()
df = s1.fit_transform(df)
x = []
y = []
for i in range(len(df)-n-n):x.append(df[i:i+n])y.append(df[i+n:i+n+n,0])x = np.array(x)
y = np.array(y)
# x = x.reshape(-1,15,n)
X_train,X_test,Y_train ,Y_test= train_test_split(x,y,test_size = 0.2,random_state=1)
X_train = torch.tensor(X_train,dtype = torch.float)
X_test = torch.tensor(X_test,dtype = torch.float)
Y_train  = torch.tensor(Y_train,dtype = torch.float)
Y_test  = torch.tensor(Y_test,dtype = torch.float)train_loader = Data.DataLoader(dataset=Data.TensorDataset(X_train, Y_train),  # 封装进Data.TensorDataset()类的数据,可以为任意维度batch_size=13,  # 每块的大小shuffle=False,  drop_last =True, #丢弃最后一组数据num_workers=0,  # 多进程(multiprocess)来读数据
)
test_loader = Data.DataLoader(dataset=Data.TensorDataset(X_test, Y_test),  # 封装进Data.TensorDataset()类的数据,可以为任意维度batch_size=13,  # 每块的大小shuffle=False,  drop_last =True, num_workers=0,  # 多进程(multiprocess)来读数据
)
Y_test = Y_test.detach().numpy()
print(Y_test)
Y_train = Y_train.detach().numpy()class LSTM(nn.Module):def __init__(self, P,input_size, output_size,w, hidden_layer_size=50):""":param input_size: 输入数据的维度:param hidden_layer_size:隐层的数目:param output_size: 输出的个数"""super().__init__()
#         self.li1 = nn.Sequential(
#             self.lstm(input_x, hidden_cell)#         )self.hidden_layer_size = hidden_layer_sizeself.lstm = nn.LSTM(input_size, hidden_layer_size,num_layers=2,bidirectional =True,dropout=0.3,batch_first=True)self.sigmoid = nn.Sigmoid()self.linear1 = nn.Linear(hidden_layer_size*2, output_size)self.linear2 = nn.Linear(hidden_layer_size*2, hidden_layer_size*2)self.dropout = nn.Dropout(p=P)self.relu = nn.ReLU()self.ww = wdef forward(self, input_x):torch.manual_seed(1)input_x = input_x.reshape(-1,15,n)input_x = self.dropout(input_x)lstm_out, (h_n, h_c) = self.lstm(input_x)
#         print(lstm_out.shape)alpha = F.softmax(self.linear2(lstm_out),dim=1)
#         print(alpha.shape)lstm_out = lstm_out*alphalstm_out = torch.sum(lstm_out,1)linear_out = self.linear1(lstm_out.view(len(input_x), -1))  return linear_outmodel = LSTM(p,input_size,output_size,hidden_size)
loss_function = nn.MSELoss()  # loss
optimizer = torch.optim.Adam(model.parameters(), lr=l)  # 优化器
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=9, gamma=0.95)
result = {}
result['train-mse'] = []
result['train-mape']= []
result['train-loss']= []
result['train-r2']= []
result['test-mse']= []
result['test-mape']= []
result['test-loss']= []
result['test-r2']= []
R2 = 0
for epochs in range(Epochs):loss_mean_train = 0loss_mean_test = 0r2_train = 0r2_test = 0model.train()for data_l in train_loader:seq, labels = data_loptimizer.zero_grad()y_pred = model(seq)labels = torch.squeeze(labels)single_loss = loss_function(y_pred, labels)loss_mean_train += single_loss.item()single_loss.backward()optimizer.step()scheduler.step()model.eval()y_predict = model(X_train).detach().numpy()
#     mse1 = np.sum((Y_train- y_predict) ** 2) / len(Y_train)mape1 = (sum(abs((y_predict - Y_train)/(Y_train+1)))/len(Y_train))*100mape1 = sum(mape1)/len(mape1)r2_train = r2_score(y_predict,Y_train)y_predict = model(X_test)single_loss_test = loss_function(y_predict, torch.squeeze(torch.tensor(Y_test,dtype = torch.float))).item()y_predict = y_predict.detach().numpy()
#     mse2 = np.sum((Y_test - y_predict) ** 2) / len(Y_test)mape2 = (sum(abs((y_predict - Y_test)/(Y_test+1)))/len(Y_test))*100mape2 = sum(mape2)/len(mape2)r2_test = r2_score(y_predict,Y_test)#     result['train-mse'].append(mse1)
#     result['test-mse'].append(mse2)result['train-mape'].append(mape1)result['test-mape'].append(mape2)result['train-r2'].append(r2_train)result['test-r2'].append(r2_test)result['train-loss'].append(loss_mean_train/len(train_loader))result['test-loss'].append(single_loss_test)print('Epochs',epochs,'loss_train',loss_mean_train/len(train_loader),'r2_train',r2_train)print('Epochs',epochs,'loss_test',single_loss_test,'r2_test',r2_test)if R2 < r2_test:R2 =r2_testtorch.save(model, 'model_lstm3.pth')print('已更新保存模型')


http://www.ppmy.cn/news/123489.html

相关文章

房屋价格预测

机器学习——房屋价格预测 点击链接查看文档代码 一&#xff0e;项目概述及计划 项目背景 &#xff1a;影响房屋价格的因素众多&#xff0c;如房屋面积、房屋层数、配套设施等等。 项目要求 &#xff1a;利用竞赛提供的数据&#xff0c;通过分析影响房屋价格的诸多因素来对房…

问题记录 bug1-系统上电挂载异常分区,df与du命令查看文件使用大小显示不一样

linux磁盘分区 在Linux中&#xff0c;一切皆目录&#xff0c;每一块硬盘分区对应Linux的一个目录&#xff0c;所以我们可以通过管理目录来管理硬盘分区&#xff0c;而将硬盘分区与文件目录关联的操作就称为“挂载”【mount】&#xff0c;反之为“卸载”【unmount】 emmc&…

中国智能茶具及电热水壶市场发展分析及投资规模预测报告2022-2028年版

中国智能茶具及电热水壶市场发展分析及投资规模预测报告2022-2028年版 【撰写单位】&#xff1a;鸿晟信合研究院 【报告目录】: 第1章&#xff1a;中国智能茶具及电热水壶行业发展综述 1.1 智能茶具及电热水壶行业报告研究范围 1.1.1 智能茶具及电热水壶行业专业名词解释 1…

香烟价格

上海地区报价,欢迎补漏 改错 有的价格过高或偏底是地域不同 .  品名    产地   批发  零售白沙&#xff08;硬盒&#xff09; 长沙卷烟厂 42.00 4.50 白沙&#xff08;软盒&#xff09; 长沙卷烟厂 37.00 4.00 芙蓉&#xff08;黄盒&#xff09; 常德卷烟厂 22.00 2.…

LM393电压比较器介绍

概述 LM393 是双电压比较器集成电路。主要应用在脉冲发生器、模数转换器、限幅器、数字逻辑门电路、电压比较电路等场合。LM393电压比较器能直接连接TTL和CMOS电平电路。 特点 1、工作温度范围:0℃ --- 70℃&#xff1b; 2、工作电源电压范围宽&#xff0c;单电源、双电源均…

食品级,精准控温,超平民价的米家电水壶2这么6?

如何选择一款好看又实用的电水壶&#xff1f;相信这也是很多消费者关心的问题&#xff0c;容量小、不保温、设计不好看、不实用&#xff0c;这些问题总是困扰着大家&#xff0c;就跟先锋一样&#xff0c;家里小孩多&#xff0c;又特别喜欢喝开水&#xff0c;所以说容量大、保温…

小米米家发布了一款恒温电水壶,红米 3S 也低调上线

作为米家电饭煲之后的第二款产品&#xff0c;米家恒温电水壶依旧是纯白色的外观设计&#xff0c;桶式直立造型。 与市面上常见的带有保温功能的电水壶相比&#xff0c;米家电水壶最大的特点是内建了蓝牙模块&#xff0c;通过蓝牙与手机相连&#xff0c;可在小米智能家庭 App 中…

如何计算价格

在做一些关于销售系统的项目时&#xff0c;肯定避免不了计算价格的功能&#xff0c;所以为了项目的需求&#xff0c;下面就和大家分享一个简单的计算价格的例子。 1、首先就是搭建页面了&#xff0c;代码如下图所示&#xff1a; 页面还是比较简单的&#xff0c;布局了一个卖水…