python短期电力预测——基于LSTM神经网络
生活随笔
收集整理的這篇文章主要介紹了
python短期电力预测——基于LSTM神经网络
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
LSTM神經網絡,一種中長期記憶時間序列預測模型,通過長期得到數據來預測未來短期的結果,對中長期預測效果很差,本文只介紹單變量預測,即通過多天的電力數據來預測短期的電力,影響因素只有時間,不考慮其他影響因素(本文只是博主自己為了應付本次泰迪杯所自己去學習而所寫的,也只供自己學習和便于查看,有所錯誤還望斧正),本次所用的數據來自泰迪杯官網所公布的部分數據,大概長這樣
?整個的步驟流程如下:
1.數據清洗
- 缺失值處理(先進行缺失值查看,有的話就處理,沒有就不處理)
- 異常值處理(先進行異常值查看,有的話幾進行處理,沒有就不處理,本文用箱型圖來查看有無缺失值)
- 歸一化處理
2.特征工程
- 特征提取
- 訓練集測試集的劃分(0.2),16個數據構成一個樣本(自己看情況選擇)
- 對樣本進行批處理(使其訓練更快)
3.模型構建
- 使用lstm神經網絡,選取8個神經元
4.訓練模型
5.測試模型
- 模型預測
- 計算模型r^2值
- 計算模型精確度
- 代碼:
- # -*- coding: utf-8 -*- # @Time : 2022/3/22 15:36 # @Author : 中意灬 # @FileName: test2.py # @Software: PyCharm import csv import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import r2_score import tensorflow as tf from tensorflow.python.keras import Sequential, layers, utils def predict_next(model, sample, epoch=20):temp1 = list(sample[:,0])for i in range(epoch):sample = sample.reshape(1, x_Seq_len, 1)pred = model.predict(sample)value = pred.tolist()[0][0]temp1.append(value)sample = np.array(temp1[i+1 : i+x_Seq_len+1])return temp1 def create_new_dataset(dataset, seq_len=12):'''基于原始數據集構造新的序列特征數據集Params:dataset : 原始數據集seq_len : 序列長度(時間跨度)Returns:X, y'''X = [] # 初始特征數據集為空列表y = [] # 初始標簽數據集為空列表,y標簽為樣本的下一個點,即預測點start = 0 # 初始位置end = dataset.shape[0] - seq_len # 截止位置,dataset.shape[0]就是有多少條for i in range(start, end): # for循環構造特征數據集sample = dataset[i: i + seq_len] # 基于時間跨度seq_len創建樣本label = dataset[i + seq_len] # 創建sample對應的標簽X.append(sample) # 保存sampley.append(label) # 保存label# 返回特征數據集和標簽集return np.array(X), np.array(y) def split_dataset(X, y, train_ratio=0.8):'''基于X和y,切分為train和testParams:X : 特征數據集y : 標簽數據集train_ratio : 訓練集占X的比例Returns:X_train, X_test, y_train, y_test'''X_len = len(X) # 特征數據集X的樣本數量train_data_len = int(X_len * train_ratio) # 訓練集的樣本數量X_train = X[:train_data_len] # 訓練集y_train = y[:train_data_len] # 訓練標簽集X_test = X[train_data_len:] # 測試集y_test = y[train_data_len:] # 測試集標簽集# 返回值return X_train, X_test, y_train, y_test# 功能函數:基于新的X_train, X_test, y_train, y_test創建批數據(batch dataset)def create_batch_data(X, y, batch_size=32, data_type=1):'''基于訓練集和測試集,創建批數據Params:X : 特征數據集y : 標簽數據集batch_size : batch的大小,即一個數據塊里面有幾個樣本data_type : 數據集類型(測試集表示1,訓練集表示2)Returns:train_batch_data 或 test_batch_data'''if data_type == 1: # 測試集dataset = tf.data.Dataset.from_tensor_slices((tf.constant(X), tf.constant(y))) # 封裝X和y,成為tensor類型test_batch_data = dataset.batch(batch_size) # 構造批數據# 返回return test_batch_dataelse: # 訓練集dataset = tf.data.Dataset.from_tensor_slices((tf.constant(X), tf.constant(y))) # 封裝X和y,成為tensor類型train_batch_data = dataset.cache().shuffle(1000).batch(batch_size) # 構造批數據# 返回return train_batch_data if __name__ == '__main__':plt.rcParams['font.sans-serif'] = ['SimHei'] # 顯示中文標簽plt.rcParams['axes.unicode_minus'] = False#解決負數問題x_Seq_len=16dataset = pd.read_csv("C:/Users/97859/Documents/WPS Cloud Files/319911131/附件1-區域15分鐘負荷數據.csv", encoding='GBK')dataset['數據時間']=pd.to_datetime(dataset['數據時間'],format="%Y-%m-%d %H:%M:%S")dataset.index=dataset.數據時間#將其索引變為時間dataset.drop(columns='數據時間',axis=1,inplace=True)plt.figure()plt.plot(dataset)plt.show()"""數據清洗"""#缺失值處理#查看是否有缺失值print(dataset.info())#無缺失值# print(dataset[dataset.isnull()==False])#無# dataset['總有功功率(kw)']=dataset['總有功功率(kw)'].fillna(0) 對缺失值填值處理# dataset1=dataset[dataset['總有功功率(kw)'].notnull()] 剔除存在缺失值的數據,自己選擇一直缺失值處理的方法#異常值處理"""箱型圖查看"""f, ax = plt.subplots()sns.boxplot(y='總有功功率(kw)', data=dataset, ax=ax)plt.show()s = dataset.describe()# 基本統計量,存在異常值的將其篩選出來進行處理,可以用中位數填值或者眾數填值,方法任選,這里沒有異常值就沒有處理q1 = s.loc['25%']q3 = s.loc['75%']iqr = q3 - q1#分位差mi = q1 - 1.5 * iqr#下限,低于這個為異常值ma = q3 + 1.5 * iqr#上限,高于這個為異常值#無異常值"""歸一化處理,均值為0,方差為1"""scaler = MinMaxScaler()dataset['總有功功率(kw)'] = scaler.fit_transform(dataset['總有功功率(kw)'].values.reshape(-1, 1))#將歸一化的數據保持with open('data.csv','w',encoding='utf-8',newline='')as f:w=csv.writer(f)w.writerow(dataset['總有功功率(kw)'])#歸一化后的繪圖dataset['總有功功率(kw)'].plot()plt.show()"""特征提取(特征工程)"""dataset_new = dataset# X為特征數據集,y為標簽數據集X, y = create_new_dataset(dataset_new.values, seq_len=x_Seq_len)# X_train為數據訓練集,X_test為數據測試集,y_train為標簽訓練集,y_test為標簽測試集合X_train, X_test, y_train, y_test = split_dataset(X, y)# 基于新的X_train, X_test, y_train, y_test創建批數據(batch dataset)# 測試批數據test_batch_dataset = create_batch_data(X_test, y_test, batch_size=24, data_type=1)# 訓練批數據train_batch_dataset = create_batch_data(X_train, y_train, batch_size=24, data_type=2)"""構建模型"""model = Sequential([layers.LSTM(8, input_shape=(x_Seq_len, 1)),layers.Dense(1)])# 定義 checkpoint,保存權重文件file_path = "best_checkpoint.hdf5"#將數據加載到內存checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(filepath=file_path,monitor='loss',mode='min',save_best_only=True,save_weights_only=True)"""編譯運行預測"""# 模型編譯model.compile(optimizer='adam', loss="mae")# 模型訓練(次數200)history = model.fit(train_batch_dataset,epochs=100,validation_data=test_batch_dataset,callbacks=[checkpoint_callback])# 顯示 train loss 和 val lossplt.figure()plt.plot(history.history['loss'], label='train loss')plt.plot(history.history['val_loss'], label='val loss')plt.title("LOSS")plt.xlabel("Epochs")plt.ylabel("Loss")plt.legend(loc='best')plt.show()# 模型驗證test_pred = model.predict(X_test, verbose=1)plt.figure()d1=plt.plot(y_test, label='True')d2=plt.plot(test_pred, label='pred')plt.legend([d1,d2],labels=['True','pred'])plt.show()# 計算r2score = r2_score(y_test, test_pred)print("r^2 的值: ", score)# 繪制test中前100個點的真值與預測值y_true = y_test # 真實值y_pred = test_pred # 預測值fig, axes = plt.subplots(2, 1)ax0=axes[0].plot(y_true, marker='o', color='red',label='true')ax1=axes[1].plot(y_pred, marker='*', color='blue',label='pred')plt.show()"""模型測試"""# 選擇test中的最后一個樣本sample = X_test[-1]sample = sample.reshape(1, sample.shape[0], 1)# 模型預測sample_pred = model.predict(sample)#predict()預測標簽值ture_data = X_test[-1] # 真實test的最后20個數據點# 預測后48個點preds=predict_next(model,ture_data,48)# 繪圖plt.figure()plt.plot(preds, color='yellow', label='Prediction')plt.plot(ture_data, color='blue', label='Truth')plt.xlabel("Epochs")plt.ylabel("Value")plt.legend(loc='best')plt.show() relative_error = 0 '''模型精確度計算''' for i in range(len(y_pred)):relative_error += (abs(y_pred[i] - y_true[i]) / y_true[i]) ** 2 acc = 1- np.sqrt(relative_error / len(y_pred)) print(f'模型的測試準確率為:',acc) ?結果分析:
- 電力數據可視化
?缺失值查看(無缺失)
?箱型圖查看異常值(無異常)
?數據歸一化后可視化
損失值變化(loss:訓練集的損失值;val_loss:測試集的損失值。當loss下降,val_loss也下降,且兩條線逐漸擬合,則說明訓練網絡正常,是最理想情況)
?訓練集中的預測值與實際值可視化
?預測后48個點可視化
?最終計算得到的r^2和模型精確度
6.數據集
?數據集???????
總結
以上是生活随笔為你收集整理的python短期电力预测——基于LSTM神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ajax 高并发请求,理解node.js
- 下一篇: 我用python自制hosts修改神器,