基于SARIMA、XGBoost和CNN-LSTM的時(shí)間序列預(yù)測(cè)對(duì)比(2)
下面我們開始使用三種不同的時(shí)間序列算法:SARIMA、XGBoost和CNN-LSTM,進(jìn)行建模并比較。
對(duì)于所有三個(gè)模型,都使用預(yù)測(cè)下一個(gè)數(shù)據(jù)點(diǎn)進(jìn)行預(yù)測(cè)。Walk-forward驗(yàn)證是一種用于時(shí)間序列建模的技術(shù),因?yàn)殡S著時(shí)間的推移,預(yù)測(cè)會(huì)變得不那么準(zhǔn)確,因此更實(shí)用的方法是在實(shí)際數(shù)據(jù)可用時(shí),用實(shí)際數(shù)據(jù)重新訓(xùn)練模型。
在建模之前需要更詳細(xì)地研究數(shù)據(jù)。圖8顯示了SP2數(shù)據(jù)集中所有特征的相關(guān)熱圖。熱圖顯示了因變量直流功率,與模塊溫度、輻照和環(huán)境溫度的強(qiáng)相關(guān)性。這些特征可能在預(yù)測(cè)中發(fā)揮重要作用。
在下面的熱圖中,交流功率顯示皮爾森相關(guān)系數(shù)為1。為了防止數(shù)據(jù)泄漏問(wèn)題,我們將直流功率從數(shù)據(jù)中刪除。
SARIMA
季節(jié)自回歸綜合移動(dòng)平均(SARIMA)是一種單變量時(shí)間序列預(yù)測(cè)方法。由于目標(biāo)變量顯示出24小時(shí)循環(huán)周期的跡象,SARIMA是一個(gè)有效的建模選項(xiàng),因?yàn)樗紤]了季節(jié)影響。這可以從下面的季節(jié)分解圖中觀察到。
SARIMA算法要求數(shù)據(jù)是平穩(wěn)的。有多種方法來(lái)檢驗(yàn)數(shù)據(jù)是否平穩(wěn),例如統(tǒng)計(jì)檢驗(yàn)(增強(qiáng)迪基-福勒檢驗(yàn)),匯總統(tǒng)計(jì)(比較數(shù)據(jù)的不同部分的均值/方差)和可視化分析數(shù)據(jù)。在建模之前進(jìn)行多次測(cè)試是很重要的。
增強(qiáng)迪基-富勒(ADF)檢驗(yàn)是一種“單位根檢驗(yàn)”,用于確定時(shí)間序列是否平穩(wěn)。從根本上說(shuō),這是一個(gè)統(tǒng)計(jì)顯著性檢驗(yàn),其中存在一個(gè)零假設(shè)和替代假設(shè),并根據(jù)得出的p值得出結(jié)論。
零假設(shè):時(shí)間序列數(shù)據(jù)是非平穩(wěn)的。
替代假設(shè):時(shí)間序列數(shù)據(jù)是平穩(wěn)的。
在我們的例子中,如果p值≤0.05,我們可以拒絕原假設(shè),并確認(rèn)數(shù)據(jù)沒(méi)有單位根。
from statsmodels.tsa.stattools import adfuller
result = adfuller(plant2_dcpower.values)
print('ADF Statistic: %f' % result[0]) print('p-value: %f' % result[1]) print('Critical Values:') for key, value in result[4].items(): print('\t%s: %.3f' % (key, value))
從ADF檢驗(yàn)來(lái)看,p值為0.000553,< 0.05。根據(jù)這一統(tǒng)計(jì)數(shù)據(jù),可以認(rèn)為該數(shù)據(jù)是穩(wěn)定的。然而,查看圖2(最上面的圖),有明顯的季節(jié)性跡象(對(duì)于被認(rèn)為是平穩(wěn)的時(shí)間序列數(shù)據(jù),不應(yīng)該有季節(jié)性和趨勢(shì)的跡象),這說(shuō)明數(shù)據(jù)是非平穩(wěn)的。因此,運(yùn)行多個(gè)測(cè)試非常重要。
為了用SARIMA對(duì)因變量建模,時(shí)間序列需要是平穩(wěn)的。如圖9(第一個(gè)和第三個(gè)圖)所示,直流電有明顯的季節(jié)性跡象。取第一個(gè)差值[t-(t-1)]去除季節(jié)性成分,如圖10所示,因?yàn)樗雌饋?lái)類似于正態(tài)分布。數(shù)據(jù)現(xiàn)在是平穩(wěn)的,適用于SARIMA算法。
SARIMA的超參數(shù)包括p(自回歸階數(shù))、d(差階數(shù))、q(移動(dòng)平均階數(shù))、p(季節(jié)自回歸階數(shù))、d(季節(jié)差階數(shù))、q(季節(jié)移動(dòng)平均階數(shù))、m(季節(jié)周期的時(shí)間步長(zhǎng))、trend(確定性趨勢(shì))。
圖11顯示了自相關(guān)(ACF)、部分自相關(guān)(PACF)和季節(jié)性ACF/PACF圖。ACF圖顯示了時(shí)間序列與其延遲版本之間的相關(guān)性。PACF顯示了時(shí)間序列與其滯后版本之間的直接相關(guān)性。藍(lán)色陰影區(qū)域表示置信區(qū)間。SACF和SPACF可以通過(guò)從原始數(shù)據(jù)中取季節(jié)差(m)來(lái)計(jì)算,在本例中為24,因?yàn)樵贏CF圖中有一個(gè)明顯的24小時(shí)的季節(jié)效應(yīng)。
根據(jù)我們的直覺(jué),超參數(shù)的起點(diǎn)可以從ACF和PACF圖中推導(dǎo)出來(lái)。如ACF和PACF均呈逐漸下降的趨勢(shì),即自回歸階數(shù)(p)和移動(dòng)平均階數(shù)(q)均大于0。p和p可以通過(guò)分別觀察PCF和SPCF圖,并計(jì)算滯后值不顯著之前具有統(tǒng)計(jì)學(xué)顯著性的滯后數(shù)來(lái)確定。同樣,q和q可以在ACF和SACF圖中找到。
差階(d)可以通過(guò)使數(shù)據(jù)平穩(wěn)的差的數(shù)量來(lái)確定。季節(jié)差異階數(shù)(D)是根據(jù)從時(shí)間序列中去除季節(jié)性成分所需的差異數(shù)來(lái)估計(jì)的。
這些超參數(shù)選擇可以看這篇文章:https://arauto.readthedocs.io/en/latest/how_to_choose_terms.html
也可以采用網(wǎng)格搜索方法進(jìn)行超參數(shù)優(yōu)化,根據(jù)最小均方誤差(MSE)選擇最優(yōu)超參數(shù),包括p = 2, d = 0, q = 4, p = 2, d = 1, q = 6, m = 24, trend = ' n '(無(wú)趨勢(shì))。
from time import time from sklearn.metrics import mean_squared_error from statsmodels.tsa.statespace.sarimax import SARIMAX
configg = [(2, 1, 4), (2, 1, 6, 24), 'n']
def train_test_split(data, test_len=48): """ Split data into training and testing. """ train, test = data[:-test_len], data[-test_len:] return train, test
def sarima_model(data, cfg, test_len, i): """ SARIMA model which outputs prediction and model. """ order, s_order, t = cfg[0], cfg[1], cfg[2] model = SARIMAX(data, order=order, seasonal_order=s_order, trend=t, enforce_stationarity=False, enfore_invertibility=False) model_fit = model.fit(disp=False) yhat = model_fit.predict(len(data))
if i + 1 == test_len: return yhat, model_fit else: return yhat
def walk_forward_val(data, cfg): """ A walk forward validation technique used for time series data. Takes current value of x_test and predicts value. x_test is then fed back into history for the next prediction. """ train, test = train_test_split(data) pred = [] history = [i for i in train] test_len = len(test)
for i in range(test_len): if i + 1 == test_len: yhat, s_model = sarima_model(history, cfg, test_len, i) pred.append(yhat) mse = mean_squared_error(test, pred) return pred, mse, s_model else: yhat = sarima_model(history, cfg, test_len, i) pred.append(yhat) history.append(test[i]) pass
if __name__ == '__main__': start_time = time() sarima_pred_plant2, sarima_mse, s_model = walk_forward_val(plant2_dcpower, configg) time_len = time() - start_time
print(f'SARIMA runtime: {round(time_len/60,2)} mins')
圖12顯示了SARIMA模型的預(yù)測(cè)值與SP2 2天內(nèi)記錄的直流功率的比較。
為了分析模型的性能,圖13顯示了模型診斷。相關(guān)圖顯示在第一個(gè)滯后后幾乎沒(méi)有相關(guān)性,下面的直方圖顯示在平均值為零附近的正態(tài)分布。由此我們可以說(shuō)模型無(wú)法從數(shù)據(jù)中收集到進(jìn)一步的信息。
*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。