SARIMAXのexog(外生変数)の入力方法
概要
- SARIMAXで電力量を予測する。
- SARIMAXに外生変数を入力する。
- エネルギーデータと外気温度でどの程度変化するか確認する。
注意
exog
のデータ数は、fit時はendog
と同じ数だけ入力、forecast時は、steps数と同じ数だけ入力する。
実装
import numpy as np
import pandas as pd
import statsmodels.api as sm
import matplotlib as plt
plt.rcParams['font.family'] = 'IPAexGothic'
df = pd.read_csv(r'C:\Users\***\OneDrive\ドキュメント\Study\Qiita\SampleData.csv',
engine='python',
index_col=[0],
parse_dates=[0],
)
df.index.freq = 'H'
# 予測日を2017年8月3日として、過去3日間のデータをSARIMAXのendogとしました。
# endog,exogは共に3日分のデータです。(exogが外生変数(外気温))
# order,seasonal_orderはコレログラムとか使って推定するのですが、面倒だったのでaicが一番低いものを入れました。
forecastdate = pd.datetime(2017,8,3,0,0)
train_df = df.loc[forecastdate -pd.offsets.Day(3) :forecastdate - pd.offsets.Hour(1),:]
temp_df = pd.DataFrame(df.loc[forecastdate:forecastdate + pd.offsets.Hour(23),'外気温度'])
ele_df = df.loc[forecastdate:forecastdate + pd.offsets.Hour(23),'高圧受電']
fit_with_temp = sm.tsa.statespace.SARIMAX( endog=train_df.loc[:,'高圧受電'],
exog=train_df.loc[:,'外気温度'],
enforce_invertibility=False,
enforce_stationarity=False,
order=(1,0,1),
seasonal_order=(1,0,0,24)).fit()
fit = sm.tsa.statespace.SARIMAX(endog=train_df.loc[:,'高圧受電'],
enforce_invertibility=False,
enforce_stationarity=False,
order=(1,0,1),
seasonal_order=(1,0,0,24)).fit()
result_df = pd.DataFrame({'実績値':ele_df,
'予測値_外生変数有':fit_with_temp.forecast(steps=24,exog=temp_df),
'予測値_外生変数無':fit.forecast(steps=24)
}
)
result_df.plot(figsize=(15,5))
結果
- 外生変数入力の有無で、結果に差が出たか比較する。
import numpy as np
import pandas as pd
import statsmodels.api as sm
import matplotlib as plt
plt.rcParams['font.family'] = 'IPAexGothic'
df = pd.read_csv(r'C:\Users\***\OneDrive\ドキュメント\Study\Qiita\SampleData.csv',
engine='python',
index_col=[0],
parse_dates=[0],
)
df.index.freq = 'H'
# 予測日を2017年8月3日として、過去3日間のデータをSARIMAXのendogとしました。
# endog,exogは共に3日分のデータです。(exogが外生変数(外気温))
# order,seasonal_orderはコレログラムとか使って推定するのですが、面倒だったのでaicが一番低いものを入れました。
forecastdate = pd.datetime(2017,8,3,0,0)
train_df = df.loc[forecastdate -pd.offsets.Day(3) :forecastdate - pd.offsets.Hour(1),:]
temp_df = pd.DataFrame(df.loc[forecastdate:forecastdate + pd.offsets.Hour(23),'外気温度'])
ele_df = df.loc[forecastdate:forecastdate + pd.offsets.Hour(23),'高圧受電']
fit_with_temp = sm.tsa.statespace.SARIMAX( endog=train_df.loc[:,'高圧受電'],
exog=train_df.loc[:,'外気温度'],
enforce_invertibility=False,
enforce_stationarity=False,
order=(1,0,1),
seasonal_order=(1,0,0,24)).fit()
fit = sm.tsa.statespace.SARIMAX(endog=train_df.loc[:,'高圧受電'],
enforce_invertibility=False,
enforce_stationarity=False,
order=(1,0,1),
seasonal_order=(1,0,0,24)).fit()
result_df = pd.DataFrame({'実績値':ele_df,
'予測値_外生変数有':fit_with_temp.forecast(steps=24,exog=temp_df),
'予測値_外生変数無':fit.forecast(steps=24)
}
)
result_df.plot(figsize=(15,5))
- 外生変数入力の有無で、結果に差が出たか比較する。
項目 | 予測精度(RMSE) |
---|---|
外生変数有 | 3.817 |
外生変数無 | 5.457 |
逐次的に処理ができる環境であれば、より精度よく予想できそうであるが、1日1回ではなかなか難しいようである。
fit_with_temp.params
外気温度 1.398241
ar.L1 0.851124
ma.L1 0.108688
ar.S.L24 0.608674
sigma2 22.464773
dtype: float64
係数を確認すると、外気温度が上昇すれば、電力量が高くなるようである。
問題は、冬季ではこれが逆転してしまうこと・・・
まとめ
- 電力量に対して、外生変数(外気温度)を入力することで一定の効果がみられる。
- 予測するデータ分の外気温度の予報値が必要。
- 逐次的に処理すれば、予測精度の改善ができそう
Author And Source
この問題について(SARIMAXのexog(外生変数)の入力方法), 我々は、より多くの情報をここで見つけました https://qiita.com/snuow/items/2504a6b2dc6cbc735e5a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .