使用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了。有大佬知道希望可以教一教。

 

物联沃分享整理
物联沃-IOTWORD物联网 » 使用LSTM预测未来气温

发表评论