I’ve been trying to implement and estimate, with pymc3, a basic stochastic volatility (SV) model of the following form:
r_t = exp{h_t/2}*e_t
h_t = r_0 + r_1*h_{t-1} + n_t
where r_t is the return process and h_t the (latent) log-variance process following a AR(1) process. My code (MWE) for this looks as follows:
import numpy as np
import pymc3 as pm
# simulate some random data
np.random.seed(13)
data = np.random.randn(10)
# SV model with AR
with pm.Model() as model:
nu = 2
rho = pm.Uniform("rho", -1, 1)
h = pm.AR("h", rho=rho, sigma=1, shape=len(data))
volatility_process = pm.Deterministic(
"volatility_process", pm.math.exp(h / 2) ** 0.5
)
r = pm.StudentT("r", nu=nu, sigma=volatility_process, observed=data)
prior = pm.sample_prior_predictive(10)
# trace = pm.sample(10)
But running the above results in the following error message:
Traceback (most recent call last):
File "C:\Users\jrilla\AppData\Local\Continuum\anaconda3\lib\site-packages\pymc3\distributions\distribution.py", line 801, in _draw_value
return dist_tmp.random(point=point, size=size)
File "C:\Users\jrilla\AppData\Local\Continuum\anaconda3\lib\site-packages\pymc3\distributions\continuous.py", line 1979, in random
point=point, size=size)
File "C:\Users\jrilla\AppData\Local\Continuum\anaconda3\lib\site-packages\pymc3\distributions\distribution.py", line 638, in draw_values
raise ValueError('Cannot resolve inputs for {}'.format([str(params[j]) for j in to_eval]))
ValueError: Cannot resolve inputs for ['Elemwise{mul,no_inplace}.0']
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 9, in <module>
File "C:\Users\jrilla\AppData\Local\Continuum\anaconda3\lib\site-packages\pymc3\sampling.py", line 1495, in sample_prior_predictive
values = draw_values([model[name] for name in names], size=samples)
File "C:\Users\jrilla\AppData\Local\Continuum\anaconda3\lib\site-packages\pymc3\distributions\distribution.py", line 620, in draw_values
size=size)
File "C:\Users\jrilla\AppData\Local\Continuum\anaconda3\lib\site-packages\pymc3\distributions\distribution.py", line 810, in _draw_value
size=None))
File "C:\Users\jrilla\AppData\Local\Continuum\anaconda3\lib\site-packages\pymc3\distributions\continuous.py", line 1979, in random
point=point, size=size)
File "C:\Users\jrilla\AppData\Local\Continuum\anaconda3\lib\site-packages\pymc3\distributions\distribution.py", line 638, in draw_values
raise ValueError('Cannot resolve inputs for {}'.format([str(params[j]) for j in to_eval]))
ValueError: Cannot resolve inputs for ['Elemwise{mul,no_inplace}.0']
Moreover, it is exactly the prior = ...
line that causes the error. Note that I am using pm.AR()
instead of pm.AR1()
, but this would result in the same error. I don’t really understand why it does not work as expected. I am able to run the (simplified) SV example as provided in the pymc3 documentation:
# SV model with GaussianRandomWalk
with pm.Model() as model:
nu = 2
sigma = pm.Exponential("sigma", 1.0, testval=1.0)
s = pm.GaussianRandomWalk("s", sigma=sigma, shape=len(data))
volatility_process = pm.Deterministic(
"volatility_process", pm.math.exp(-2 * s) ** 0.5
)
r = pm.StudentT("r", nu=nu, sigma=volatility_process, observed=data)
prior = pm.sample_prior_predictive(10)
# trace = pm.sample(10)
where they show the example for a Gaussian random walk (GRW), instead of the general AR process I want to use. Since the GRM is just a specific AR and it works for GRM, I don’t see why it shouldn’t also work for the general AR. As can be seen in the code, I basically just replace pm.GaussianRandomWalk(...)
with pm.AR(...)
(each with their required arguments). I am also able to simply implement/estimate the AR process itself:
# Simple AR
with pm.Model() as model:
rho = pm.Uniform("rho", -1, 1)
h = pm.AR("h", rho=rho, sigma=1, shape=len(data), observed=data)
prior = pm.sample_prior_predictive(10)
#trace = pm.sample(10)
which works fine as well, so I assume I am not making a mistake with defining the AR. It’s only when the AR is used as the latent process that the error arises.
Any idea on what the issue is here or what I’m doing wrong? I can’t seem to wrap my head around it.
Thanks!