Už známe klasické modely časových řad typu ARIMA. Existuje ale ještě jedna možnost, jak časové řady modelovat, a sice prostřednictvím tzv. strukturních modelů. Ty jsou modely stavovými, ovšem namísto koeficientů AR či MA částí modelujme přímo vývoj střední hodnoty, sezónních složek atd.
V tomto cvičení (které je současně testem) si zkusíme jeden z nejjednodušších a přitom ohromně mocných modelů: lokální lineární trend. Opět budeme mít pozorovanou veličinu $y_t$, která má tentokrát střední hodnotu - level - $l_t$ a je zatížena normálním šumem $\varepsilon_t$. Střední hodnotu budeme rovněž modelovat, a sice jako veličinu, která je ovlivněna svou přechozí hodnotou $l_{t-1}$ a šumem $\xi_t$, ale vstupuje do ní i drift $b_t$. Jedná se tedy o náhodnou procházku s driftem. A abychom dokázali pochytat i dynamiku na střední hodnotě, budeme i samotný drift modelovat jako náhodnou procházku. V řeči statového modelu to bude vypadat následovně (dobře rozmyslete!):
Je důležité myslet na to, že pozorovaná veličina je $y_t$, zatímco nepozorovatelné $l_t$ a $b_t$ budeme uvažovat jako stavy.
Zkusíme si systém nasimulovat se známými hodnotami variancí (v kódu níže zadávám směrodatné odchylky kvůli scipy!):
%% Cell type:code id: tags:
``` python
ndat=300
npred=50
sigma_epsilon=10
sigma_xi=.9
sigma_zeta=.3
mu=np.zeros(ndat)
nu=np.zeros(ndat)
l=np.zeros(ndat)
b=np.zeros(ndat)
y=np.zeros(ndat)
fortinrange(1,ndat):
nu[t]=nu[t-1]+norm.rvs(scale=sigma_zeta)
mu[t]=mu[t-1]+nu[t-1]+norm.rvs(scale=sigma_xi)
y[t]=mu[t]+norm.rvs(scale=sigma_epsilon)
b[t]=b[t-1]+norm.rvs(scale=sigma_zeta)
l[t]=l[t-1]+b[t-1]+norm.rvs(scale=sigma_xi)
y[t]=l[t]+norm.rvs(scale=sigma_epsilon)
plt.plot(y,label=r'$y_t$')
plt.legend()
plt.show()
```
%% Cell type:markdown id: tags:
Zkuste si pustit simulaci víckrát, ať se seznámíte s flexibilitou modelu. Rovněž zkuste měnit variance jednotlivých šumů a pozorujte, jak se změny projevují (chce to pokaždé více běhů).
%% Cell type:markdown id: tags:
## Úkol 1:
Využijte Kalmanův filtr pro modelování výše uvedeného systému. Tj. sestavte matice (uveďte je zde), pusťte odhad a udělejte predikce i na např. 50 kroků za horizont dat.
%% Cell type:code id: tags:
``` python
A=***
H=***
Q=***
R=***# pozor, musí být 2D
```
%% Cell type:code id: tags:
``` python
kf=KF(A=A,B=None,H=H,R=R,Q=Q)
fortinrange(ndat+npred):
kf.predict()
ift<ndat:
kf.correct(np.atleast_1d(y[t]))
kf.log()
log_x=np.array(kf.log_x).T
```
%% Cell type:code id: tags:
``` python
plt.plot(y,label=r'$y_t$')
plt.plot(log_x[0].T,label=r'$\hat{\mu}_t$')
plt.legend()
```
%% Cell type:markdown id: tags:
## Úkol 2:
V souboru '20180224_Gp_part_5m.txt' naleznete měření z přístroje zjišťujícího tok elektronů a protonů v slunečním větru. Tento instrument je umístěn v družici [GOES-15](https://en.wikipedia.org/wiki/GOES_15). Vyberte sloupec s měřeními "Electrons at >2.0 Mev" a zkuste jej namodelovat pomocí modelu lokálního lineárního trendu. To znamená, že budete muset vyladit i (neznámé) hodnoty variancí šumu. Nedá to moc práce, ale chce to použít mozek :)