-
Notifications
You must be signed in to change notification settings - Fork 253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ARX with exogenous variable forecasts residual variance is not as expected #749
Comments
Thanks for the report. When I try and copy and paste the code above, I see |
I realised I am not using the latest version. Let me update and check again before coming back to either update or close the issue. |
I think it is NumPy changes on strictness of broadcasting. This issue has already helped me find a future bug. |
Glad to hear it helped! |
Yup. That is exactly the problem. Still need to work through he actual issue here |
To add a bit more detail of the expected behaviour which is that in the set up above, we should have |
When I manually compute the means and variances, I get the same as the arch package computes. When I run this code (after yours): resids = test_res._resid
for i in range(1, y.shape[0]):
_m = 0 + y_coeff * y[i] + x_coeff * x[i]
# i-1 here since there is no resid for y[0]
_v = 0.0 + res_coeff * test_res._resid[i-1] ** 2
print(f"{i}: {_m:0.4f} {_v:0.4f}")
print(f'Actual means: {means}')
print(f'Actual vars: {vars}') I get
|
Systematically find an fix bugs that affect fixed results closes #749
The code appears to be correct. I think you have the timing of the x variable off by 1. |
Systematically find an fix bugs that affect fixed results closes #749
Yes, the calculation from the residual from I changed the coefficients and values of x in the code below to get integer outcomes.
which gets us
Actual means and Actual residuals are from |
Systematically find an fix bugs that affect fixed results closes #749
Systematically find an fix bugs that affect fixed results closes #749
Systematically find an fix bugs that affect fixed results closes #749
Systematically find an fix bugs that affect fixed results closes #749
You need to shift the data to be aligned right to see where the -15 comes from. Since the y is lagged, the correctly aligned series are
Which matches the output. Alignment of the series is the key to understanding what is going on. |
I have closed since I completed the PR, but feel free to continue to post if the isn't clear. |
Thanks for the clarification. Your calculation makes perfect sense but in this case, it means sims.mean does not actually contain the expected value which you calculated as exp_val? |
Probably need one more check that the X is being handled correctly in the forecast. There are tests for it, but alignment is always one of the trickiest parts. |
Here is the simplest explnation. import numpy as np
import pandas as pd
import arch
from arch.univariate import Normal as ARCHNormal
seed = 42
test_df = pd.DataFrame(
{
"y": np.array([0, 7, 2, 5, 9, 3, 8]).astype(float),
"x": np.array([0, 1, 2, 3, 4, 5, 6]).astype(float),
}
)
y = test_df["y"].values
x = test_df["x"].values
test_model = arch.arch_model(
y=test_df["y"],
x=test_df["x"],
mean="ARX",
vol="GARCH",
lags=0,
p=1,
q=0,
rescale=False,
)
# LS mean y = a + b X, ARCH(1) variance
x_coeff = 1.0 # coefficient for exogenous variable
res_coeff = 1.0 # lag 1 coefficient for volatility process
start = 1 # start from second observation
test_model.distribution = ARCHNormal(seed=seed)
# Parameters are a=0, b=1, omega=0, alpha=1
test_res = test_model.fix([0.0, x_coeff, 0.0, res_coeff]) # constants set to zero
sims = test_res.forecast(
horizon=1,
start=start,
method="simulation",
simulations=1,
x=x[:, np.newaxis],
align="origin",
) You can see the model is an ARX with no lags of y and just X, so that the mean model is I still need to verify that this is the correct behavior with the docs, but this is how it is working. The docs are a bit confusing and so some examples showing the correct behavior shoudl be added (and verified). Also see this example with sims = test_res.forecast(
horizon=1,
start=2,
method="simulation",
simulations=1,
x=x_oos,
align="origin",
)
print(sims.mean)
|
Add additional test Fix bug that occurs when simulations=1 closes #749
I have added tests in #752 and the results are correct. The way x variables are handled depends on the shape of x. In the case you are using, since x has the same shape as the original y, the forecast for period 1 uses y[0] and x[1]. For period 2 it uses y[1] and x[2], and so on. |
However, if you add a lag for y, the calculations for sims.mean are not correctly aligned as seen in #749 (comment) vs #749 (comment) If you look at how to get the same values as sims.mean in #749 (comment) |
Hmm - I swear I wrote a reply earlier. Seems to have gotten eaten. I have re double-checked things and they are correct. The challenge is that the x alignment in modeling and in forecasting is not the same. I have attempted to explain it a bit more in the notebook. The key difference is that if you use |
You are right! This whole section in your link is missing from the equivalent chapter in the docs here. This all makes sense now. Thanks. |
The above code tries to simulate a AR(1) with 1 exogenous variable with a GARCH(1,0) volatility process with horizon=1 and start=1. Unexpectedly, the residual variance does not align with expectations unless the coefficient for the exogenous variable is subtracted from the residual from the previous time step i.e. eps = eps - x_coeff.
The text was updated successfully, but these errors were encountered: