利用LSTM长短期记忆算法分析猪肉价格未来走势

1、背景

期望通过科学算法辅助计算未来猪肉价格走势,为养殖户和政府提供相关决策,帮助养殖户判断接下来的养殖规模,帮助政府出台宏观调控政策。
数据为过去几年的历史猪价,可在中国养猪网或统计年鉴中自己获取

2、算法介绍

该算法较与循环神经网络(RNN)基础模型增加了遗忘门和细胞状态更新,解决了梯度消失和梯度爆炸问题,可进行选择性记忆,基于此可以更加科学的为养殖户及相关部门提供决策。该模型使用有效的Adam优化器随机梯度下降进行拟合,并使用均方根误差损失函数进行了优化

3、预测代码

3.1、数据处理

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
import math

plt.rcParams['font.family'] = 'SimHei'## 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False ## 用来正常显示负号


data=pd.read_csv('E:/chy-data/data.csv',usecols=[0,7],index_col='编号')
#删除价格单位所属行
data=data[1:]
#将猪价的数据类型变为float
data['猪肉']=data['猪肉'].astype('float64')
#print(data['猪肉'])
#data[['年','月','周数']]=data[['年','月','周数']].astype('int64')
#data[['出栏肉猪均价','仔猪均价','母猪均价','猪肉','玉米','小麦麸','育肥猪配合料']]=data[['出栏肉猪均价','仔猪均价','母猪均价','猪肉','玉米','小麦麸','育肥猪配合料']].astype('float64')
#查看前五行数据
display(data.head())
#data.describe()
#查看数据概览
data.info()
data=data.values
#print(data)
#print(data[['猪肉']])
#print(data.iloc[:,0])
#print(data.values)
猪肉
编号	
1.0	23.31
2.0	23.36
3.0	23.46
4.0	23.59
5.0	23.81
<class 'pandas.core.frame.DataFrame'>
Float64Index: 257 entries, 1.0 to 257.0
Data columns (total 1 columns):
猪肉    257 non-null float64
dtypes: float64(1)
memory usage: 4.0 KB
plt.figure(figsize=(20,8),dpi=80)
plt.plot(data)
plt.title('2011-2015年每周猪肉价格变化')
plt.show()

3.2、构造时间序列的输入输出、以及数据标准化

#参数初始化
#时间步长
steps = 30
#特征数
features=1
#构造时间序列的输入及输出,及前n个数据作为X,第n+1个数据为预测结果y
def create_dataset(data, steps=1):
    dataX, dataY = [], []
    for i in range(len(data)-steps-1):
        a = data[i:(i+steps), 0]
        dataX.append(a)
        dataY.append(data[i + steps, 0])
    return np.array(dataX), np.array(dataY)
#数据标准化,避免量纲对预测的影响

scaler = MinMaxScaler(feature_range=(0, 1))
#不能对全部数据fit_transform----------data = scaler.fit_transform(data)
#print(data)
#划分训练集和测试集,训练集70%,测试集30%
train_size = int(len(data) * 0.7)
test_size = len(data) - train_size
train,test = data[0:train_size,:], data[train_size:len(data),:]
#train数据进行fit_transform,先对其训练再进行标准化
train=scaler.fit_transform(train)
#test数据只能进行转化,因为测试集是训练后模型用来测试的
test=scaler.transform(test)


#输出data的输入及输出,假设滑动窗口距离为steps,即时间序列的当前数据只受前steps条数据的影响
#steps = 10
trainX, trainY = create_dataset(train, steps)
testX, testY = create_dataset(test, steps)
#display(testX,testY)
#展示单变量拆分后的结果
# for i in range(len(trainX)):
#     print(trainX[i],trainY[i])

3.3、构建LSTM模型并预测

#构造适合LSTM模型的参数格式
#LSTM模型期望的输入数据形状如下[样本数, 时间步长, 特征数]
#features=1
trainX = np.reshape(trainX, (trainX.shape[0], trainX.shape[1],features ))
testX = np.reshape(testX, (testX.shape[0], testX.shape[1],features))
    
    
#建立LSTM模型,隐藏层64个神经元,迭代1000次
#steps时间步长,features特征数量(单变量序列,只考虑猪价,故值为1)
#每个样本的输入形状在第一个隐藏层的定义的input_shape参数中指定
model = Sequential()
model.add(LSTM(64,activation='relu', input_shape=(steps, features)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, epochs=1000, batch_size=10, verbose=0)
    
#进行预测
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)

#print(trainX)
#print(testX)
trainPredict = scaler.inverse_transform(trainPredict)
trainY = scaler.inverse_transform([trainY])
testPredict = scaler.inverse_transform(testPredict)
testY = scaler.inverse_transform([testY])
#保存输出的预测值
pre_testPredict=testPredict[-1][0]
#print(testPredict,testY)
#该模型使用有效的Adam版本随机梯度下降进行拟合,并使用均方误差或“ mse ”损失函数进行了优化。
trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))
print('Train Score: %.2f RMSE' % (trainScore))
testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0]))
print('Test Score: %.2f RMSE' % (testScore))
trainPredictPlot = np.empty_like(data)
trainPredictPlot[:, :] = np.nan
trainPredictPlot[steps:len(trainPredict)+steps, :] = trainPredict

# shift test predictions for plotting
testPredictPlot = np.empty_like(data)
testPredictPlot[:, :] = np.nan
testPredictPlot[len(trainPredict)+(steps*2)+1:len(data)-1, :] = testPredict

#print(testPredict,testY)
print(testPredict.shape,testY.shape)
plt.figure(figsize=(20,8),dpi=80)
#plt.plot(scaler.inverse_transform(data))
plt.plot(data)
plt.plot(trainPredictPlot)
plt.plot(testPredictPlot)
plt.show()
(47, 1) (1, 47)

3.4、存储预测值

#循环预测价格函数
#初始化空一维数组,用于存储所有预测值
scatter_y=np.array([])
for i in range(52):
    
    if i==0:
        data_pre=data
    else:
        #更新data数据,将预测的值作为输入进行下一轮预测
        data_pre=np.concatenate((data_pre,Pending_y),axis=0)
    #使用末尾的步长个值,预测下一个未知值
    #print(data[-steps:,:])
    #将输入数据标准化处理
    Pending_X=scaler.transform(data_pre[-steps:,:]).reshape(-1,steps)
    #print(Pending_X)
    Pending_X = np.reshape(Pending_X, (Pending_X.shape[0], Pending_X.shape[1],features ))
    #预测输出值
    Pending_y = model.predict(Pending_X)
    #反标准化
    Pending_y = scaler.inverse_transform(Pending_y)
    #结果保留2位小数
    Pending_y=np.around(Pending_y, decimals=2)
    #print(Pending_y)
    
    #将所有预测值存储到scatter_y数组
    scatter_y=np.append(scatter_y,Pending_y[0,0])
    #看看怎么生成excel
    #print(scatter_y)

3.5、绘图

#作图,标示预测值
plt.figure(figsize=(20,8),dpi=80)
plt.plot(data)
plt.plot(trainPredictPlot)
sx=np.arange(len(data),len(data_pre)+1)
sxx=[i for i in sx]
plt.scatter(sxx,scatter_y)
plt.show()    

在这里插入图片描述

预测数据导出到csv文件中


result = pd.DataFrame(
    data={
        "周数":[i for i in range(1,len(scatter_y)+1)],
        "猪价预测": np.around(list(scatter_y.reshape(-1)), decimals=2)
        #"預測價格": np.around(list(test_predict.reshape(-1)), decimals=2)
        #"2016年周数":np.randmon.randint(len)
    }
)
result.to_csv("预测结果.csv",encoding='utf_8_sig',sep=',', index=None)
#print(result)
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页