時間序列預測 — VMD-LSTM實現單變量多步光伏預測(Tensorflow):單變量轉為多變量

目錄

1?數據處理

1.1 導入庫文件

1.2 導入數據集

1.3 缺失值分析

2 VMD經驗模態分解

3?構造訓練數據

4 LSTM模型訓練

5 預測


1?數據處理

1.1 導入庫文件

import time
import datetime
import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt  
from sampen import sampen2  # sampen庫用于計算樣本熵
from vmdpy import VMD  # VMD分解庫import tensorflow as tf 
from sklearn.cluster import KMeans
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error, mean_absolute_percentage_error 
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Dropout, LSTM, GRU
from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping# 忽略警告信息
import warnings
warnings.filterwarnings('ignore')  

1.2 導入數據集

實驗數據集采用數據集8:新疆光伏風電數據集(下載鏈接),數據集包括組件溫度(℃) 、溫度(°)?? ?氣壓(hPa)、濕度(%)、總輻射(W/m2)、直射輻射(W/m2)、散射輻射(W/m2)、實際發電功率(mw)特征,時間間隔15min。對數據進行可視化:

# 導入數據
data_raw = pd.read_excel("E:\\課題\\08數據集\\新疆風電光伏數據\\光伏2019.xlsx")
data_raw
from itertools import cycle
# 可視化數據
def visualize_data(data, row, col):cycol = cycle('bgrcmk')cols = list(data.columns)fig, axes = plt.subplots(row, col, figsize=(16, 4))fig.tight_layout()if row == 1 and col == 1:  # 處理只有1行1列的情況axes = [axes]  # 轉換為列表,方便統一處理for i, ax in enumerate(axes.flat):if i < len(cols):ax.plot(data.iloc[:,i], c=next(cycol))ax.set_title(cols[i])else:ax.axis('off')  # 如果數據列數小于子圖數量,關閉多余的子圖plt.subplots_adjust(hspace=0.6)plt.show()visualize_data(data_raw.iloc[:,1:], 2, 4)

?單獨查看部分功率數據,發現有較強的規律性。

?因為只是單變量預測,只選取實際發電功率(mw)數據進行實驗:

1.3 缺失值分析

首先查看數據的信息,發現并沒有缺失值

data_raw.info()

?進一步統計缺失值

data_raw.isnull().sum()

2 VMD經驗模態分解

使用VMD將目標信號分解成若干個模態,進一步可視化分解結果

# VMD分解函數
# signal: 輸入信號
# alpha: 正則化參數
# tau: 時間尺度參數
# K: 分量數量
# DC: 是否包括直流分量
# init: 初始化方法
# tol: 收斂容限
# n_ite: 最大迭代次數
def vmd_decompose(series=None, alpha=2000, tau=0, K=7, DC=0, init=1, tol=1e-7, draw=True): # 得到 VMD 分解后的各個分量、分解后的信號和頻率imfs_vmd, imfs_hat, omega = VMD(series, alpha, tau, K, DC, init, tol)  # 將 VMD 分解分量轉換為 DataFrame, 并重命名df_vmd = pd.DataFrame(imfs_vmd.T)df_vmd.columns = ['imf'+str(i) for i in range(K)]return df_vmd
df_vmd = vmd_decompose(data_raw['實際發電功率(mw)'])  # 對 df_raw_data['AQI'] 進行 VMD 分解,并將結果賦值給 df_vmd
# 繪制 df_vmd 的數據,以子圖形式顯示每個分量
ax = df_vmd.plot(title='VMD Decomposition', figsize=(16,8), subplots=True,fontsize=16)
for a in ax:a.legend(loc='upper right',prop={'size': 14})plt.subplots_adjust(hspace=0.5)

將原始數據和分解后的模態合并

df_vmd['sum'] = data_raw['實際發電功率(mw)']  # 將 data_raw['實際發電功率(mw)']添加到 df_vmd 中的 'sum' 列

?這里利用VMD-LSTM進行預測的思路是通過VMD將原始功率分解為多個變量,然后將分解變量作為輸入特征,將原始出力功率作為標簽,將單變量轉為多變量進行預測。

3?構造訓練數據

構造訓練數據,也是真正預測未來的關鍵。首先設置預測的timesteps時間步、predict_steps預測的步長(預測的步長應該比總的預測步長小),length總的預測步長,參數可以根據需要更改。

timesteps = 96*5 #構造x,為96*5個數據,表示每次用前96*5個數據作為一段
predict_steps = 96 #構造y,為96個數據,表示用后96個數據作為一段
length = 96 #預測多步,預測96個數據
feature_num = 7 #特征的數量

通過前5天的timesteps數據預測后一天的數據predict_steps個,需要對數據集進行滾動劃分(也就是前timesteps行的特征和后predict_steps行的標簽訓練,后面預測時就可通過timesteps行特征預測未來的predict_steps個標簽)。因為是多變量,特征和標簽分開劃分,不然后面歸一化會有信息泄露的問題。

# 構造數據集,用于真正預測未來數據
# 整體的思路也就是,前面通過前timesteps個數據訓練后面的predict_steps個未來數據
# 預測時取出前timesteps個數據預測未來的predict_steps個未來數據。
def create_dataset(datasetx,datasety,timesteps=36,predict_size=6):datax=[]#構造xdatay=[]#構造yfor each in range(len(datasetx)-timesteps - predict_steps):x = datasetx[each:each+timesteps]y = datasety[each+timesteps:each+timesteps+predict_steps]datax.append(x)datay.append(y)return datax, datay

數據處理前,需要對數據進行歸一化,按照上面的方法劃分數據,這里返回劃分的數據和歸一化模型,函數的定義如下:

# 數據歸一化操作
def data_scaler(datax,datay):# 數據歸一化操作scaler1 = MinMaxScaler(feature_range=(0,1))scaler2 = MinMaxScaler(feature_range=(0,1))datax = scaler1.fit_transform(datax)datay = scaler2.fit_transform(datay)# 用前面的數據進行訓練,留最后的數據進行預測trainx, trainy = create_dataset(datax[:-timesteps-predict_steps,:],datay[:-timesteps-predict_steps,0],timesteps, predict_steps)trainx = np.array(trainx)trainy = np.array(trainy)return trainx, trainy, scaler1, scaler2

然后對數據按照上面的函數進行劃分和歸一化。通過前5天的96*5數據預測后一天的數據96個,需要對數據集進行滾動劃分(也就是前96*5行的特征和后96行的標簽訓練,后面預測時就可通過96*5行特征預測未來的96個標簽)

datax = df_vmd[:,:-1]
datay = df_vmd[:,-1].reshape(df_vmd.shape[0],1)
trainx, trainy, scaler1, scaler2 = data_scaler(datax, datay)

4 LSTM模型訓練

首先搭建模型的常規操作,然后使用訓練數據trainx和trainy進行訓練,進行50個epochs的訓練,每個batch包含128個樣本(建議使用GPU進行訓練)。預測并計算誤差,訓練好將模型保存,并進行可視化,將這些步驟封裝為函數。

# # 創建lSTM模型
def LSTM_model_train(trainx, trainy):# 調用GPU加速gpus = tf.config.experimental.list_physical_devices(device_type='GPU')for gpu in gpus:tf.config.experimental.set_memory_growth(gpu, True)# LSTM網絡構建 start_time = datetime.datetime.now()model = Sequential()model.add(LSTM(128, input_shape=(timesteps, feature_num), return_sequences=True))model.add(Dropout(0.5))model.add(LSTM(128, return_sequences=True))model.add(LSTM(64, return_sequences=False))model.add(Dense(predict_steps))model.compile(loss="mean_squared_error", optimizer="adam")# 模型訓練model.fit(trainx, trainy, epochs=50, batch_size=128)end_time = datetime.datetime.now()running_time = end_time - start_time# 保存模型model.save('vmd_lstm_model.h5')# 返回構建好的模型return modely
model = LSTM_model_train(trainx, trainy)

5 預測

首先加載訓練好后的模型

# 加載模型
from tensorflow.keras.models import load_model
model = load_model('vmd_lstm_model.h5')

準備好需要預測的數據,訓練時保留了6天的數據,將前5天的數據作為輸入預測,將預測的結果和最后一天的真實值進行比較。

y_true = datay[-timesteps-predict_steps:-timesteps]
x_pred = datax[-timesteps:]

預測并計算誤差,并進行可視化,將這些步驟封裝為函數。

# 預測并計算誤差和可視化
def predict_and_plot(x, y_true, model, scaler, timesteps):# 變換輸入x格式,適應LSTM模型predict_x = np.reshape(x, (1, timesteps, feature_num))  # 預測predict_y = model.predict(predict_x)predict_y = scaler.inverse_transform(predict_y)y_predict = []y_predict.extend(predict_y[0])# 計算誤差r2 = r2_score(y_true, y_predict)rmse = mean_squared_error(y_true, y_predict, squared=False)mae = mean_absolute_error(y_true, y_predict)mape = mean_absolute_percentage_error(y_true, y_predict)print("r2: %.2f\nrmse: %.2f\nmae: %.2f\nmape: %.2f" % (r2, rmse, mae, mape))# 預測結果可視化cycol = cycle('bgrcmk')plt.figure(dpi=100, figsize=(14, 5))plt.plot(y_true, c=next(cycol), markevery=5)plt.plot(y_predict, c=next(cycol), markevery=5)plt.legend(['y_true', 'y_predict'])plt.xlabel('時間')plt.ylabel('功率(kW)')plt.show()return y_predict
y_predict_nowork = predict_and_plot(x_pred, y_true, model, scaler2, timesteps)

最后得到可視化結果,發下可視化結果并不是太好,可以通過調參和數據處理進一步提升模型預測效果。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/208802.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/208802.shtml
英文地址,請注明出處:http://en.pswp.cn/news/208802.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

優化算法 學習記錄

文章目錄 相關資料 優化算法梯度下降學習率牛頓法 隨機梯度下降小批量隨機梯度下降動量法動量法解決上述問題 AdaGrad 算法RMSProp算法Adam學習率調度器余弦學習率調度預熱 相關資料 李沐 動手學深度學習 優化算法 優化算法使我們能夠繼續更新模型參數&#xff0c;并使損失函…

Elasticsearch:使用 Elasticsearch 向量搜索及 RAG 來實現 Chatbot

Elasticsearch 的向量搜索為我們的語義搜索提供了可能。而在人工智能的動態格局中&#xff0c;檢索增強生成&#xff08;Retrieval Augmented Generation - RAG&#xff09;已經成為游戲規則的改變者&#xff0c;徹底改變了我們生成文本和與文本交互的方式。 RAG 使用大型語言模…

Android TextView 超出省略失效 解決方法

解決方法 我是在使用 ConstraintLayout 嵌套 LinearLayout 水平方向&#xff0c;TextView 又使用layout_weight&#xff08;權重&#xff09;情況下出現這種問題&#xff0c;最后將layout_width從 0dp 改為 1dp 得以解決。 <androidx.constraintlayout.widget.ConstraintLa…

MongoDB的刪除文檔、查詢文檔語句

本文主要介紹MongoDB的刪除文檔、查詢文檔命令語句。 目錄 MongoDB刪除文檔MongoDB查詢文檔 MongoDB刪除文檔 MongoDB是一種基于文檔的NoSQL數據庫&#xff0c;它使用BSON格式存儲文檔。刪除文檔是MongoDB數據庫中的常見操作之一。 下面是MongoDB刪除文檔的詳細介紹和示例&am…

當年為什么選擇計算機?

確切的來說不是遠的計算機&#xff0c;高考那會計算機很熱門&#xff0c;根本考不上&#xff01;學習了一個和計算機關系很密切的專業&#xff0c;編程搞得好&#xff0c;才能找到好工作&#xff0c;才能有飯吃&#xff01;記得當年我還跑去武漢大學的計算機課堂和人家一起聽課…

導入自定義模塊出現紅色波浪線,但是能正常執行

問題描述&#xff1a; 導入自己定義的模塊時&#xff0c;出現紅色波浪線&#xff0c;可以繼續執行 解決&#xff1a; 在存放當前執行文件的文件夾右鍵&#xff0c;然后將其設置為sources root即可 結果&#xff1a;

基于深度學習yolov5實現安全帽人體識別工地安全識別系統-反光衣識別系統

歡迎大家點贊、收藏、關注、評論啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代碼。 文章目錄 一項目簡介 二、功能三、系統四. 總結 一項目簡介 實現安全帽人體識別工地安全識別系統需要使用深度學習技術&#xff0c;特別是YOLOv5算法。下面是對基于YOLOv5實現安…

帶你真正理解web地圖切片規則

很多時候我們即使做完了項目還是對切片規則一知半解&#xff0c;只知道照著例子寫代碼&#xff0c;不理解WMTSCapabilities文件中參數的具體含義&#xff0c;也無法理解切片規則是如何產生的&#xff0c;不知道經緯度切圖和平面切圖的差別是啥&#xff0c;等等種種疑問&#xf…

Leetcode 39 組合總和

題意理解&#xff1a; 一個 無重復元素 的整數數組 candidates 和一個目標整數 target 從candidates 取數字&#xff0c;使其和 target &#xff0c;有多少種組合&#xff08;candidates 中的 同一個 數字可以 無限制重復被選取&#xff09; 這道題和之前一道組合的區別&am…

Vue學習筆記-Vue3中setup函數注意點

setup編寫示例 <script> import {reactive} from vue export default {name: "DemoVue",props:[xxx,yy,...],setup(props,context){const data reactive({......})//setup必須有返回值return {data,}} } </script>setup執行的時機 在beforeCreate()之…

【51單片機系列】74HC595實現對LED點陣的控制

本文是關于LED點陣的使用&#xff0c;使用74HC595模塊實現對LED點陣的控制。 文章目錄 一、8x8LED點陣的原理1.1 LED點陣顯示原理1.2 LED點陣內部結構圖1.3 開發板上的LED點陣原理圖1.4 74HC595芯片 二、使用74HC595模塊實現流水燈效果三、 使用74HC595模塊控制LED點陣對角線亮…

python基于DeeplabV3Plus開發構建手機屏幕表面缺陷圖像分割識別系統

Deeplab是圖像分割領域非常強大的模型&#xff0c;在前面的博文中我們也進行過很多相應項目的開發實踐&#xff0c;感興趣的話可以自行移步閱讀即可&#xff1a; 《基于DeepLabv3Plus開發構建人臉人像分割系統》 《基于DeepLabV3實踐路面、橋梁、基建裂縫裂痕分割》 《基于D…

【鏈表Linked List】力扣-203 移除鏈表元素

目錄 題目描述 解題過程 題目描述 給你一個鏈表的頭節點 head 和一個整數 val &#xff0c;請你刪除鏈表中所有滿足 Node.val val 的節點&#xff0c;并返回 新的頭節點 。 示例 1&#xff1a; 輸入&#xff1a;head [1,2,6,3,4,5,6], val 6 輸出&#xff1a;[1,2,3,4,5…

快速學會繪制Pyqt5中的所有圖(下)

Pyqt5相關文章: 快速掌握Pyqt5的三種主窗口 快速掌握Pyqt5的2種彈簧 快速掌握Pyqt5的5種布局 快速弄懂Pyqt5的5種項目視圖&#xff08;Item View&#xff09; 快速弄懂Pyqt5的4種項目部件&#xff08;Item Widget&#xff09; 快速掌握Pyqt5的6種按鈕 快速掌握Pyqt5的10種容器&…

鴻蒙原生應用開發——分布式數據對象

01、什么是分布式數據對象 在可信組網環境下&#xff0c;多個相互組網認證的設備將各自創建的對象加入同一個 sessionId&#xff0c;使得加入的多個數據對象之間可以同步數據&#xff0c;也就是說&#xff0c;當某一數據對象屬性發生變更時&#xff0c;其他數據對象會檢測到這…

讓聰明的車連接智慧的路,C-V2X開啟智慧出行生活

“聰明的車 智慧的路”形容的便是車路協同的智慧交通系統&#xff0c;從具備無鑰匙啟動&#xff0c;智能輔助駕駛和豐富娛樂影音功能的智能網聯汽車&#xff0c;到園區的無人快遞配送車&#xff0c;和開放的城市道路上自動駕駛的公交車、出租車&#xff0c;越來越多的車聯網應用…

thinkphp lists todo

來由&#xff1a; 數據庫的這個字段我想返回成&#xff1a; 新奇的寫法如下&#xff1a; 邏輯層的代碼&#xff1a; public function goodsDetail($goodId){$detail $this->good->where(id, $goodId)->hidden([type_params,user_id])->find();if (!$detail) {ret…

springboot(ssm出租車管理網站 出租車公司管理系統Java系統

springboot(ssm出租車管理網站 出租車公司管理系統Java系統 開發語言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服務器&#xff1a;tomcat 數據庫&#xff1a;mysql 5.7&#xff08;或8.0&#xff09;…

如何使用PostMan進行并發測試?

如何使用PostMan進行并發測試&#xff1f; &#x1f440;(Postman 的 runner 實際上是串行執行的&#xff0c;因此不能作為并發測試&#xff0c; 只是批量測試&#xff0c;本文如下稱為并發的是錯誤的) 文章目錄 如何使用PostMan進行并發測試&#xff1f;POST篇流程Pre-req 腳…

Conda常用命令總結

使用conda或anaconda的小伙伴們都知道&#xff0c;圖形界面時不靠譜的&#xff0c;而在命令行下&#xff0c;所有的操作就會穩定很多&#xff0c;且極少出現問題。因此&#xff0c;熟記conda的命令行就變得十分有用。但對于我這樣近50歲依舊奮斗在代碼第一線的大齡程序員而已&a…