還是先來吐槽
時間序列模型arima 用python 實現(xiàn)的話是用statsmodels.tsa.arima_model 來做,樣本內(nèi)的擬合和預(yù)測都沒什么問題。但是樣本外的預(yù)測沒想到 竟然成了很大的問題。
問題
- 無論是forecast 還是predict 在預(yù)測的時候都只能做到一步預(yù)測砚哆,如果進行多步預(yù)測擅羞,其實在后面幾步用的是擬合值而不是真實值,所以對于想要使用滑窗一步預(yù)測就很難受忿等。
- 為什么這個接口對于這么簡單的功能卻這么蹩腳,主要是因為在arima model 進行預(yù)測的時候是必須依賴該數(shù)據(jù)之前的數(shù)的殘差崔挖。
解決問題
所以就第一個直觀的想法就是
能不能取出之前模型估計的參數(shù)贸街,然后根據(jù)喂進去新的數(shù)據(jù),再進行計算
查了很多資料狸相,終于在這個的基礎(chǔ)上使用_arma_predict_out_of_sample這個內(nèi)置函數(shù)薛匪,進行了改進,才得以搞定脓鹃。不過一定要注意的是逸尖,這個只能進行樣本外的一步預(yù)測。
實踐部分
生成數(shù)據(jù)
import pandas as pd
import numpy as np
from statsmodels.tsa.arima_model import ARMA #模型
from statsmodels.tsa.arima_model import _arma_predict_out_of_sample
## 生成隨機數(shù)
data=np.random.rand(200)
df= pd.DataFrame({'data':data})
分割train_dataset 和test_dataset
length = len(df)
train_data = df.iloc[0:int(length/8)*7,:]
test_data = df.iloc[int(length/8)*7:,:]
生成模型
result = ARMA(train_data['data'],order=(2,1)).fit()
pred = result.predict()
最關(guān)鍵的部分 瘸右,提取參數(shù)
params = result.params
residuals = result.resid
p = result.k_ar
q = result.k_ma
k_exog = result.k_exog
k_trend = result.k_trend
steps = 1
樣本內(nèi)數(shù)據(jù)驗證
## 樣本內(nèi)測試
in_data = train_data.iloc[0:11,:]
in_resid = residuals.iloc[0:11]
a = _arma_predict_out_of_sample(params, steps, in_resid, \
p, q, k_trend, k_exog,\
endog = in_data['data'], exog=None, start=len(in_data))
test_pred=pred[8:13]
test_pred
a[0]## 會發(fā)現(xiàn)沒什么誤差
樣本外預(yù)測,滑窗式操作
new_resid = residuals.tail(3).copy()
new_data = train_data.tail(3).copy()
for i in range(len(test_data)):
print(i)
## temp_data 應(yīng)該增加最后一行娇跟,減去第一行
a = _arma_predict_out_of_sample(params, steps, new_resid, \
p, q, k_trend, k_exog,\
endog = new_data['data'], exog=None, start=len(new_data))
tomorrow_index = test_data.index[i]
temp_resid = test_data.loc[tomorrow_index,'data'] - a[0]
new_resid[tomorrow_index] = temp_resid
new_resid.drop(new_resid.index[0],inplace=True)
new_data = new_data.append(test_data.iloc[i,:])
new_data.drop(new_data.index[0],inplace=True)
pred[tomorrow_index] = a[0]
_arma_predict_out_of_sample具體參數(shù)解讀
- start 參數(shù)
未完待續(xù)......