以下內容引自:https://blog.csdn.net/qifeidemumu/article/details/88782550
使用“網格搜索”來迭代地探索參數的不同組合。 對於參數的每個組合,我們使用statsmodels
模塊的SARIMAX()
函數擬合一個新的季節性ARIMA模型,並評估其整體質量。 一旦我們探索了參數的整個范圍,我們的最佳參數集將是我們感興趣的標准產生最佳性能的參數。 我們開始生成我們希望評估的各種參數組合:
-
# Define the p, d and q parameters to take any value between 0 and 2
-
p = d = q = range(0, 2)
-
-
# Generate all different combinations of p, q and q triplets
-
pdq = list(itertools.product(p, d, q))
-
-
# Generate all different combinations of seasonal p, q and q triplets
-
seasonal_pdq = [( x[0], x[1], x[2], 12) for x in list(itertools.product(p, d, q))]
-
-
print('Examples of parameter combinations for Seasonal ARIMA...')
-
print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[1]))
-
print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[2]))
-
print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[3]))
-
print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[4]))
-
Output
-
Examples of parameter combinations for Seasonal ARIMA...
-
SARIMAX: ( 0, 0, 1) x (0, 0, 1, 12)
-
SARIMAX: ( 0, 0, 1) x (0, 1, 0, 12)
-
SARIMAX: ( 0, 1, 0) x (0, 1, 1, 12)
-
SARIMAX: ( 0, 1, 0) x (1, 0, 0, 12)
我們現在可以使用上面定義的參數三元組來自動化不同組合對ARIMA模型進行培訓和評估的過程。 在統計和機器學習中,這個過程被稱為模型選擇的網格搜索(或超參數優化)。
在評估和比較配備不同參數的統計模型時,可以根據數據的適合性或准確預測未來數據點的能力,對每個參數進行排序。 我們將使用AIC
(Akaike信息標准)值,該值通過使用statsmodels
安裝的ARIMA型號方便地返回。 AIC
衡量模型如何適應數據,同時考慮到模型的整體復雜性。 在使用大量功能的情況下,適合數據的模型將被賦予比使用較少特征以獲得相同的適合度的模型更大的AIC得分。 因此,我們有興趣找到產生最低AIC
值的模型。
下面的代碼塊通過參數的組合來迭代,並使用SARIMAX
函數來適應相應的季節性ARIMA模型。 這里, order
參數指定(p, d, q)
參數,而seasonal_order
參數指定季節性ARIMA模型的(P, D, Q, S)
季節分量。 在安裝每個SARIMAX()
模型后,代碼打印出其各自的AIC
得分。
-
warnings.filterwarnings( "ignore")
-
-
for param in pdq:
-
for param_seasonal in seasonal_pdq:
-
try:
-
mod = sm.tsa.statespace.SARIMAX(y,
-
order=param,
-
seasonal_order=param_seasonal,
-
enforce_stationarity= False,
-
enforce_invertibility= False)
-
-
results = mod.fit()
-
-
print( 'ARIMA{}x{}12 - AIC:{}'.format(param, param_seasonal, results.aic))
-
except:
-
continue
由於某些參數組合可能導致數字錯誤指定,因此我們明確禁用警告消息,以避免警告消息過載。 這些錯誤指定也可能導致錯誤並引發異常,因此我們確保捕獲這些異常並忽略導致這些問題的參數組合。
上面的代碼應該產生以下結果,這可能需要一些時間:
-
Output
-
SARIMAX(0, 0, 0)x(0, 0, 1, 12) - AIC:6787.3436240402125
-
SARIMAX(0, 0, 0)x(0, 1, 1, 12) - AIC:1596.711172764114
-
SARIMAX(0, 0, 0)x(1, 0, 0, 12) - AIC:1058.9388921320026
-
SARIMAX(0, 0, 0)x(1, 0, 1, 12) - AIC:1056.2878315690562
-
SARIMAX(0, 0, 0)x(1, 1, 0, 12) - AIC:1361.6578978064144
-
SARIMAX(0, 0, 0)x(1, 1, 1, 12) - AIC:1044.7647912940095
-
...
-
...
-
...
-
SARIMAX(1, 1, 1)x(1, 0, 0, 12) - AIC:576.8647112294245
-
SARIMAX(1, 1, 1)x(1, 0, 1, 12) - AIC:327.9049123596742
-
SARIMAX(1, 1, 1)x(1, 1, 0, 12) - AIC:444.12436865161305
-
SARIMAX(1, 1, 1)x(1, 1, 1, 12) - AIC:277.7801413828764
我們的代碼的輸出表明, SARIMAX(1, 1, 1)x(1, 1, 1, 12)
產生最低的AIC
值為277.78。 因此,我們認為這是我們考慮過的所有模型中的最佳選擇。
第5步 - 安裝ARIMA時間序列模型
使用網格搜索,我們已經確定了為我們的時間序列數據生成最佳擬合模型的參數集。 我們可以更深入地分析這個特定的模型。
我們首先將最佳參數值插入到新的SARIMAX
模型中:
-
mod = sm.tsa.statespace.SARIMAX(y,
-
order=(1, 1, 1),
-
seasonal_order=( 1, 1, 1, 12),
-
enforce_stationarity= False,
-
enforce_invertibility= False)
-
-
results = mod.fit()
-
-
print(results.summary().tables[ 1])
-
Output
-
==============================================================================
-
coef std err z P>|z| [0.025 0.975]
-
------------------------------------------------------------------------------
-
ar.L1 0.3182 0.092 3.443 0.001 0.137 0.499
-
ma.L1 -0.6255 0.077 -8.165 0.000 -0.776 -0.475
-
ar.S.L12 0.0010 0.001 1.732 0.083 -0.000 0.002
-
ma.S.L12 -0.8769 0.026 -33.811 0.000 -0.928 -0.826
-
sigma2 0.0972 0.004 22.634 0.000 0.089 0.106
-
==============================================================================
由SARIMAX的輸出產生的SARIMAX
返回大量的信息,但是我們將注意力集中在系數表上。 coef
列顯示每個特征的重量(即重要性)以及每個特征如何影響時間序列。 P>|z|
列通知我們每個特征重量的意義。 這里,每個重量的p值都低於或接近0.05
,所以在我們的模型中保留所有權重是合理的。
在 fit 季節性ARIMA模型(以及任何其他模型)的情況下,運行模型診斷是非常重要的,以確保沒有違反模型的假設。 plot_diagnostics
對象允許我們快速生成模型診斷並調查任何異常行為。
-
results.plot_diagnostics(figsize=(15, 12))
-
plt.show()
我們的主要關切是確保我們的模型的殘差是不相關的,並且平均分布為零。 如果季節性ARIMA模型不能滿足這些特性,這是一個很好的跡象,可以進一步改善。
殘差在數理統計中是指實際觀察值與估計值(擬合值)之間的差。“殘差”蘊含了有關模型基本假設的重要信息。如果回歸模型正確的話, 我們可以將殘差看作誤差的觀測值。 它應符合模型的假設條件,且具有誤差的一些性質。利用殘差所提供的信息,來考察模型假設的合理性及數據的可靠性稱為殘差分析
在這種情況下,我們的模型診斷表明,模型殘差正常分布如下:
-
在右上圖中,我們看到紅色
KDE
線與N(0,1)
行(其中N(0,1)
)是正態分布的標准符號,平均值0
,標准偏差為1
) 。 這是殘留物正常分布的良好指示。 -
左下角的qq圖顯示,殘差(藍點)的有序分布遵循采用
N(0, 1)
的標准正態分布采樣的線性趨勢。 同樣,這是殘留物正常分布的強烈指示。 -
隨着時間的推移(左上圖)的殘差不會顯示任何明顯的季節性,似乎是白噪聲。 這通過右下角的自相關(即相關圖)來證實,這表明時間序列殘差與其本身的滯后值具有低相關性。
這些觀察結果使我們得出結論,我們的模型選擇了令人滿意,可以幫助我們了解我們的時間序列數據和預測未來價值。
雖然我們有一個令人滿意的結果,我們的季節性ARIMA模型的一些參數可以改變,以改善我們的模型擬合。 例如,我們的網格搜索只考慮了一組受限制的參數組合,所以如果我們拓寬網格搜索,我們可能會找到更好的模型。
第6步 - 驗證預測
我們已經獲得了我們時間序列的模型,現在可以用來產生預測。 我們首先將預測值與時間序列的實際值進行比較,這將有助於我們了解我們的預測的准確性。 get_prediction()
和conf_int()
屬性允許我們獲得時間序列預測的值和相關的置信區間。
-
pred = results.get_prediction(start=pd.to_datetime( '1998-01-01'), dynamic=False)#預測值
-
pred_ci = pred.conf_int() #置信區間
上述規定需要從1998年1月開始進行預測。
dynamic=False
參數確保我們每個點的預測將使用之前的所有歷史觀測。
我們可以繪制二氧化碳時間序列的實際值和預測值,以評估我們做得如何。 注意我們如何在時間序列的末尾放大日期索引。
-
ax = y[ '1990':].plot(label='observed')
-
pred.predicted_mean.plot(ax=ax, label='One-step ahead Forecast', alpha=.7)
-
-
ax.fill_between(pred_ci. index,
-
pred_ci.iloc[:, 0],
-
pred_ci.iloc[:, 1], color='k', alpha=.2)
-
#圖形填充fill fill_between,參考網址:
-
#https: //www.cnblogs.com/gengyi/p/9416845.html
-
-
ax.set_xlabel( 'Date')
-
ax.set_ylabel( 'CO2 Levels')
-
plt.legend()
-
-
plt.show()
pred.predicted_mean 可以得到預測均值,就是置信區間的上下加和除以2
函數間區域填充 fill_between用法:
plt.fill_between( x, y1, y2=0, where=None, interpolate=False, step=None, hold=None,data=None, **kwarg)
x - array( length N) 定義曲線的 x 坐標
y1 - array( length N ) or scalar 定義第一條曲線的 y 坐標
y2 - array( length N ) or scalar 定義第二條曲線的 y 坐標
where - array of bool (length N), optional, default: None 排除一些(垂直)區域被填充。注:我理解的垂直區域,但幫助文檔上寫的是horizontal regions
也可簡單地描述為:
plt.fill_between(x,y1,y2,where=條件表達式, color=顏色,alpha=透明度)" where = " 可以省略,直接寫條件表達式
總體而言,我們的預測與真實價值保持一致,呈現總體增長趨勢。
量化預測的准確性
這是很有必要的。 我們將使用MSE(均方誤差,也就是方差),它總結了我們的預測的平均誤差。 對於每個預測值,我們計算其到真實值的距離並對結果求平方。 結果需要平方,以便當我們計算總體平均值時,正/負差異不會相互抵消。
-
y_forecasted = pred.predicted_mean
-
y_truth = y[ '1998-01-01':]
-
-
# Compute the mean square error
-
mse = ((y_forecasted - y_truth) ** 2).mean()
-
print( 'The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
-
Output
-
The Mean Squared Error of our forecasts is 0.07
我們前進一步預測的MSE值為0.07
,這是接近0的非常低的值。MSE=0是預測情況將是完美的精度預測參數的觀測值,但是在理想的場景下通常不可能。
然而,使用動態預測(dynamic=True)可以獲得更好地表達我們的真實預測能力。 在這種情況下,我們只使用時間序列中的信息到某一點,之后,使用先前預測時間點的值生成預測。
在下面的代碼塊中,我們指定從1998年1月起開始計算動態預測和置信區間。
-
pred_dynamic = results.get_prediction( start=pd.to_datetime('1998-01-01'), dynamic=True, full_results=True)
-
pred_dynamic_ci = pred_dynamic.conf_int()
繪制時間序列的觀測值和預測值,我們看到即使使用動態預測,總體預測也是准確的。 所有預測值(紅線)與地面真相(藍線)相當吻合,並且在我們預測的置信區間內。
-
ax = y[ '1990':].plot(label='observed', figsize=(20, 15))
-
pred_dynamic.predicted_mean.plot( label='Dynamic Forecast', ax=ax)
-
-
ax.fill_between(pred_dynamic_ci. index,
-
pred_dynamic_ci.iloc[:, 0],
-
pred_dynamic_ci.iloc[:, 1], color='k', alpha=.25)
-
-
ax.fill_betweenx(ax.get_ylim(), pd.to_datetime( '1998-01-01'), y.index[-1],
-
alpha=. 1, zorder=-1)
-
-
ax.set_xlabel( 'Date')
-
ax.set_ylabel( 'CO2 Levels')
-
-
plt.legend()
-
plt.show()
我們再次通過計算MSE量化我們預測的預測性能:
-
# Extract the predicted and true values of our time-series
-
y_forecasted = pred_dynamic.predicted_mean
-
y_truth = y[ '1998-01-01':]
-
-
# Compute the mean square error
-
mse = ((y_forecasted - y_truth) ** 2).mean()
-
print( 'The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
OutputThe Mean Squared Error of our forecasts is 1.01
從動態預測獲得的預測值產生1.01的MSE。 這比前進一步略高,這是意料之中的,因為我們依賴於時間序列中較少的歷史數據。
前進一步和動態預測都證實了這個時間序列模型是有效的。 然而,關於時間序列預測的大部分興趣是能夠及時預測未來價值觀。
第7步 - 生成和可視化預測
在本教程的最后一步,我們將介紹如何利用季節性ARIMA時間序列模型來預測未來的價值。 我們的時間序列對象的
get_forecast()
屬性可以計算預先指定數量的步驟的預測值。
-
# Get forecast 500 steps ahead in future
-
pred_uc = results.get_forecast(steps= 500)
-
-
# Get confidence intervals of forecasts
-
pred_ci = pred_uc.conf_int()
我們可以使用此代碼的輸出繪制其未來值的時間序列和預測。
-
ax = y.plot( label='observed', figsize=(20, 15))
-
pred_uc.predicted_mean.plot(ax=ax, label='Forecast')
-
ax.fill_between(pred_ci. index,
-
pred_ci.iloc[:, 0],
-
pred_ci.iloc[:, 1], color='k', alpha=.25)
-
ax.set_xlabel( 'Date')
-
ax.set_ylabel( 'CO2 Levels')
-
-
plt.legend()
-
plt.show()
現在可以使用我們生成的預測和相關的置信區間來進一步了解時間序列並預見預期。 我們的預測顯示,時間序列預計將繼續穩步增長。
隨着我們對未來的進一步預測,我們對自己的價值觀信心愈來愈自然。 這反映在我們的模型產生的置信區間,隨着我們進一步走向未來,這個模型越來越大。
結論
在本教程中,我們描述了如何在Python中實現季節性ARIMA模型。 我們廣泛使用了pandas
和statsmodels
圖書館,並展示了如何運行模型診斷,以及如何產生二氧化碳時間序列的預測。
這里還有一些其他可以嘗試的事情:
- 更改動態預測的開始日期,以了解其如何影響預測的整體質量。
- 嘗試更多的參數組合,看看是否可以提高模型的適合度。
- 選擇不同的指標以選擇最佳模型。 例如,我們使用
AIC
測量來找到最佳模型,但是您可以尋求優化采樣均方誤差
補充:其中一些好用的方法,代碼如下:
-
filename_ts = 'data/series1.csv'
-
ts_df = pd.read_csv(filename_ts, index_col= 0, parse_dates=[0])
-
-
n_sample = ts_df.shape[ 0]
-
print(ts_df.shape)
-
print(ts_df.head())
-
# Create a training sample and testing sample before analyzing the series
-
-
n_train= int(0.95*n_sample)+1
-
n_forecast=n_sample-n_train
-
#ts_df
-
ts_train = ts_df.iloc[:n_train][ 'value']
-
ts_test = ts_df.iloc[n_train:][ 'value']
-
print(ts_train.shape)
-
print(ts_test.shape)
-
print("Training Series:", "\n", ts_train.tail(), "\n")
-
print("Testing Series:", "\n", ts_test.head())
-
def tsplot(y, lags=None, title='', figsize=(14, 8)):
-
-
fig = plt.figure(figsize=figsize)
-
layout = ( 2, 2)
-
ts_ax = plt.subplot2grid(layout, ( 0, 0))
-
hist_ax = plt.subplot2grid(layout, ( 0, 1))
-
acf_ax = plt.subplot2grid(layout, ( 1, 0))
-
pacf_ax = plt.subplot2grid(layout, ( 1, 1))
-
-
y.plot(ax=ts_ax) # 折線圖
-
ts_ax.set_title(title)
-
y.plot(ax=hist_ax, kind= 'hist', bins=25) #直方圖
-
hist_ax.set_title( 'Histogram')
-
smt.graphics.plot_acf(y, lags=lags, ax=acf_ax) # ACF自相關系數
-
smt.graphics.plot_pacf(y, lags=lags, ax=pacf_ax) # 偏自相關系數
-
[ax.set_xlim( 0) for ax in [acf_ax, pacf_ax]]
-
sns.despine()
-
fig.tight_layout()
-
return ts_ax, acf_ax, pacf_ax
-
-
tsplot(ts_train, title= 'A Given Training Series', lags=20);
-
# 此處運用BIC(貝葉斯信息准則)進行模型參數選擇
-
# 另外還可以利用AIC(赤池信息准則),視具體情況而定
-
import itertools
-
-
p_min = 0
-
d_min = 0
-
q_min = 0
-
p_max = 4
-
d_max = 0
-
q_max = 4
-
-
# Initialize a DataFrame to store the results
-
results_bic = pd.DataFrame(index=[ 'AR{}'.format(i) for i in range(p_min,p_max+1)],
-
columns=[ 'MA{}'.format(i) for i in range(q_min,q_max+1)])
-
-
for p,d,q in itertools.product(range(p_min,p_max+1),
-
range(d_min,d_max+ 1),
-
range(q_min,q_max+ 1)):
-
if p==0 and d==0 and q==0:
-
results_bic.loc[ 'AR{}'.format(p), 'MA{}'.format(q)] = np.nan
-
continue
-
-
try:
-
model = sm.tsa.SARIMAX(ts_train, order=(p, d, q),
-
#enforce_stationarity=False,
-
#enforce_invertibility=False,
-
)
-
results = model.fit() ##下面可以顯示具體的參數結果表
-
## print(model_results.summary())
-
## print(model_results.summary().tables[1])
-
# http://www.statsmodels.org/stable/tsa.html
-
# print("results.bic",results.bic)
-
# print("results.aic",results.aic)
-
-
results_bic.loc[ 'AR{}'.format(p), 'MA{}'.format(q)] = results.bic
-
except:
-
continue
-
results_bic = results_bic[results_bic.columns].astype(float)
results_bic如下所示:
為了便於觀察,下面對上表進行可視化:、
-
fig, ax = plt.subplots(figsize=( 10, 8))
-
ax = sns.heatmap(results_bic,
-
mask=results_bic.isnull(),
-
ax=ax,
-
annot=True,
-
fmt= '.2f',
-
);
-
ax.set_title( 'BIC');
-
//annot
-
//annotate的縮寫,annot默認為False,當annot為True時,在heatmap中每個方格寫入數據
-
//annot_kws,當annot為True時,可設置各個參數,包括大小,顏色,加粗,斜體字等
-
# annot_kws={ 'size':9,'weight':'bold', 'color':'blue'}
-
#具體查看:https: //blog.csdn.net/m0_38103546/article/details/79935671
-
# Alternative model selection method, limited to only searching AR and MA parameters
-
-
train_results = sm.tsa.arma_order_select_ic(ts_train, ic=[ 'aic', 'bic'], trend='nc', max_ar=4, max_ma=4)
-
-
print( 'AIC', train_results.aic_min_order)
-
print( 'BIC', train_results.bic_min_order)
注:
SARIMA總代碼如下:
-
-
"""
-
https://www.howtoing.com/a-guide-to-time-series-forecasting-with-arima-in-python-3/
-
http://www.statsmodels.org/stable/datasets/index.html
-
"""
-
-
import warnings
-
import itertools
-
import pandas as pd
-
import numpy as np
-
import statsmodels.api as sm
-
import matplotlib.pyplot as plt
-
plt.style.use( 'fivethirtyeight')
-
-
'''
-
1-Load Data
-
Most sm.datasets hold convenient representations of the data in the attributes endog and exog.
-
If the dataset does not have a clear interpretation of what should be an endog and exog,
-
then you can always access the data or raw_data attributes.
-
https://docs.scipy.org/doc/numpy/reference/generated/numpy.recarray.html
-
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.resample.html
-
# resample('MS') groups the data in buckets by start of the month,
-
# after that we got only one value for each month that is the mean of the month
-
# fillna() fills NA/NaN values with specified method
-
# 'bfill' method use Next valid observation to fill gap
-
# If the value for June is NaN while that for July is not, we adopt the same value
-
# as in July for that in June
-
'''
-
-
data = sm.datasets.co2.load_pandas()
-
y = data.data # DataFrame with attributes y.columns & y.index (DatetimeIndex)
-
print(y)
-
names = data.names # tuple
-
raw = data.raw_data # float64 np.recarray
-
-
y = y[ 'co2'].resample('MS').mean()
-
print(y)
-
-
y = y.fillna(y.bfill()) # y = y.fillna(method='bfill')
-
print(y)
-
-
y.plot(figsize=( 15,6))
-
plt.show()
-
-
'''
-
2-ARIMA Parameter Seletion
-
ARIMA(p,d,q)(P,D,Q)s
-
non-seasonal parameters: p,d,q
-
seasonal parameters: P,D,Q
-
s: period of time series, s=12 for annual period
-
Grid Search to find the best combination of parameters
-
Use AIC value to judge models, choose the parameter combination whose
-
AIC value is the smallest
-
https://docs.python.org/3/library/itertools.html
-
http://www.statsmodels.org/stable/generated/statsmodels.tsa.statespace.sarimax.SARIMAX.html
-
'''
-
-
# Define the p, d and q parameters to take any value between 0 and 2
-
p = d = q = range( 0, 2)
-
-
# Generate all different combinations of p, q and q triplets
-
pdq = list(itertools.product(p, d, q))
-
-
# Generate all different combinations of seasonal p, q and q triplets
-
seasonal_pdq = [(x[ 0], x[1], x[2], 12) for x in pdq]
-
-
print( 'Examples of parameter combinations for Seasonal ARIMA...')
-
print( 'SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[1]))
-
print( 'SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[2]))
-
print( 'SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[3]))
-
print( 'SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[4]))
-
-
warnings.filterwarnings( "ignore") # specify to ignore warning messages
-
-
for param in pdq:
-
for param_seasonal in seasonal_pdq:
-
try:
-
mod = sm.tsa.statespace.SARIMAX(y,
-
order=param,
-
seasonal_order=param_seasonal,
-
enforce_stationarity= False,
-
enforce_invertibility= False)
-
-
results = mod.fit()
-
-
print( 'ARIMA{}x{}12 - AIC:{}'.format(param, param_seasonal, results.aic))
-
except:
-
continue
-
-
-
'''
-
3-Optimal Model Analysis
-
Use the best parameter combination to construct ARIMA model
-
Here we use ARIMA(1,1,1)(1,1,1)12
-
the output coef represents the importance of each feature
-
mod.fit() returnType: MLEResults
-
http://www.statsmodels.org/stable/generated/statsmodels.tsa.statespace.mlemodel.MLEResults.html#statsmodels.tsa.statespace.mlemodel.MLEResults
-
Use plot_diagnostics() to check if parameters are against the model hypothesis
-
model residuals must not be correlated
-
'''
-
-
mod = sm.tsa.statespace.SARIMAX(y,
-
order=( 1, 1, 1),
-
seasonal_order=( 1, 1, 1, 12),
-
enforce_stationarity= False,
-
enforce_invertibility= False)
-
-
results = mod.fit()
-
print(results.summary().tables[ 1])
-
-
results.plot_diagnostics(figsize=( 15, 12))
-
plt.show()
-
-
'''
-
4-Make Predictions
-
get_prediction(..., dynamic=False)
-
Prediction of each point will use all historic observations prior to it
-
http://www.statsmodels.org/stable/generated/statsmodels.tsa.statespace.mlemodel.MLEResults.get_prediction.html#statsmodels.regression.recursive_ls.MLEResults.get_prediction
-
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.plot.html
-
https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.fill_between.html
-
'''
-
-
pred = results.get_prediction(start=pd.to_datetime( '1998-01-01'), dynamic=False)
-
pred_ci = pred.conf_int() # return the confidence interval of fitted parameters
-
-
# plot real values and predicted values
-
# pred.predicted_mean is a pandas series
-
ax = y[ '1990':].plot(label='observed') # ax is a matplotlib.axes.Axes
-
pred.predicted_mean.plot(ax=ax, label= 'One-step ahead Forecast', alpha=.7)
-
-
# fill_between(x,y,z) fills the area between two horizontal curves defined by (x,y)
-
# and (x,z). And alpha refers to the alpha transparencies
-
ax.fill_between(pred_ci.index,
-
pred_ci.iloc[:, 0],
-
pred_ci.iloc[:, 1], color='k', alpha=.2)
-
-
ax.set_xlabel( 'Date')
-
ax.set_ylabel( 'CO2 Levels')
-
plt.legend()
-
-
plt.show()
-
-
# Evaluation of model
-
y_forecasted = pred.predicted_mean
-
y_truth = y[ '1998-01-01':]
-
-
# Compute the mean square error
-
mse = ((y_forecasted - y_truth) ** 2).mean()
-
print( 'The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
-
-
'''
-
5-Dynamic Prediction
-
get_prediction(..., dynamic=True)
-
Prediction of each point will use all historic observations prior to 'start' and
-
all predicted values prior to the point to predict
-
'''
-
-
pred_dynamic = results.get_prediction(start=pd.to_datetime( '1998-01-01'), dynamic=True, full_results=True)
-
pred_dynamic_ci = pred_dynamic.conf_int()
-
-
ax = y[ '1990':].plot(label='observed', figsize=(20, 15))
-
pred_dynamic.predicted_mean.plot(label= 'Dynamic Forecast', ax=ax)
-
-
ax.fill_between(pred_dynamic_ci.index,
-
pred_dynamic_ci.iloc[:, 0],
-
pred_dynamic_ci.iloc[:, 1], color='k', alpha=.25)
-
-
ax.fill_betweenx(ax.get_ylim(), pd.to_datetime( '1998-01-01'), y.index[-1],
-
alpha= .1, zorder=-1)
-
-
ax.set_xlabel( 'Date')
-
ax.set_ylabel( 'CO2 Levels')
-
-
plt.legend()
-
plt.show()
-
-
# Extract the predicted and true values of our time-series
-
y_forecasted = pred_dynamic.predicted_mean
-
y_truth = y[ '1998-01-01':]
-
-
# Compute the mean square error
-
mse = ((y_forecasted - y_truth) ** 2).mean()
-
print( 'The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
-
-
'''
-
6-Visualize Prediction
-
In-sample forecast: forecasting for an observation that was part of the data sample;
-
Out-of-sample forecast: forecasting for an observation that was not part of the data sample.
-
'''
-
-
# Get forecast 500 steps ahead in future
-
# 'steps': If an integer, the number of steps to forecast from the end of the sample.
-
pred_uc = results.get_forecast(steps= 500) # retun out-of-sample forecast
-
-
# Get confidence intervals of forecasts
-
pred_ci = pred_uc.conf_int()
-
-
ax = y.plot(label= 'observed', figsize=(20, 15))
-
pred_uc.predicted_mean.plot(ax=ax, label= 'Forecast')
-
ax.fill_between(pred_ci.index,
-
pred_ci.iloc[:, 0],
-
pred_ci.iloc[:, 1], color='k', alpha=.25)
-
ax.set_xlabel( 'Date')
-
ax.set_ylabel( 'CO2 Levels')
-
-
plt.legend()
-
plt.show()