- 0 写在前面
- 1 这段代码可以直接运行
- 安装包的时候,一定要注意版本兼容问题(我连续搞了三天才整明白了)
大家可以移步下面的链接,要个关注不过分吧~
https://blog.csdn.net/weixin_42521185/article/details/124083897
- 然后我们这里还要一个数据集,我把它上传到这个链接里,大家可以移步自取~
1 这段代码可以直接运行https://download.csdn.net/download/weixin_42521185/85106045
- 如果有不清楚的地方欢迎留言讨论哦!
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten, LSTM, TimeDistributed, RepeatVector
n_in = 168 # 训练数据:一周每个小时的观测数据
n_out = 24 # 预测结果:下一天的24h的数据
n_features = 1
n_test = 1 # 测试集的batchsize 这里取1组数据(168个)进行测试
n_epochs = 50
# 1. 导入数据
def load_data() -> pd.DataFrame:
data = pd.read_excel('data3.xlsx')
data.columns = ['BillingDate', 'VolumnHL'] # 修改一下属性名
return data
# 2. 归一化(可以帮助模型更快拟合)
def max_min_normalization(data:pd.DataFrame) ->pd.DataFrame:
volume = data.VolumnHL.values # 单取出第二列,组成一个向量
volume = volume.reshape(len(volume), 1) # 修改张量形状,多行一列
# print(volume)
# scaler = MinMaxScaler(feature_range=(0, 1)) # 归一化,范围是(0,1)
volume_new = scaler.fit_transform(volume)
volume = volume_new.reshape(len(volume_new), ) # 修改一下形状
data['VolumnHL'] = volume # 更新到data中去
# print(data)
return data
# 3. 划分X和Y
def build_XY(data, n_in, n_out) -> np.array:
data = data.drop(["BillingDate"], axis=1)
X_train, Y_train = [], []
num = data.shape[0]-n_in-n_out+1
for i in range(num): # range是不包括括号内数据的,所以+1
X_train.append(np.array(data.iloc[i:i+n_in]))
Y_train.append(np.array(data.iloc[i+n_in:i+n_in+n_out]["VolumnHL"]))
return np.array(X_train), np.array(Y_train)
# 4. 划分训练集和测试集【注意:测试集是不能出现在训练集中的】
def split_data(x, y, n_test:int):
train_x = x[:-n_test]
test_x = x[-n_test:] # 取最后一组作为测试集
train_y = y[:-n_test]
test_y = y[-n_test:] # 取最后一组,用来计算最后输出的正确性
print(train_x.shape, test_x.shape) # (552, 168, 1) (1, 168, 1)
print(train_y.shape, test_y.shape) # (552, 24) (1, 24)
return train_x, train_y, test_x, test_y
# 5. 构建最简单的LSTM
def build_lstm(n_in: int, n_features: int):
model = Sequential()
model.add(LSTM(12, activation='relu', input_shape=(n_in, n_features)))
model.add(Dropout(0.3))
model.add(Dense(n_out))
model.compile(optimizer='adam', loss='mae')
return model
# 6.模型拟合
def model_fit(train_x, train_y, test_x, test_y, n_features):
model = build_lstm(n_in=n_in, n_features=n_features)
model.compile(loss='mae', optimizer='adam')
model.fit(train_x, train_y, epochs=n_epochs, batch_size=128, verbose=1, validation_data=(test_x, test_y))
m = model.evaluate(test_x, test_y)
print(m)
return model
data = load_data()
scaler = MinMaxScaler(feature_range=(0, 1)) # 归一化,范围是(0,1); 一定要写成全局变量,不然反归一化会受到影响
data = max_min_normalization(data) # 将预测信息归一化到(0,1)之间
data_copy = data.copy()
x, y = build_XY(data_copy, n_in, n_out) # 划分X和Y
# print(x)
# print("++++++++++++++++++++++++++++++")
# print(y)
# print(x.shape, y.shape) # x:553,168,1 y:553,24
train_x, train_y, test_x, test_y = split_data(x, y, n_test)
model = build_lstm(n_in, n_features)
print("------------")
print(model)
print("+++++++++++++")
model = model_fit(train_x, train_y, test_x, test_y, n_features)
predict = model.predict(test_x)
print(predict) # 由于之间喂给网络的数据都是做过归一化的,所以现在数据都是在(0,1)之间
# 7. 反归一化预测数据和真实数据
predict = scaler.inverse_transform(predict)[0] # 一定要用scaler!!!
print(predict)
actual = scaler.inverse_transform(test_y)[0]
print(actual)
# 8. 画图
predict = predict # 模型预测结果
actual = actual # 真实值输出结果
x = [x for x in range(24)]
fig, ax = plt.subplots(figsize=(15, 5), dpi=300)
ax.plot(x, predict, linewidth=2.0, label="predict")
ax.plot(x, actual, linewidth=2.0, label="actual")
ax.legend(loc=2)
# ax.set_title(bf_name)
plt.ylim((0, 900000))
plt.grid(linestyle='-.')
plt.show()
# 9. 输出精确度
error = 0
summery = 0
for i in range(24):
error += abs(predict[i] - actual[i])
summery += actual[i]
acc = 1 - error/summery
print(acc)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)