时序数据-LSTM模型-实现用电量预测
生活随笔
收集整理的這篇文章主要介紹了
时序数据-LSTM模型-实现用电量预测
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
作者: 明天依舊可好
QQ交流群: 807041986
原文鏈接: https://mtyjkh.blog.csdn.net/article/details/115612319
深度學習系列:深度學習
我的環境: win10、jupyter notebook、tensorflow2
0.導入相關包設置相關參數
import pandas as pd import matplotlib.pyplot as plt import tensorflow as tf import numpy as npfrom numpy import array from sklearn import metrics from sklearn.preprocessing import MinMaxScaler from keras.models import Sequential from keras.layers import Dense,LSTM,Bidirectional# 數據調節 from scipy.ndimage import gaussian_filter1d from scipy.signal import medfilt# 確保結果可以重現 from numpy.random import seed seed(1) tf.random.set_seed(1)# 設置相關參數 n_timestamp = 24 # 時間戳 train_days = 3500 # 用于訓練的天數 testing_days = 1500 # 用于預測的天數 n_epochs = 25 # 訓練輪數 filter_on = 1 # 激活數據過濾器 # ==================================== # 選擇模型: # 1: 單層 LSTM # 2: 多層 LSTM # 3: 雙向 LSTM # ==================================== model_type = 11.讀取數據
原始數據是以小時為單位的。
url = "./data/AEP_hourly.csv" dataset = pd.read_csv(url) dataset.head()2.將數據整合成以天為單位
以空格為切割符,將Datetime字段后的具體時間點切割掉
dataset_new = dataset for index, row in dataset.iterrows():dataset_new["Datetime"][index] = row["Datetime"].split(" ")[0]dataset_new.head()經過上面的切割后每一天有24份數據(分別對應24個時辰),接下來合并這24份數據。
dataset_new_2 = dataset_new.groupby(by='Datetime')['AEP_MW'].sum()*0.00001dict_dataset = {'Datetime':dataset_new_2.index,'AEP_MW':dataset_new_2.values} dataset_new_3 = pd.DataFrame(dict_dataset) dataset_new_3.head()3.數據預處理
采用高斯過濾和中值過濾,關于中值過濾的相關問題,可以參考我這篇文章【中值濾波】。
dataset = dataset_new_3if filter_on == 1: # 數據集過濾dataset['AEP_MW'] = medfilt(dataset['AEP_MW'], 3) # 中值過濾dataset['AEP_MW'] = gaussian_filter1d(dataset['AEP_MW'], 1.2) # 高斯過濾dataset4.將數據拆分
# 設置訓練和測試數據集 train_set = dataset[0:train_days].reset_index(drop=True) test_set = dataset[train_days: train_days+testing_days].reset_index(drop=True) training_set = train_set.iloc[:, 1:2].values testing_set = test_set.iloc[:, 1:2].values# 將數據標準化,范圍是0到1 sc = MinMaxScaler(feature_range=(0, 1)) training_set_scaled = sc.fit_transform(training_set) testing_set_scaled = sc.fit_transform(testing_set)5.時間戳函數
# 取前 n_timestamp 天的數據為 X;n_timestamp+1天數據為 Y。 def data_split(sequence, n_timestamp):X = []y = []for i in range(len(sequence)):end_ix = i + n_timestampif end_ix > len(sequence)-1:breakseq_x, seq_y = sequence[i:end_ix], sequence[end_ix]X.append(seq_x)y.append(seq_y)return array(X), array(y)X_train, y_train = data_split(training_set_scaled, n_timestamp) X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1) X_test, y_test = data_split(testing_set_scaled, n_timestamp) X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], 1)6.模型構建
# 使用 Keras建構 LSTM模型 if model_type == 1:# 單層 LSTMmodel = Sequential()model.add(LSTM(units=50, activation='relu',input_shape=(X_train.shape[1], 1)))model.add(Dense(units=1)) if model_type == 2:# 多層 LSTMmodel = Sequential()model.add(LSTM(units=50, activation='relu', return_sequences=True,input_shape=(X_train.shape[1], 1)))model.add(LSTM(units=50, activation='relu'))model.add(Dense(1)) if model_type == 3:# 雙向 LSTMmodel = Sequential()model.add(Bidirectional(LSTM(50, activation='relu'),input_shape=(X_train.shape[1], 1)))model.add(Dense(1))model.summary() # 輸出模型結構7.模型訓練
# 模型訓練,batch_size越大越精準,訓練消耗越大 model.compile(optimizer='adam', loss='mean_squared_error') history = model.fit(X_train, y_train, epochs=n_epochs, batch_size=32) loss = history.history['loss'] epochs = range(len(loss))# 得到測試集數據集的預測值 y_predicted = model.predict(X_test)# 將數據還原 y_predicted_descaled = sc.inverse_transform(y_predicted) y_train_descaled = sc.inverse_transform(y_train) y_test_descaled = sc.inverse_transform(y_test) y_pred = y_predicted.ravel() # 將多維數組轉換為一維數組 y_pred = [round(i, 2) for i in y_pred] # 保留兩位小數 y_tested = y_test.ravel() # 將多維數組轉換為一維數組8.可視化結果
# 進行模型預測 y_predicted = model.predict(X_test)# 顯示預測結果 plt.figure(figsize=(8, 7))plt.subplot(3, 2, 3) plt.plot(y_test_descaled, color='black', linewidth=1, label='True value') plt.plot(y_predicted_descaled, color='red', linewidth=1, label='Predicted') plt.legend(frameon=False) plt.ylabel("AEP_MW") plt.xlabel("Day") plt.title("Predicted data (n days)")plt.subplot(3, 2, 4) plt.plot(y_test_descaled[:60], color='black', linewidth=1, label='True value') plt.plot(y_predicted_descaled[:60], color='red', label='Predicted') plt.legend(frameon=False) plt.ylabel("AEP_MW") plt.xlabel("Day") plt.title("Predicted data (first 60 days)")plt.subplot(3, 3, 7) plt.plot(epochs, loss, color='black') plt.ylabel("Loss") plt.xlabel("Epoch") plt.title("Training curve")plt.subplot(3, 3, 8) plt.plot(y_test_descaled-y_predicted_descaled, color='black') plt.ylabel("Residual") plt.xlabel("Day") plt.title("Residual plot")plt.subplot(3, 3, 9) plt.scatter(y_predicted_descaled, y_test_descaled, s=2, color='black') plt.ylabel("Y true") plt.xlabel("Y predicted") plt.title("Scatter plot")plt.subplots_adjust(hspace=0.5, wspace=0.3) plt.show()# 自己定義 MAPE 函數 def mape(y_true, y_pred):return np.mean(np.abs((y_pred - y_true) / y_true)) * 100MSE = metrics.mean_squared_error(y_test_descaled, y_predicted_descaled) # MSE均方誤差 RMSE = metrics.mean_squared_error(y_test_descaled, y_predicted_descaled)**0.5 MAE = metrics.mean_absolute_error(y_test_descaled, y_predicted_descaled) # MAE平方絕對誤差 MAPE = mape(y_test_descaled, y_predicted_descaled) r2 = metrics.r2_score(y_test_descaled, y_predicted_descaled) # 決定系數(擬合優度)接近1越好print("MSE = " + str(round(MSE, 5))) print("RMSE = " + str(round(RMSE, 5))) print("MAE = " + str(round(MAE, 5))) print("MAPE = " + str(round(MAPE, 5))) print("R2 = " + str(round(r2, 5)))
代碼和數據傳送門:https://download.csdn.net/download/qq_38251616/16651321
總結
以上是生活随笔為你收集整理的时序数据-LSTM模型-实现用电量预测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 包装器 tf.keras.layers.
- 下一篇: Sequential 顺序模型和 Mod