赞
踩
使用Tensorflow实现LSTM模型预测未来气温
首先本人不是计算机专业,也没有学过算法,对模型只是在会用的阶段,虚心接受大家所有真诚的建议与教导。这里我也是用通俗易懂的语言说一下我的想法,如果有不同意的那就是你对,我多多学习。
数据集我就不提供了,大家可以自己去找,我的格式是这样的globaltem.csv
首先导包
- import pandas as pd
- import matplotlib.pyplot as plt
- import numpy as np
- from keras.layers import Dense, LSTM, Input
- from tensorflow.keras.callbacks import EarlyStopping
- from tensorflow.keras import optimizers
- from keras.models import Model
- from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
定义一个函数进行数据预处理,因为LSTM是用前x个预测后1个数,所以按此将数据划分为训练集和测试集。然后这里的参数look_back(其他人可能叫timestep)就是用前几个预测后1个,如果timestep过大可能会导致预测结果出现是直线的情况。
这里也可以做数据归一化的处理,直接用MinMaxScaler或者按你自己要的来。
- def creat_dataset(dataset, look_back):
- dataX, dataY = [], []
- for i in range(len(dataset)-look_back-1):
- a = dataset[i:(i+look_back)]
- dataX.append(a)
- dataY.append(dataset[i+look_back])
- print(np.array(dataX).shape)
- print(np.array(dataY).shape)
- return np.array(dataX), np.array(dataY)
读数据
- # 读取数据
- df = pd.read_csv('globaltem.csv')
-
- # 特征工程
- look_back = 1
- dataset = np.array(df[['tem']])
- trainX, trainY = creat_dataset(dataset, look_back)
定义模型
-
- # lstm
- def model1(input_shape):
- inputs = Input(shape=input_shape)
- x = LSTM(64)(inputs)
- x = Dense(100)(x)
- x = Dense(1)(x)
- model = Model(inputs=inputs, outputs=x) # 建立模型
- return model
模型的训练与测试。
这里加了早停策略,也就是保留训练过程中准确率最高的模型,防止出现过拟合。大家有兴趣可以自己去搜一下。
- # 模型的训练
-
- model = model1(trainX.shape[1:]) # 实例化模型
- batch_size = 4 # 每一训练批次的样本数量
- epochs = 800 # 最大训练轮数
- opt = optimizers.Adam(learning_rate=0.001) # 优化器
- model.compile(loss='mse',
- optimizer=opt,
- metrics=['mae', 'mse'])
- early_stopping = EarlyStopping(monitor='loss', min_delta=0.001, patience=20) # 早停策略
- history = model.fit(
- trainX, trainY,
- batch_size=batch_size,
- epochs=epochs,
- use_multiprocessing=True, # 使用多线程
- callbacks=[early_stopping]) # 训练模型
- # 测试集上预测
- trainPredict = model.predict(trainX)
- trainPredict = pd.DataFrame(trainPredict)
- trainY = pd.DataFrame(trainY)
预测未来
- yy = []
- yy.append(trainY[0].values[-1:][0])
- x = np.array([dataset[-1 * look_back:]])
- # 预测未来n年
- n = 10
- for i in range(n):
- pred = model.predict(x)
- yy.append(pred[0][0])
- x = np.append(x[0], pred, axis=0)
- x = np.array([pd.DataFrame(x, columns=['rate']).values[-1 * look_back:]])
-
- print("预测未来n年:", yy)
画图将结果可视化,并计算MSE、MAE、r2_score
这里MSE和MAE值越小说明模型效果越好,r2_score值越接近于1说明预测值和真实值完全一样
- # 实际值与预测值比较图
- plt.plot(trainY[0], color='blue', label='true')
- plt.plot(trainPredict[0], color='red', label='pred')
- plt.plot([x for x in range(len(trainY)-1, len(trainY) + n, 1)], yy, color='black', label='pred2')
- plt.legend(loc='upper left')
- plt.show()
-
- # lstm评价
- print("lstm:")
- print("mse", mean_squared_error(trainY[0], trainPredict[0]))
- print("mae", mean_absolute_error(trainY[0], trainPredict[0]))
- print("r2_score", r2_score(trainY[0], trainPredict[0]))
拟合结果和预测结果如下
可以直观的看到拟合结果是非常好的,但是预测效果看着就是不太可能的样子。
我从网上了解到,可能原因有:
1.数据集过少
2.减小timestep步长
3.lstm中units的值过小,也就是这里的参数
4.可能是全连接层Dense 激活函数的原因,进入源文件后可以看到 Dense第一个参数是units,后面就是激活函数,要将其去掉或者改为sigmoid.但我这里已经是None了,我后面又改成了sigmoid结果直接变成0了。有大佬知道希望可以教一教。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。